|
64 | 64 |
|
65 | 65 | using namespace swift;
|
66 | 66 |
|
67 |
| -#if 1 |
| 67 | +#if 0 |
68 | 68 | #define SWIFT_TASK_GROUP_DEBUG_LOG(group, fmt, ...) \
|
69 | 69 | fprintf(stderr, "[%#lx] [%s:%d][group(%p%s)] (%s) " fmt "\n", \
|
70 | 70 | (unsigned long)Thread::current().platformThreadId(), \
|
@@ -390,7 +390,11 @@ class TaskGroupBase : public TaskGroupTaskStatusRecord {
|
390 | 390 | virtual void enqueueCompletedTask(AsyncTask *completedTask, bool hadErrorResult) = 0;
|
391 | 391 |
|
392 | 392 | /// Resume waiting task with result from `completedTask`
|
393 |
| - void resumeWaitingTask(AsyncTask *completedTask, TaskGroupStatus &assumed, bool hadErrorResult, bool alreadyDecremented = false); |
| 393 | + void resumeWaitingTask(AsyncTask *completedTask, |
| 394 | + TaskGroupStatus &assumed, |
| 395 | + bool hadErrorResult, |
| 396 | + bool alreadyDecremented = false, |
| 397 | + bool taskWasRetained = false); |
394 | 398 |
|
395 | 399 | // ==== Status manipulation -------------------------------------------------
|
396 | 400 |
|
@@ -827,7 +831,9 @@ class DiscardingTaskGroup: public TaskGroupBase {
|
827 | 831 |
|
828 | 832 | private:
|
829 | 833 | /// Resume waiting task with specified error
|
830 |
| - void resumeWaitingTaskWithError(SwiftError *error, TaskGroupStatus &assumed, bool alreadyDecremented); |
| 834 | + void resumeWaitingTaskWithError(SwiftError *error, |
| 835 | + TaskGroupStatus &assumed, |
| 836 | + bool alreadyDecremented); |
831 | 837 | };
|
832 | 838 |
|
833 | 839 | } // end anonymous namespace
|
@@ -1240,11 +1246,16 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
|
1240 | 1246 | switch (readyErrorItem.getStatus()) {
|
1241 | 1247 | case ReadyStatus::RawError:
|
1242 | 1248 | SWIFT_TASK_GROUP_DEBUG_LOG(this, "offer, complete, resume with raw error:%p", readyErrorItem.getRawError(this));
|
1243 |
| - resumeWaitingTaskWithError(readyErrorItem.getRawError(this), assumed, alreadyDecrementedStatus); |
| 1249 | + resumeWaitingTaskWithError(readyErrorItem.getRawError(this), assumed, |
| 1250 | + alreadyDecrementedStatus); |
1244 | 1251 | break;
|
1245 | 1252 | case ReadyStatus::Error:
|
1246 | 1253 | SWIFT_TASK_GROUP_DEBUG_LOG(this, "offer, complete, resume with errorItem.task:%p", readyErrorItem.getTask());
|
1247 |
| - resumeWaitingTask(readyErrorItem.getTask(), assumed, /*hadErrorResult=*/true, alreadyDecrementedStatus); |
| 1254 | + SWIFT_TASK_GROUP_DEBUG_LOG(this, "offer, complete, expect that it was extra retained %p", readyErrorItem.getTask()); |
| 1255 | + resumeWaitingTask(readyErrorItem.getTask(), assumed, |
| 1256 | + /*hadErrorResult=*/true, |
| 1257 | + alreadyDecrementedStatus, |
| 1258 | + /*taskWasRetained=*/true); |
1248 | 1259 | break;
|
1249 | 1260 | default:
|
1250 | 1261 | swift_Concurrency_fatalError(0,
|
@@ -1283,7 +1294,10 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
|
1283 | 1294 | resumeWaitingTaskWithError(readyErrorItem.getRawError(this), assumed, alreadyDecrementedStatus);
|
1284 | 1295 | break;
|
1285 | 1296 | case ReadyStatus::Error:
|
1286 |
| - resumeWaitingTask(readyErrorItem.getTask(), assumed, /*hadErrorResult=*/true, alreadyDecrementedStatus); |
| 1297 | + resumeWaitingTask(readyErrorItem.getTask(), assumed, |
| 1298 | + /*hadErrorResult=*/true, |
| 1299 | + alreadyDecrementedStatus, |
| 1300 | + /*taskWasRetained=*/true); |
1287 | 1301 | break;
|
1288 | 1302 | default:
|
1289 | 1303 | swift_Concurrency_fatalError(0,
|
@@ -1317,7 +1331,8 @@ void TaskGroupBase::resumeWaitingTask(
|
1317 | 1331 | AsyncTask *completedTask,
|
1318 | 1332 | TaskGroupStatus &assumed,
|
1319 | 1333 | bool hadErrorResult,
|
1320 |
| - bool alreadyDecremented) { |
| 1334 | + bool alreadyDecremented, |
| 1335 | + bool taskWasRetained) { |
1321 | 1336 | auto waitingTask = waitQueue.load(std::memory_order_acquire);
|
1322 | 1337 | assert(waitingTask && "waitingTask must not be null when attempting to resume it");
|
1323 | 1338 | assert(assumed.hasWaitingTask());
|
@@ -1384,13 +1399,21 @@ void TaskGroupBase::resumeWaitingTask(
|
1384 | 1399 | auto before = completedTask;
|
1385 | 1400 | _swift_taskGroup_detachChild(asAbstract(this), completedTask);
|
1386 | 1401 | SWIFT_TASK_GROUP_DEBUG_LOG(this, "completedTask %p; AFTER DETACH (count:%d)", completedTask, swift_retainCount(completedTask));
|
1387 |
| - if (isDiscardingResults() && hadErrorResult) { |
| 1402 | + if (isDiscardingResults() && hadErrorResult && taskWasRetained) { |
1388 | 1403 | SWIFT_TASK_GROUP_DEBUG_LOG(this, "BEFORE RELEASE error task=%p (count:%d)\n",
|
1389 | 1404 | completedTask,
|
1390 | 1405 | swift_retainCount(completedTask));
|
1391 |
| -// We only used the task to keep the error in the future fragment around |
| 1406 | + // We only used the task to keep the error in the future fragment around |
1392 | 1407 | // so now that we emitted the error and detached the task, we are free to release the task immediately.
|
1393 |
| - swift_release(completedTask); // we need to do this if the error is a class |
| 1408 | + auto error = completedTask->futureFragment()->getError(); |
| 1409 | + fprintf(stderr, "[%s:%d](%s) THE ERRROR IN RELEASING %p\n", __FILE_NAME__, __LINE__, __FUNCTION__, |
| 1410 | + error); |
| 1411 | + swift_release(completedTask); |
| 1412 | +// swift_errorRelease(error); |
| 1413 | + } else { |
| 1414 | + fprintf(stderr, "[%s:%d](%s) DID NOT RELEASE %p\n", __FILE_NAME__, __LINE__, __FUNCTION__, |
| 1415 | + completedTask); |
| 1416 | +// assert(false); |
1394 | 1417 | }
|
1395 | 1418 |
|
1396 | 1419 | _swift_tsan_acquire(static_cast<Job *>(waitingTask));
|
@@ -1799,6 +1822,7 @@ void TaskGroupBase::waitAll(SwiftError* bodyError, AsyncTask *waitingTask,
|
1799 | 1822 |
|
1800 | 1823 | #if SWIFT_TASK_GROUP_BODY_THROWN_ERROR_WINS
|
1801 | 1824 | if (bodyError) {
|
| 1825 | + // FIXME: are we ok with releases here? |
1802 | 1826 | fillGroupNextErrorResult(context, bodyError);
|
1803 | 1827 | } else {
|
1804 | 1828 | fillGroupNextResult(context, result);
|
|
0 commit comments