I have a specific locking order that I am following. I am writing a thread pool to do some tasks that are currently done sequentially.
The locking order is pool->queue->job.
However, sometimes I need to lock the job to check the state of the job, and then lock the queue to move the job from one queue to another. So, to follow the lock ordering I get this:
lock job
if (job->state == CANCELED) {
unlock job
lock queue
lock job
// check that it is still canceled and do work
}
My question is, is there an alternate way to do this that doesn’t have the unlock/lock job? How is this handled when lock order must be preserved and a lock ‘higher up’ is needed?
I think you could do a a try-lock on queue. If it succeeds, you have both locks and can continue. If it fails, someone else has the queue lock already and as you don’t know if he’s maybe waiting for your job lock, you must do an unlock on job first before you may do a blocking lock on queue, otherwise you might deadlock.
I think the following code won’t ever deadlock:
You might be unlocking queue and job in different order of locking, depending if try-lock succeeded or not (order is right if it succeeded, wrong otherwise), yet I still think it won’t ever deadlock.