1 #ifndef ANDROID_PDX_SERVICE_DISPATCHER_H_ 2 #define ANDROID_PDX_SERVICE_DISPATCHER_H_ 3 4 #include <memory> 5 #include <mutex> 6 #include <unordered_map> 7 #include <vector> 8 9 #include <pdx/file_handle.h> 10 11 namespace android { 12 namespace pdx { 13 14 class Service; 15 16 /* 17 * ServiceDispatcher manages a list of Service instances and handles message 18 * reception and dispatch to the services. This makes repetitive dispatch tasks 19 * easier to implement. 20 */ 21 class ServiceDispatcher { 22 public: 23 // Get a new instance of ServiceDispatcher, or return nullptr if init failed. 24 static std::unique_ptr<ServiceDispatcher> Create(); 25 26 ~ServiceDispatcher(); 27 28 /* 29 * Adds a service to the list of services handled by this dispatcher. This 30 * will fail if any threads are blocked waiting for messages in this 31 * dispatcher. 32 * 33 * Returns 0 on success; -EEXIST if the service was already added. 34 */ 35 int AddService(const std::shared_ptr<Service>& service); 36 37 /* 38 * Removes a service from this dispatcher. This will fail if any threads are 39 * blocked waiting for messages in this dispatcher. 40 * 41 * Returns 0 on success; -ENOENT if the service was not previously added; 42 * -EBUSY if there are threads in the dispatcher. 43 */ 44 int RemoveService(const std::shared_ptr<Service>& service); 45 46 /* 47 * Receive and dispatch one set of messages. Multiple threads may enter this 48 * method to create an implicit thread pool, as described for 49 * enterDispatchLoop() below, however this method exits after one dispatch 50 * cycle, requiring an external loop. This is useful when other work needs 51 * to be done in the service dispatch loop. 52 */ 53 int ReceiveAndDispatch(); 54 55 /* 56 * Same as above with timeout in milliseconds. A negative value means 57 * infinite timeout, while a value of 0 means return immediately if no 58 * messages are available to receive. 59 */ 60 int ReceiveAndDispatch(int timeout); 61 62 /* 63 * Receive and dispatch messages until canceled. When more than one thread 64 * enters this method it creates an implicit thread pool to dispatch messages. 65 * Explicit thread pools may be created by using a single dispatch thread that 66 * hands Message instances (via move assignment) over to a queue of threads 67 * (or perhaps one of several) to handle. 68 */ 69 int EnterDispatchLoop(); 70 71 /* 72 * Sets the canceled state of the dispatcher. When canceled is true, any 73 * threads blocked waiting for messages will return. This method waits until 74 * all dispatch threads have exited the dispatcher. 75 */ 76 void SetCanceled(bool cancel); 77 78 /* 79 * Gets the canceled state of the dispatcher. 80 */ 81 bool IsCanceled() const; 82 83 private: 84 ServiceDispatcher(); 85 86 // Internal thread accounting. 87 int ThreadEnter(); 88 void ThreadExit(); 89 90 std::mutex mutex_; 91 std::condition_variable condition_; 92 std::atomic<bool> canceled_{false}; 93 94 std::vector<std::shared_ptr<Service>> services_; 95 96 int thread_count_ = 0; 97 LocalHandle event_fd_; 98 LocalHandle epoll_fd_; 99 100 ServiceDispatcher(const ServiceDispatcher&) = delete; 101 void operator=(const ServiceDispatcher&) = delete; 102 }; 103 104 } // namespace pdx 105 } // namespace android 106 107 #endif // ANDROID_PDX_SERVICE_DISPATCHER_H_ 108