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 82 class EventListener; 83 class EventListenerGroup; 84 class EventListenerSingle; 85 86 typedef std::map<EventEmitter*, EventRequest*> EmitterRequestMap_t; 87 88 // EventListener 89 // 90 // The EventListener class provides an object to wait on for specific events 91 // from EventEmitter objects. The EventListener becomes signalled for 92 // read when events are waiting, making it is also an Emitter. 93 class EventListener { 94 public: 95 EventListener(); 96 ~EventListener(); 97 98 // Called by EventEmitter to signal the Listener that a new event is 99 // available. 100 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events) = 0; 101 102 protected: 103 pthread_cond_t signal_cond_; 104 DISALLOW_COPY_AND_ASSIGN(EventListener); 105 }; 106 107 108 // EventListenerLock 109 // 110 // On construction, references and locks the emitter. WaitOnEvent will 111 // temporarily unlock waiting for any event in |events| to become signaled. 112 // The functione exits with the lock taken. The destructor will automatically 113 // unlock the emitter. 114 class EventListenerLock : public EventListener { 115 public: 116 explicit EventListenerLock(EventEmitter* emitter); 117 ~EventListenerLock(); 118 119 // Called by EventEmitter to signal the Listener that a new event is 120 // available. 121 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events); 122 123 // Called with the emitters lock held (which happens in the constructor). 124 // Waits in a condvar until one of the events in |events| is raised or 125 // or the timeout expired. Returns with the emitter lock held, which 126 // will be release when the destructor is called. 127 // 128 // On Error: 129 // ETIMEOUT if the timeout is exceeded. 130 // EINTR if the wait was interrupted. 131 Error WaitOnEvent(uint32_t events, int ms_max); 132 133 private: 134 EventEmitter* emitter_; 135 sdk_util::AutoLock* lock_; 136 uint32_t events_; 137 DISALLOW_COPY_AND_ASSIGN(EventListenerLock); 138 }; 139 140 141 class EventListenerPoll : public EventListener { 142 public: 143 EventListenerPoll() : EventListener(), signaled_(0) {} 144 145 // Called by EventEmitter to signal the Listener that a new event is 146 // available. 147 virtual void ReceiveEvents(EventEmitter* emitter, uint32_t events); 148 149 // Wait for the any requested emitter/filter pairs to emit one of the 150 // events in the matching filter. Returns 0 on success. 151 // 152 // On Error: 153 // ETIMEOUT if the timeout is exceeded. 154 // EINTR if the wait was interrupted. 155 Error WaitOnAny(EventRequest* requests, size_t cnt, int ms_max); 156 157 private: 158 sdk_util::SimpleLock signal_lock_; 159 EmitterRequestMap_t emitters_; 160 size_t signaled_; 161 DISALLOW_COPY_AND_ASSIGN(EventListenerPoll); 162 }; 163 164 } // namespace nacl_io 165 166 #endif /* LIBRARIES_NACL_IO_EVENT_LISTENER_H_ */ 167