Home | History | Annotate | Download | only in nacl_io
      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/scoped_ref.h"
     19 
     20 // Kernel Events
     21 //
     22 // Certain file objects such as pipes or sockets can become signaled when
     23 // read or write buffers become available, or when the connection is torn
     24 // down.  EventListener provides a mechanism for a thread to wait on
     25 // specific events from these objects which are derived from EventEmitters.
     26 //
     27 // EventEmitter and EventListener together provide support for an "epoll"
     28 // like interface.  See:
     29 //     http://man7.org/linux/man-pages/man7/epoll.7.html
     30 //
     31 // Such that we map the arguments at behavior of
     32 //     epoll_wait maps to Wait, and
     33 //     epoll_ctl maps to Track, Update, Free.
     34 //
     35 //  Behavior of EventListeners
     36 //    FDs are automatically removed when closed.
     37 //    KE_SHUTDOWN can not be masked.
     38 //    KE_SHUTDOWN is only seen if the hangup happens after Wait starts.
     39 //    Dup'd FDs get their own event info which must also get signaled.
     40 //    Adding a non streaming FD will fail.
     41 //    EventEmitters can also be waited on.
     42 //    It is illegal for an a EventListener to add itself.
     43 //
     44 //  Locking:
     45 //    EventListener::{Track/Update/Free}
     46 //      AUTO_LOCK(EventListener::info_lock_)
     47 //       EventEmitter::RegisterEventInfo
     48 //         AUTO_LOCK(EventEmitter::emitter_lock_)
     49 //
     50 //    EventEmitter::Destroy
     51 //      EventListener::AbandonedEventInfo
     52 //        AUTO_LOCK(EventListener::info_lock_)
     53 //
     54 //    EventListener::RaiseEvent
     55 //      AUTO_LOCK(EventEmitter::emitter_lock_)
     56 //        EventListener::Signal
     57 //          AUTO_LOCK(EventListener::signal_lock_)
     58 //
     59 //    EventListener::Wait
     60 //      AUTO_LOCK(EventListener::info_lock_)
     61 //        ...
     62 //      AUTO_LOCK(EventListener::signal_lock_)
     63 //        ...
     64 
     65 namespace nacl_io {
     66 
     67 struct EventData {
     68   // Bit Mask of signaled POLL events.
     69   uint32_t events;
     70   uint64_t user_data;
     71 };
     72 
     73 
     74 // EventListener
     75 //
     76 // The EventListener class provides an object to wait on for specific events
     77 // from EventEmitter objects.  The EventListener becomes signalled for
     78 // read when events are waiting, making it is also an Emitter.
     79 class EventListener : public EventEmitter {
     80  public:
     81    EventListener();
     82    ~EventListener();
     83 
     84  protected:
     85   // Called prior to free to unregister all EventInfos from the EventEmitters.
     86   void Destroy();
     87 
     88  public:
     89    // Declared in EventEmitter
     90    virtual uint32_t GetEventStatus();
     91    virtual int GetType();
     92 
     93    // Called by EventEmitter to signal the Listener that a new event is
     94    // available.
     95    void Signal(const ScopedEventInfo& info);
     96 
     97    // Wait for one or more previously Tracked events to take place
     98    // or until ms_timeout expires, and fills |events| up to |max| limit.
     99    // The number of events recored is returned in |count|.
    100    Error Wait(EventData* events, int max, int ms_timeout, int* out_count);
    101 
    102    // Tracks a new set of POLL events for a given unique |id|.  The
    103    // |user_data| will be returned in the Wait when an event of type |filter|
    104    // is received with that |id|.
    105    Error Track(int id,
    106                const ScopedEventEmitter& emitter,
    107                uint32_t filter,
    108                uint64_t user_data);
    109 
    110    // Updates the tracking of events for |id|, replacing the |user_data|
    111    // that's returned, as well as which events will signal.
    112    Error Update(int id, uint32_t filter, uint64_t user_data);
    113 
    114    // Unregisters the existing |id|.
    115    Error Free(int id);
    116 
    117    // Notification by EventEmitter that it is abandoning the event.  Do not
    118    // access the emitter after this.
    119    void AbandonedEventInfo(const ScopedEventInfo& event);
    120 
    121  private:
    122   // Protects the data in the EventInfo map.
    123   sdk_util::SimpleLock info_lock_;
    124 
    125   // Map from ID to live a event info.
    126   EventInfoMap_t event_info_map_;
    127 
    128   // Protects waiting_, signaled_ and used with the signal_cond_.
    129   sdk_util::SimpleLock signal_lock_;
    130   pthread_cond_t signal_cond_;
    131 
    132   // The number of threads currently waiting on this Listener.
    133   uint32_t waiting_;
    134 
    135   // Set of event infos signaled during a wait.
    136   EventInfoSet_t signaled_;
    137 };
    138 
    139 typedef sdk_util::ScopedRef<EventListener> ScopedEventListener;
    140 
    141 }  // namespace nacl_io
    142 
    143 #endif  /* LIBRARIES_NACL_IO_EVENT_LISTENER_H_ */
    144