Index: mojo/public/cpp/utility/lib/run_loop.cc |
diff --git a/mojo/public/cpp/utility/lib/run_loop.cc b/mojo/public/cpp/utility/lib/run_loop.cc |
index f68ad79a08917b9928eba8716baa494c57d6ed2a..1fde95cfecdf1d829fa2f175e9cd5c86e934a104 100644 |
--- a/mojo/public/cpp/utility/lib/run_loop.cc |
+++ b/mojo/public/cpp/utility/lib/run_loop.cc |
@@ -5,22 +5,44 @@ |
#include "mojo/public/cpp/utility/run_loop.h" |
#include <assert.h> |
+#include <pthread.h> |
#include <algorithm> |
#include <vector> |
+#include "mojo/public/c/system/macros.h" |
#include "mojo/public/cpp/system/time.h" |
#include "mojo/public/cpp/system/wait.h" |
-#include "mojo/public/cpp/utility/lib/thread_local.h" |
#include "mojo/public/cpp/utility/run_loop_handler.h" |
namespace mojo { |
namespace { |
-internal::ThreadLocalPointer<RunLoop> current_run_loop; |
- |
const MojoTimeTicks kInvalidTimeTicks = static_cast<MojoTimeTicks>(0); |
+pthread_key_t g_current_run_loop_key; |
+ |
+// Ensures that the "current run loop" functionality is available (i.e., that we |
+// have a TLS slot). |
+void EnsureCurrentRunLoopInitialized() { |
+ static pthread_once_t current_run_loop_key_once = PTHREAD_ONCE_INIT; |
+ int error = pthread_once(¤t_run_loop_key_once, []() { |
+ int error = pthread_key_create(&g_current_run_loop_key, nullptr); |
vardhan
2016/05/19 21:37:35
does it make sense to provide a destructor to pthr
|
+ MOJO_ALLOW_UNUSED_LOCAL(error); |
+ assert(!error); |
+ }); |
+ MOJO_ALLOW_UNUSED_LOCAL(error); |
+ assert(!error); |
+} |
+ |
+void SetCurrentRunLoop(RunLoop* run_loop) { |
+ EnsureCurrentRunLoopInitialized(); |
+ |
+ int error = pthread_setspecific(g_current_run_loop_key, run_loop); |
+ MOJO_ALLOW_UNUSED_LOCAL(error); |
+ assert(!error); |
+} |
+ |
// State needed for one iteration of WaitMany(). |
struct WaitState { |
std::vector<Handle> handles; |
@@ -38,29 +60,19 @@ struct RunLoop::RunState { |
RunLoop::RunLoop() |
: run_state_(nullptr), next_handler_id_(0), next_sequence_number_(0) { |
assert(!current()); |
- current_run_loop.Set(this); |
+ SetCurrentRunLoop(this); |
} |
RunLoop::~RunLoop() { |
assert(current() == this); |
NotifyHandlers(MOJO_RESULT_ABORTED, IGNORE_DEADLINE); |
- current_run_loop.Set(nullptr); |
-} |
- |
-// static |
-void RunLoop::SetUp() { |
- current_run_loop.Allocate(); |
-} |
- |
-// static |
-void RunLoop::TearDown() { |
- assert(!current()); |
- current_run_loop.Free(); |
+ SetCurrentRunLoop(nullptr); |
} |
// static |
RunLoop* RunLoop::current() { |
- return current_run_loop.Get(); |
+ EnsureCurrentRunLoopInitialized(); |
+ return static_cast<RunLoop*>(pthread_getspecific(g_current_run_loop_key)); |
} |
void RunLoop::AddHandler(RunLoopHandler* handler, |