| 453 | } |
| 454 | |
| 455 | static void ProcessOneJob(JobThreadContext* ctx, HJob hjob) |
| 456 | { |
| 457 | uint32_t generation = ToGeneration(hjob); |
| 458 | uint32_t index = ToIndex(hjob); |
| 459 | |
| 460 | Job job; |
| 461 | { |
| 462 | DM_MUTEX_OPTIONAL_SCOPED_LOCK(ctx->m_Mutex); |
| 463 | |
| 464 | JobItem& item = ctx->m_Items.Get(index); |
| 465 | assert(item.m_Generation == generation); |
| 466 | |
| 467 | // The item may have been cancelled just before |
| 468 | bool finished = item.m_Status > JOBSYSTEM_STATUS_QUEUED; |
| 469 | if (finished) |
| 470 | { |
| 471 | PutDone(ctx, hjob, item.m_Status, 0); |
| 472 | return; |
| 473 | } |
| 474 | |
| 475 | job = item.m_Job; |
| 476 | |
| 477 | // Make sure it cannot be canceled now |
| 478 | item.m_Status = JOBSYSTEM_STATUS_PROCESSING; |
| 479 | } |
| 480 | |
| 481 | // Don't keep the lock here, as the jobs may use their own locks, and it may easily lead to a dead lock |
| 482 | HJobContext context = ctx->m_Context; |
| 483 | int32_t result = job.m_Process(context, hjob, job.m_Context, job.m_Data); |
| 484 | |
| 485 | PutDone(ctx, hjob, JOBSYSTEM_STATUS_FINISHED, result); |
| 486 | } |
| 487 | |
| 488 | static HJob SelectAndPopJob(JobThreadContext* ctx, uint64_t time, JobItem** out_item) |
| 489 | { |
no test coverage detected