1 /* Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #ifndef LIBRARIES_NACL_IO_EVENT_LISTENER_H_ 7 #define LIBRARIES_NACL_IO_EVENT_LISTENER_H_ 8 9 #include <pthread.h> 10 11 #include <map> 12 #include <set> 13 #include <vector> 14 15 #include "nacl_io/error.h" 16 #include "nacl_io/event_emitter.h" 17 18 #include "sdk_util/auto_lock.h" 19 #include "sdk_util/macros.h" 20 #include "sdk_util/scoped_ref.h" 21 22 // Kernel Events 23 // 24 // Certain file objects such as pipes or sockets can become signaled when 25 // read or write buffers become available, or when the connection is torn 26 // down. EventListener provides a mechanism for a thread to wait on 27 // specific events from these objects which are derived from EventEmitters. 28 // 29 // Calling RegisterListener_Locked on an event emitter, will cause all 30 // Listeners matching the event mask are signaled so they may try to make 31 // progress. In the case of "select" or "poll", multiple threads could be 32 // notified that one or more emitters are signaled and allowed to make 33 // progress. In the case of "read" or "write", only one thread at a time 34 // should make progress, to ensure that if one thread consumes the signal, 35 // the other can correctly timeout. 36 // 37 // Events Listeners requirements: 38 // 1- Must reference counting Emitters to ensure they are not destroyed 39 // while waiting for a signal. 40 // 2- Must unregister themselves from all emitters prior to being destoryed. 41 // 3- Must never be shared between threads since interals may not be locked 42 // to prevent dead-locks with emitter signals. 43 // 4- Must never lock themselves before locking an emitter to prevent 44 // dead-locks 45 // 46 // There are two types of listeners, EventListenerSingle and EventListenerGroup 47 // For Single listeners, all listeners are unblocked by the Emitter, but 48 // they individually take the emitters lock and test against the current 49 // status to ensure another listener didn't consume the signal. 50 // 51 // Locking: 52 // EventEmitter::<Backgroun IO> 53 // *LOCK* EventEmitter::emitter_lock_ 54 // EventEmitter::RaiseEvent_Locked 55 // EventListenerSingle::ReceiveEvents 56 // <no locking, using emitter's lock> 57 // EventListenerGroup::ReceiveEvents 58 // *LOCK* EventListenerGroup::signal_lock_ 59 // 60 // EventListenerSingle::WaitOnLock 61 // *LOCK* EventEmitter::emitter_lock_ 62 // 63 // EventListenerGroup::WaitOnAny 64 // *LOCK* EventListenerGroup::signal_lock_ 65 // 66 67 namespace nacl_io { 68 69 struct EventData { 70 // Bit Mask of signaled POLL events. 71 uint32_t events; 72 uint64_t user_data; 73 }; 74 75 struct EventRequest { 76 ScopedEventEmitter emitter; 77 uint32_t filter; 78 uint32_t events; 79 }; 80 81 class EventListener; 82 class EventListenerGroup; 83 class EventListenerSingle; 84 85 typedef std::map<EventEmitter*, EventRequest*> EmitterRequestMap_t; 86 87 // EventListener 88 // 89 // The EventListener class provides an object to wait on for specific events 90 // from EventEmitter objects. The EventListener becomes signalled for 91 // read when events are waiting, making it is also an Emitter. 92 class EventListener { 93 public: 94 EventListener(); 95 ~EventListener(); 96 97 // Called by EventEmitter to signal the Listener that a new event is 98 // available. 99 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events) = 0; 100 101 protected: 102 pthread_cond_t signal_cond_; 103 DISALLOW_COPY_AND_ASSIGN(EventListener); 104 }; 105 106 // EventListenerLock 107 // 108 // On construction, references and locks the emitter. WaitOnEvent will 109 // temporarily unlock waiting for any event in |events| to become signaled. 110 // The functione exits with the lock taken. The destructor will automatically 111 // unlock the emitter. 112 class EventListenerLock : public EventListener { 113 public: 114 explicit EventListenerLock(EventEmitter* emitter); 115 ~EventListenerLock(); 116 117 // Called by EventEmitter to signal the Listener that a new event is 118 // available. 119 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events); 120 121 // Called with the emitters lock held (which happens in the constructor). 122 // Waits in a condvar until one of the events in |events| is raised or 123 // or the timeout expired. Returns with the emitter lock held, which 124 // will be release when the destructor is called. 125 // 126 // On Error: 127 // ETIMEOUT if the timeout is exceeded. 128 // EINTR if the wait was interrupted. 129 Error WaitOnEvent(uint32_t events, int ms_max); 130 131 private: 132 EventEmitter* emitter_; 133 sdk_util::AutoLock* lock_; 134 uint32_t events_; 135 DISALLOW_COPY_AND_ASSIGN(EventListenerLock); 136 }; 137 138 class EventListenerPoll : public EventListener { 139 public: 140 EventListenerPoll() : EventListener(), signaled_(0) {} 141 142 // Called by EventEmitter to signal the Listener that a new event is 143 // available. 144 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events); 145 146 // Wait for the any requested emitter/filter pairs to emit one of the 147 // events in the matching filter. Returns 0 on success. 148 // 149 // On Error: 150 // ETIMEOUT if the timeout is exceeded. 151 // EINTR if the wait was interrupted. 152 Error WaitOnAny(EventRequest* requests, size_t cnt, int ms_max); 153 154 private: 155 sdk_util::SimpleLock signal_lock_; 156 EmitterRequestMap_t emitters_; 157 size_t signaled_; 158 DISALLOW_COPY_AND_ASSIGN(EventListenerPoll); 159 }; 160 161 } // namespace nacl_io 162 163 #endif /* LIBRARIES_NACL_IO_EVENT_LISTENER_H_ */ 164