MB-19222: Fix race condition in TaskQueue shutdown 11/62911/4
authorDave Rigby <daver@couchbase.com>
Wed, 12 Nov 2014 14:58:28 +0000 (14:58 +0000)
committerChiyoung Seo <chiyoung@couchbase.com>
Sat, 23 Apr 2016 00:49:32 +0000 (00:49 +0000)
commit8cbe913fa9a2f78388adb2d2ce6dbfeee1e23e6e
tree82c3df6ec42b4dfb617ecec1aacb6fe74ada6275
parentbd34bbccc9531064bdf544354c03095d60fb4f20
MB-19222: Fix race condition in TaskQueue shutdown

There is a bug in the use of ExecutorThread.state when sleeping a
TaskQueue - TaskQueue::_doSleep() doesn't atomically transition the
state from RUNNING -> SLEEPING. This can cause a deadlock when
shutting down a ExecutorThread:

    Thread A:                           Thread B:
    --------------------------------    ------------------------------
    if (t.state == RUNNING) {  // true
                                        t.state = SHUTDOWN
        t.state = SLEEPING              cb_join_thread(Thread A)
                                        // wait forever
    ...
    if (t.state == SHUTDOWN) { // FALSE
      exit(0) // NEVER REACHED
    }

Fix by changing ExecutorThread.state to be an AtomicValue, and use
compare-and-exchange to move from RUNNING -> SLEEPING (and SLEEPING ->
RUNNING).

Change-Id: I9fab90a83978ae2aa6a0dcdd3b079a1c2f369402
Reviewed-on: http://review.couchbase.org/62911
Well-Formed: buildbot <build@couchbase.com>
Tested-by: buildbot <build@couchbase.com>
Reviewed-by: Will Gardner <will.gardner@couchbase.com>
src/executorthread.cc
src/executorthread.h
src/taskqueue.cc