| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ef649608d39f909fb3a16cac847cf486c8bb7119
|
| --- /dev/null
|
| +++ b/native_client_sdk/src/libraries/nacl_io/event_listener.h
|
| @@ -0,0 +1,145 @@
|
| +/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#ifndef LIBRARIES_NACL_IO_EVENT_LISTENER_H_
|
| +#define LIBRARIES_NACL_IO_EVENT_LISTENER_H_
|
| +
|
| +#include <pthread.h>
|
| +
|
| +#include <map>
|
| +#include <set>
|
| +#include <vector>
|
| +
|
| +#include "nacl_io/error.h"
|
| +#include "nacl_io/event_emitter.h"
|
| +
|
| +#include "sdk_util/scoped_ref.h"
|
| +
|
| +// Kernel Events
|
| +//
|
| +// Certain file objects such as pipes or sockets can become signaled when
|
| +// read or write buffers become available, or when the connection is torn
|
| +// 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
|
| +//
|
| +// Such that we map the arguments at behavior of
|
| +// epoll_wait maps to Wait, and
|
| +// epoll_ctl maps to Track, Update, Free.
|
| +//
|
| +// 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.
|
| +//
|
| +// Locking:
|
| +// EventListener::{Track/Update/Free}
|
| +// AUTO_LOCK(EventListener::info_lock_)
|
| +// EventEmitter::RegisterEventInfo
|
| +// AUTO_LOCK(EventEmitter::emitter_lock_)
|
| +//
|
| +// EventEmitter::Destroy
|
| +// EventListener::AbandonedEventInfo
|
| +// AUTO_LOCK(EventListener::info_lock_)
|
| +//
|
| +// EventListener::RaiseEvent
|
| +// AUTO_LOCK(EventEmitter::emitter_lock_)
|
| +// EventListener::Signal
|
| +// AUTO_LOCK(EventListener::signal_lock_)
|
| +//
|
| +// EventListener::Wait
|
| +// AUTO_LOCK(EventListener::info_lock_)
|
| +// ...
|
| +// AUTO_LOCK(EventListener::signal_lock_)
|
| +// ...
|
| +
|
| +enum KernelEventType {
|
| + KE_READ_READY = 1,
|
| + KE_WRITE_READY = 2,
|
| + KE_SHUTDOWN = 4
|
| +};
|
| +
|
| +struct EventData {
|
| + // Bit Mask of signaled KernelEvents
|
| + uint32_t events;
|
| + uint64_t user_data;
|
| +};
|
| +
|
| +
|
| +// 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 {
|
| + public:
|
| + EventListener();
|
| + ~EventListener();
|
| +
|
| + protected:
|
| + // Called prior to free to unregister all EventInfos from the EventEmitters.
|
| + void Destroy();
|
| +
|
| + 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 KernelEventTypes 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);
|
| +
|
| + private:
|
| + // Protects the data in the EventInfo map.
|
| + SimpleLock info_lock_;
|
| +
|
| + // Map from ID to live a event info.
|
| + EventInfoMap_t event_info_map_;
|
| +
|
| + // Protects waiting_, signaled_ and used with the signal_cond_.
|
| + SimpleLock signal_lock_;
|
| + pthread_cond_t signal_cond_;
|
| +
|
| + // The number of threads currently waiting on this Listener.
|
| + uint32_t waiting_;
|
| +
|
| + // Set of event infos signaled during a wait.
|
| + EventInfoSet_t signaled_;
|
| +};
|
| +
|
| +typedef ScopedRef<EventListener> ScopedEventListener;
|
| +
|
| +#endif /* LIBRARIES_NACL_IO_EVENT_LISTENER_H_ */
|
|
|