| 328 | } |
| 329 | |
| 330 | static JobSystemResult CancelJobInternal(JobThreadContext* ctx, HJob hjob) |
| 331 | { |
| 332 | JobItem* item = GetJobItem(ctx, hjob); |
| 333 | if (!item) |
| 334 | return JOBSYSTEM_RESULT_INVALID_HANDLE; |
| 335 | |
| 336 | JobSystemResult result = JOBSYSTEM_RESULT_CANCELED; |
| 337 | |
| 338 | if (item->m_Status == JOBSYSTEM_STATUS_PROCESSING || item->m_Status == JOBSYSTEM_STATUS_CALLBACK) |
| 339 | { |
| 340 | item->m_CancelRequested = 1; |
| 341 | result = JOBSYSTEM_RESULT_PENDING; |
| 342 | } |
| 343 | else if (item->m_Status == JOBSYSTEM_STATUS_FINISHED) |
| 344 | { |
| 345 | item->m_Status = JOBSYSTEM_STATUS_CANCELED; |
| 346 | item->m_Result = 0; |
| 347 | } |
| 348 | else |
| 349 | { |
| 350 | // Can only cancel queued/created items directly, but still wait on children when already canceled |
| 351 | assert(item->m_Status == JOBSYSTEM_STATUS_CREATED || item->m_Status == JOBSYSTEM_STATUS_QUEUED || item->m_Status == JOBSYSTEM_STATUS_CANCELED); |
| 352 | item->m_Status = JOBSYSTEM_STATUS_CANCELED; |
| 353 | } |
| 354 | |
| 355 | HJob hchild = item->m_FirstChild; |
| 356 | while (hchild != INVALID_JOB) |
| 357 | { |
| 358 | JobSystemResult childresult = CancelJobInternal(ctx, hchild); |
| 359 | if (childresult == JOBSYSTEM_RESULT_INVALID_HANDLE) |
| 360 | { |
| 361 | break; // We cannot get the item pointer |
| 362 | } |
| 363 | |
| 364 | JobItem* child = GetJobItem(ctx, hchild); |
| 365 | if (child == 0) |
| 366 | { |
| 367 | break; // We cannot iterate further |
| 368 | } |
| 369 | |
| 370 | if (childresult == JOBSYSTEM_RESULT_PENDING) |
| 371 | result = JOBSYSTEM_RESULT_PENDING; |
| 372 | |
| 373 | hchild = child->m_Sibling; |
| 374 | } |
| 375 | |
| 376 | return result; |
| 377 | } |
| 378 | |
| 379 | JobSystemResult JobSystemCancelJob(HJobContext context, HJob hjob) |
| 380 | { |
no test coverage detected