blob: eb687f4e865dcda461026740e459fc2a8bde9274 [file] [log] [blame]
#ifndef ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
#define ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_
#include <sys/epoll.h>
#include <atomic>
#include <functional>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <vector>
#include <pdx/file_handle.h>
#include <pdx/status.h>
namespace android {
namespace dvr {
class EpollEventDispatcher {
public:
// Function type for event handlers. The handler receives a bitmask of the
// epoll events that occurred on the file descriptor associated with the
// handler.
using Handler = std::function<void(int)>;
EpollEventDispatcher();
~EpollEventDispatcher();
// |handler| is called on the internal dispatch thread when |fd| is signaled
// by events in |event_mask|.
pdx::Status<void> AddEventHandler(int fd, int event_mask, Handler handler);
pdx::Status<void> RemoveEventHandler(int fd);
void Stop();
private:
void EventThread();
std::thread thread_;
std::atomic<bool> exit_thread_{false};
// Protects handlers_ and removed_handlers_ and serializes operations on
// epoll_fd_ and event_fd_.
std::mutex lock_;
// Maintains a map of fds to event handlers. This is primarily to keep any
// references alive that may be bound in the std::function instances. It is
// not used at dispatch time to avoid performance problems with different
// versions of std::unordered_map.
std::unordered_map<int, Handler> handlers_;
// List of fds to be removed from the map. The actual removal is performed
// by the event dispatch thread to avoid races.
std::vector<int> removed_handlers_;
pdx::LocalHandle epoll_fd_;
pdx::LocalHandle event_fd_;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_SERVICES_DISPLAYD_EPOLL_EVENT_DISPATCHER_H_