Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4130)

Unified Diff: base/waitable_event.h

Issue 53026: POSIX: allow WaitableEvents to be deleted while watching them. (Closed)
Patch Set: Addressing Jeremy's comments Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/waitable_event_posix.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/waitable_event.h
diff --git a/base/waitable_event.h b/base/waitable_event.h
index 73fc7ff56ed938e1cc6b175e60d4c760dd472fa6..d2b0999db30b1804bac82309f06afca5db0f03b8 100644
--- a/base/waitable_event.h
+++ b/base/waitable_event.h
@@ -16,6 +16,7 @@
#include <utility>
#include "base/condition_variable.h"
#include "base/lock.h"
+#include "base/ref_counted.h"
#endif
#include "base/message_loop.h"
@@ -60,8 +61,6 @@ class WaitableEvent {
HANDLE Release();
#endif
- // WARNING: Destroying a WaitableEvent while threads are waiting on it is not
- // supported. Doing so will cause crashes or other instability.
~WaitableEvent();
// Put the event in the un-signaled state.
@@ -93,6 +92,9 @@ class WaitableEvent {
// count: the number of elements in @waitables
//
// returns: the index of a WaitableEvent which has been signaled.
+ //
+ // You MUST NOT delete any of the WaitableEvent objects while this wait is
+ // happening.
static size_t WaitMany(WaitableEvent** waitables, size_t count);
// For asynchronous waiting, see WaitableEventWatcher
@@ -130,10 +132,35 @@ class WaitableEvent {
#if defined(OS_WIN)
HANDLE handle_;
#else
+ // On Windows, one can close a HANDLE which is currently being waited on. The
+ // MSDN documentation says that the resulting behaviour is 'undefined', but
+ // it doesn't crash. However, if we were to include the following members
+ // directly then, on POSIX, one couldn't use WaitableEventWatcher to watch an
+ // event which gets deleted. This mismatch has bitten us several times now,
+ // so we have a kernel of the WaitableEvent, which is reference counted.
+ // WaitableEventWatchers may then take a reference and thus match the Windows
+ // behaviour.
+ struct WaitableEventKernel :
+ public RefCountedThreadSafe<WaitableEventKernel> {
+ public:
+ WaitableEventKernel(bool manual_reset, bool initially_signaled)
+ : manual_reset_(manual_reset),
+ signaled_(initially_signaled) {
+ }
+
+ bool Dequeue(Waiter* waiter, void* tag);
+
+ Lock lock_;
+ bool signaled_;
+ const bool manual_reset_;
+ std::list<Waiter*> waiters_;
+ };
+
+ scoped_refptr<WaitableEventKernel> kernel_;
+
bool SignalAll();
bool SignalOne();
void Enqueue(Waiter* waiter);
- bool Dequeue(Waiter* waiter, void* tag);
// When dealing with arrays of WaitableEvent*, we want to sort by the address
// of the WaitableEvent in order to have a globally consistent locking order.
@@ -143,11 +170,6 @@ class WaitableEvent {
typedef std::pair<WaitableEvent*, size_t> WaiterAndIndex;
static size_t EnqueueMany(WaiterAndIndex* waitables,
size_t count, Waiter* waiter);
-
- Lock lock_;
- bool signaled_;
- const bool manual_reset_;
- std::list<Waiter*> waiters_;
#endif
DISALLOW_COPY_AND_ASSIGN(WaitableEvent);
« no previous file with comments | « no previous file | base/waitable_event_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698