Home | History | Annotate | Download | only in pdx
      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