1 #ifndef ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
2 #define ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
3 
4 #include <sys/epoll.h>
5 
6 #include <atomic>
7 #include <functional>
8 #include <mutex>
9 #include <thread>
10 #include <unordered_map>
11 #include <vector>
12 
13 #include <pdx/file_handle.h>
14 #include <pdx/status.h>
15 
16 namespace android {
17 namespace dvr {
18 
19 class EpollEventDispatcher {
20  public:
21   // Function type for event handlers. The handler receives a bitmask of the
22   // epoll events that occurred on the file descriptor associated with the
23   // handler.
24   using Handler = std::function<void(int)>;
25 
26   EpollEventDispatcher();
27   ~EpollEventDispatcher();
28 
29   // |handler| is called on the internal dispatch thread when |fd| is signaled
30   // by events in |event_mask|.
31   pdx::Status<void> AddEventHandler(int fd, int event_mask, Handler handler);
32   pdx::Status<void> RemoveEventHandler(int fd);
33 
34   void Stop();
35 
36  private:
37   void EventThread();
38 
39   std::thread thread_;
40   std::atomic<bool> exit_thread_{false};
41 
42   // Protects handlers_ and removed_handlers_ and serializes operations on
43   // epoll_fd_ and event_fd_.
44   std::mutex lock_;
45 
46   // Maintains a map of fds to event handlers. This is primarily to keep any
47   // references alive that may be bound in the std::function instances. It is
48   // not used at dispatch time to avoid performance problems with different
49   // versions of std::unordered_map.
50   std::unordered_map<int, Handler> handlers_;
51 
52   // List of fds to be removed from the map. The actual removal is performed
53   // by the event dispatch thread to avoid races.
54   std::vector<int> removed_handlers_;
55 
56   pdx::LocalHandle epoll_fd_;
57   pdx::LocalHandle event_fd_;
58 };
59 
60 }  // namespace dvr
61 }  // namespace android
62 
63 #endif  // ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
64