NSConditionLock console message: "unlocked from thread which did not lock it"

  • Hello All,

    Under Leopard, my application has begun logging console messages like this:

    2007-11-25 09:09:03.572 Script Debugger 4[66788:613] *** -[NSConditionLock
    unlockWithCondition:]: lock (<NSConditionLock: 0x2b5e7ed0> '(null)')
    unlocked from thread which did not lock it

    The message is correct: I lock the NSConditionLock from a worker thread to
    block the thread until another thread (the main thread) receives a response
    and the worker can continue on.

    This seems to me like a legitimate use of a lock.  Can anyone explain what
    the problem here is.

    Cheers
    -Mark

    ------------------------------------------------------------------------
    Mark Alldritt                      Late Night Software Ltd.
    Phone: 250-380-1725                Script Debugger 4.0 - AppleScript IDE
    WEB:  http://www.latenightsw.com/  FaceSpan 4.3 - AppleScript RAD
                                      Affrus 1.0 - Perl Debugging
  • On Nov 25, 2007 11:40 AM, Mark Alldritt <alldritt...> wrote:
    > The message is correct: I lock the NSConditionLock from a worker thread to
    > block the thread until another thread (the main thread) receives a response
    > and the worker can continue on.
    >
    > This seems to me like a legitimate use of a lock.  Can anyone explain what
    > the problem here is.

    It is, but it doesn't sound like you're doing it correctly. Take a
    close look at the section titled Using an NSConditionLock:

    <file://localhost/Developer/ADC%20Reference%20Library/documentation/Cocoa/Conceptual/Multithreading/articles/CocoaLocks.html#//apple_ref/doc/uid/20000737>

    NSConditionLock is, at its core, a mutual exclusion lock. The only
    difference is that it allows a thread (the consumer) to intelligently
    release the lock until a condition is satisfied, at which point it
    re-acquires the lock and continues. The produced still has to ACQUIRE
    the lock before it can change the condition.

    Make sense?
  • On Nov 25, 2007 12:23 PM, stephen joseph butler
    <stephen.butler...> wrote:
    > <file://localhost/Developer/ADC%20Reference%20Library/documentation/Cocoa/Conceptual/Multithreading/articles/CocoaLocks.html#//apple_ref/doc/uid/20000737>

    Sorry. I meant to link to the online version:

    <http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/ar
    ticles/CocoaLocks.html#//apple_ref/doc/uid/20000737
    >
  • > This seems to me like a legitimate use of a lock.  Can anyone explain what
    > the problem here is.

    > From the docs on NSLock:

    > Warning: The NSLock class uses POSIX threads to implement its locking
    > behavior. When sending an unlock message to an NSLock object, you must be sure
    > that message is sent from the same thread that sent the initial lock message.
    > Unlocking a lock from a different thread can result in undefined behavior.

    NSCondition probably uses NSLock in its implementation. You might want to
    file a bug against the docs, that the warning should be repeated or
    referenced in the NSCondition docs.

    Most of the time, code that takes any kind of lock in one thread and
    releases it in another is wrong. Such code usually has race conditions,
    because such code usually at some point has an inter-thread sequence that
    behaves similarly to the naïve "if !myflag then" vs "myflag = true" type of
    resource protection.

    You may have the exception, where external factors guarantee that your main
    thread never receives a response and unlocks just before a worker thread
    locks, and that the worker thread always completes taking the lock before
    the main thread releases it. But are you sure? Are you 100% sure that the
    following sequence could never occur?

    1) worker posts request to main thread
    2) main thread processes request
    3) main thread receives response
    4) main thread signals
    5) worker thread waits for signal, and waits, and waits...


    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • On Nov 25, 2007, at 9:40 AM, Mark Alldritt wrote:
    > Under Leopard, my application has begun logging console messages
    > like this:
    >
    > 2007-11-25 09:09:03.572 Script Debugger 4[66788:613] *** -
    > [NSConditionLock
    > unlockWithCondition:]: lock (<NSConditionLock: 0x2b5e7ed0> '(null)')
    > unlocked from thread which did not lock it
    >
    > The message is correct: I lock the NSConditionLock from a worker
    > thread to
    > block the thread until another thread (the main thread) receives a
    > response
    > and the worker can continue on.
    >
    > This seems to me like a legitimate use of a lock.  Can anyone
    > explain what
    > the problem here is.

    POSIX does not require unlocking from a different thread to work
    properly, though it may, so as NSLock and related are built on top of
    the pthreads API, the same is true there as well.

    What you want to do is lock and unlock in the same thread, in both
    threads.  NSConditionLock, which you're already using, makes this
    straightforward, whereas it is not possible with plain NSLocks.  For
    example, to block the background thread:

    [condLock lockWhenCondition:1]; // block until 1
    [condLock unlock];

    In the main thread:

    [condLock lock];
    [condLock unlockWithCondition:1];  // 1 means background thread can
    proceed

    assuming that the lock was created/initialized with -initWithCondition:
    0.

    Chris Kane
    Cocoa Frameworks, Apple
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today