From: Wez Furlong Date: Thu, 10 Jul 2014 18:37:17 +0000 (-0700) Subject: use recursive_mutex to protect State X-Git-Tag: v0.22.0~462 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d7f1adb631b9b6c989eeef31aae04c4472adf370;p=folly.git use recursive_mutex to protect State Summary: maelstrom destructs a Promise during an indirect call from maybeCallback and deadlocks on itself unless we use a recursive mutex. There may be a smarter way to proceed but at the moment I can't build and deploy a package from trunk because the service is non-functional :-/ Test Plan: run ``` fbconfig -r folly/wangle messaging/maelstrom fbmake runtests ``` Reviewed By: hannesr@fb.com Subscribers: fugalh, fsilva FB internal diff: D1428504 --- diff --git a/folly/wangle/detail/State.h b/folly/wangle/detail/State.h index 4c78d956..1e98e4e3 100644 --- a/folly/wangle/detail/State.h +++ b/folly/wangle/detail/State.h @@ -57,7 +57,7 @@ class State { template void setCallback(F func) { { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); if (callback_) { throw std::logic_error("setCallback called twice"); @@ -71,7 +71,7 @@ class State { void fulfil(Try&& t) { { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); if (ready()) { throw std::logic_error("fulfil called twice"); @@ -122,13 +122,13 @@ class State { } void deactivate() { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); active_ = false; } void activate() { { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); active_ = true; } maybeCallback(); @@ -136,7 +136,7 @@ class State { private: void maybeCallback() { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); if (!calledBack_ && value_ && callback_ && active_) { // TODO we should probably try/catch here @@ -148,7 +148,7 @@ class State { void detachOne() { bool shouldDelete; { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); detached_++; assert(detached_ == 1 || detached_ == 2); shouldDelete = (detached_ == 2); @@ -170,7 +170,7 @@ class State { // this lock isn't meant to protect all accesses to members, only the ones // that need to be threadsafe: the act of setting value_ and callback_, and // seeing if they are set and whether we should then continue. - std::mutex mutex_; + std::recursive_mutex mutex_; }; template