108 lines
3.1 KiB
C
108 lines
3.1 KiB
C
|
#ifndef ANDROID_PDX_SERVICE_DISPATCHER_H_
|
||
|
#define ANDROID_PDX_SERVICE_DISPATCHER_H_
|
||
|
|
||
|
#include <memory>
|
||
|
#include <mutex>
|
||
|
#include <unordered_map>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <pdx/file_handle.h>
|
||
|
|
||
|
namespace android {
|
||
|
namespace pdx {
|
||
|
|
||
|
class Service;
|
||
|
|
||
|
/*
|
||
|
* ServiceDispatcher manages a list of Service instances and handles message
|
||
|
* reception and dispatch to the services. This makes repetitive dispatch tasks
|
||
|
* easier to implement.
|
||
|
*/
|
||
|
class ServiceDispatcher {
|
||
|
public:
|
||
|
// Get a new instance of ServiceDispatcher, or return nullptr if init failed.
|
||
|
static std::unique_ptr<ServiceDispatcher> Create();
|
||
|
|
||
|
~ServiceDispatcher();
|
||
|
|
||
|
/*
|
||
|
* Adds a service to the list of services handled by this dispatcher. This
|
||
|
* will fail if any threads are blocked waiting for messages in this
|
||
|
* dispatcher.
|
||
|
*
|
||
|
* Returns 0 on success; -EEXIST if the service was already added.
|
||
|
*/
|
||
|
int AddService(const std::shared_ptr<Service>& service);
|
||
|
|
||
|
/*
|
||
|
* Removes a service from this dispatcher. This will fail if any threads are
|
||
|
* blocked waiting for messages in this dispatcher.
|
||
|
*
|
||
|
* Returns 0 on success; -ENOENT if the service was not previously added;
|
||
|
* -EBUSY if there are threads in the dispatcher.
|
||
|
*/
|
||
|
int RemoveService(const std::shared_ptr<Service>& service);
|
||
|
|
||
|
/*
|
||
|
* Receive and dispatch one set of messages. Multiple threads may enter this
|
||
|
* method to create an implicit thread pool, as described for
|
||
|
* enterDispatchLoop() below, however this method exits after one dispatch
|
||
|
* cycle, requiring an external loop. This is useful when other work needs
|
||
|
* to be done in the service dispatch loop.
|
||
|
*/
|
||
|
int ReceiveAndDispatch();
|
||
|
|
||
|
/*
|
||
|
* Same as above with timeout in milliseconds. A negative value means
|
||
|
* infinite timeout, while a value of 0 means return immediately if no
|
||
|
* messages are available to receive.
|
||
|
*/
|
||
|
int ReceiveAndDispatch(int timeout);
|
||
|
|
||
|
/*
|
||
|
* Receive and dispatch messages until canceled. When more than one thread
|
||
|
* enters this method it creates an implicit thread pool to dispatch messages.
|
||
|
* Explicit thread pools may be created by using a single dispatch thread that
|
||
|
* hands Message instances (via move assignment) over to a queue of threads
|
||
|
* (or perhaps one of several) to handle.
|
||
|
*/
|
||
|
int EnterDispatchLoop();
|
||
|
|
||
|
/*
|
||
|
* Sets the canceled state of the dispatcher. When canceled is true, any
|
||
|
* threads blocked waiting for messages will return. This method waits until
|
||
|
* all dispatch threads have exited the dispatcher.
|
||
|
*/
|
||
|
void SetCanceled(bool cancel);
|
||
|
|
||
|
/*
|
||
|
* Gets the canceled state of the dispatcher.
|
||
|
*/
|
||
|
bool IsCanceled() const;
|
||
|
|
||
|
private:
|
||
|
ServiceDispatcher();
|
||
|
|
||
|
// Internal thread accounting.
|
||
|
int ThreadEnter();
|
||
|
void ThreadExit();
|
||
|
|
||
|
std::mutex mutex_;
|
||
|
std::condition_variable condition_;
|
||
|
std::atomic<bool> canceled_{false};
|
||
|
|
||
|
std::vector<std::shared_ptr<Service>> services_;
|
||
|
|
||
|
int thread_count_ = 0;
|
||
|
LocalHandle event_fd_;
|
||
|
LocalHandle epoll_fd_;
|
||
|
|
||
|
ServiceDispatcher(const ServiceDispatcher&) = delete;
|
||
|
void operator=(const ServiceDispatcher&) = delete;
|
||
|
};
|
||
|
|
||
|
} // namespace pdx
|
||
|
} // namespace android
|
||
|
|
||
|
#endif // ANDROID_PDX_SERVICE_DISPATCHER_H_
|