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

Unified Diff: native_client_sdk/src/libraries/nacl_io/event_listener.h

Issue 23498015: [NaCl SDK] Support non blocking TCP/UDP (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 7 years, 3 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
Index: native_client_sdk/src/libraries/nacl_io/event_listener.h
diff --git a/native_client_sdk/src/libraries/nacl_io/event_listener.h b/native_client_sdk/src/libraries/nacl_io/event_listener.h
index cb93f116b2f1b91179e78193ba8bb9551641c45a..4b9647a0b38bebae9469b44a764c2a7856404c89 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_listener.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_listener.h
@@ -15,6 +15,8 @@
#include "nacl_io/error.h"
#include "nacl_io/event_emitter.h"
+#include "sdk_util/auto_lock.h"
+#include "sdk_util/macros.h"
#include "sdk_util/scoped_ref.h"
// Kernel Events
@@ -24,43 +26,43 @@
// down. EventListener provides a mechanism for a thread to wait on
// specific events from these objects which are derived from EventEmitters.
//
-// EventEmitter and EventListener together provide support for an "epoll"
-// like interface. See:
-// http://man7.org/linux/man-pages/man7/epoll.7.html
+// Calling RegisterListener_Locked on an event emitter, will cause all
+// Listeners matching the event mask are signaled so they may try to make
+// progress. In the case of "select" or "poll", multiple threads could be
+// notified that one or more emitters are signaled and allowed to make
+// progress. In the case of "read" or "write", only one thread at a time
+// should make progress, to ensure that if one thread consumes the signal,
+// the other can correctly timeout.
//
-// Such that we map the arguments at behavior of
-// epoll_wait maps to Wait, and
-// epoll_ctl maps to Track, Update, Free.
+// Events Listeners requirements:
+// 1- Must reference counting Emitters to ensure they are not destroyed
+// while waiting for a signal.
+// 2- Must unregister themselves from all emitters prior to being destoryed.
+// 3- Must never be shared between threads since interals may not be locked
+// to prevent dead-locks with emitter signals.
+// 4- Must never lock themselves before locking an emitter to prevent
+// dead-locks
//
-// Behavior of EventListeners
-// FDs are automatically removed when closed.
-// KE_SHUTDOWN can not be masked.
-// KE_SHUTDOWN is only seen if the hangup happens after Wait starts.
-// Dup'd FDs get their own event info which must also get signaled.
-// Adding a non streaming FD will fail.
-// EventEmitters can also be waited on.
-// It is illegal for an a EventListener to add itself.
+// There are two types of listeners, EventListenerSingle and EventListenerGroup
+// For Single listeners, all listeners are unblocked by the Emitter, but
+// they individually take the emitters lock and test against the current
+// status to ensure another listener didn't consume the signal.
//
// Locking:
-// EventListener::{Track/Update/Free}
-// AUTO_LOCK(EventListener::info_lock_)
-// EventEmitter::RegisterEventInfo
-// AUTO_LOCK(EventEmitter::emitter_lock_)
+// EventEmitter::<Backgroun IO>
+// *LOCK* EventEmitter::emitter_lock_
+// EventEmitter::RaiseEvent_Locked
+// EventListenerSingle::ReceiveEvents
+// <no locking, using emitter's lock>
+// EventListenerGroup::ReceiveEvents
+// *LOCK* EventListenerGroup::signal_lock_
//
-// EventEmitter::Destroy
-// EventListener::AbandonedEventInfo
-// AUTO_LOCK(EventListener::info_lock_)
+// EventListenerSingle::WaitOnLock
+// *LOCK* EventEmitter::emitter_lock_
//
-// EventListener::RaiseEvent
-// AUTO_LOCK(EventEmitter::emitter_lock_)
-// EventListener::Signal
-// AUTO_LOCK(EventListener::signal_lock_)
+// EventListenerGroup::WaitOnAny
+// *LOCK* EventListenerGroup::signal_lock_
//
-// EventListener::Wait
-// AUTO_LOCK(EventListener::info_lock_)
-// ...
-// AUTO_LOCK(EventListener::signal_lock_)
-// ...
namespace nacl_io {
@@ -70,74 +72,95 @@ struct EventData {
uint64_t user_data;
};
+struct EventRequest {
+ ScopedEventEmitter emitter;
+ uint32_t filter;
+ uint32_t events;
+};
+
+
+class EventListener;
+class EventListenerGroup;
+class EventListenerSingle;
+
+typedef std::map<EventEmitter*, EventRequest*> EmitterRequestMap_t;
// EventListener
//
// The EventListener class provides an object to wait on for specific events
// from EventEmitter objects. The EventListener becomes signalled for
// read when events are waiting, making it is also an Emitter.
-class EventListener : public EventEmitter {
+class EventListener {
public:
- EventListener();
- ~EventListener();
+ EventListener();
+ ~EventListener();
+
+ // Called by EventEmitter to signal the Listener that a new event is
+ // available.
+ virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events) = 0;
protected:
- // Called prior to free to unregister all EventInfos from the EventEmitters.
- void Destroy();
+ pthread_cond_t signal_cond_;
+ DISALLOW_COPY_AND_ASSIGN(EventListener);
+};
+
+// EventListenerLock
+//
+// On construction, references and locks the emitter. WaitOnEvent will
+// temporarily unlock waiting for any event in |events| to become signaled.
+// The functione exits with the lock taken. The destructor will automatically
+// unlock the emitter.
+class EventListenerLock : public EventListener {
public:
- // Declared in EventEmitter
- virtual uint32_t GetEventStatus();
- virtual int GetType();
-
- // Called by EventEmitter to signal the Listener that a new event is
- // available.
- void Signal(const ScopedEventInfo& info);
-
- // Wait for one or more previously Tracked events to take place
- // or until ms_timeout expires, and fills |events| up to |max| limit.
- // The number of events recored is returned in |count|.
- Error Wait(EventData* events, int max, int ms_timeout, int* out_count);
-
- // Tracks a new set of POLL events for a given unique |id|. The
- // |user_data| will be returned in the Wait when an event of type |filter|
- // is received with that |id|.
- Error Track(int id,
- const ScopedEventEmitter& emitter,
- uint32_t filter,
- uint64_t user_data);
-
- // Updates the tracking of events for |id|, replacing the |user_data|
- // that's returned, as well as which events will signal.
- Error Update(int id, uint32_t filter, uint64_t user_data);
-
- // Unregisters the existing |id|.
- Error Free(int id);
-
- // Notification by EventEmitter that it is abandoning the event. Do not
- // access the emitter after this.
- void AbandonedEventInfo(const ScopedEventInfo& event);
+ explicit EventListenerLock(EventEmitter* emitter);
+ ~EventListenerLock();
+
+ // Called by EventEmitter to signal the Listener that a new event is
+ // available.
+ virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events);
+
+ // Called with the emitters lock held (which happens in the constructor).
+ // Waits in a condvar until one of the events in |events| is raised or
+ // or the timeout expired. Returns with the emitter lock held, which
+ // will be release when the destructor is called.
+ //
+ // On Error:
+ // ETIMEOUT if the timeout is exceeded.
+ // EINTR if the wait was interrupted.
+ Error WaitOnEvent(uint32_t events, int ms_max);
+
+private:
+ EventEmitter* emitter_;
+ sdk_util::AutoLock* lock_;
+ uint32_t events_;
+ DISALLOW_COPY_AND_ASSIGN(EventListenerLock);
+};
- private:
- // Protects the data in the EventInfo map.
- sdk_util::SimpleLock info_lock_;
- // Map from ID to live a event info.
- EventInfoMap_t event_info_map_;
+class EventListenerPoll : public EventListener {
+ public:
+ EventListenerPoll() : EventListener(), signaled_(0) {}
- // Protects waiting_, signaled_ and used with the signal_cond_.
- sdk_util::SimpleLock signal_lock_;
- pthread_cond_t signal_cond_;
+ // Called by EventEmitter to signal the Listener that a new event is
+ // available.
+ virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events);
- // The number of threads currently waiting on this Listener.
- uint32_t waiting_;
+ // Wait for the any requested emitter/filter pairs to emit one of the
+ // events in the matching filter. Returns 0 on success.
+ //
+ // On Error:
+ // ETIMEOUT if the timeout is exceeded.
+ // EINTR if the wait was interrupted.
+ Error WaitOnAny(EventRequest* requests, size_t cnt, int ms_max);
- // Set of event infos signaled during a wait.
- EventInfoSet_t signaled_;
+ private:
+ sdk_util::SimpleLock signal_lock_;
+ EmitterRequestMap_t emitters_;
+ size_t signaled_;
+ DISALLOW_COPY_AND_ASSIGN(EventListenerPoll);
};
-typedef sdk_util::ScopedRef<EventListener> ScopedEventListener;
-
} // namespace nacl_io
#endif /* LIBRARIES_NACL_IO_EVENT_LISTENER_H_ */

Powered by Google App Engine
This is Rietveld 408576698