Deadlocks

| No Comments

Mike Ash just posted in interesting article about deadlocks.

There’s another pattern that is related that I use. As he says, there is often a parent child relationship between locks. Now let’s say that you have chosen to always lock the parent first and then the child, I have found that it is often the case that I want to lock the child but then depending on some state, I then need to lock the parent. In that case, this is the pattern I use:

  BOOL haveParentLock = NO;

TRY_AGAIN:
  [childLock lock]

  if (someCondition) {
    haveParentLock = YES;
    if (![parentLock tryLock]) {
      [childLock unlock];
      [parentLock lock];
      goto TRY_AGAIN;
    }

    // Do something with both locks
  }

  // Do something that only requires the child lock

  [childLock unlock];
  if (haveParentLock)
    [parentLock unlock];

The important thing to note about this is if you have to release the child lock to gain the parent lock, it is important that you loop to check the condition again because you’ve released the child lock and some other thread might have sneaked in. (Some people might prefer to use a loop, but I tend to use a goto for this kind of thing.)

You also don’t want to be locking the parent every time because then you defeat the purpose of having child locks.

Leave a comment