The goal is to have a single-threaded event-driven framework. The end-user will do something like:
class MyEventFramework : public EventFramework {
protected:
virtual void onData (const Data& data);
virtual void onReport (const Report& report);
virtual void onUserRequest (const UserRequest& userRequest);
...
};
There are other components behind the scenes, like a series of timers, etc.
Most of these handlers are called by my own code, so I can use select() or a similar concept (kqueue(), epoll(), etc) over a series of file descriptors.
My issue is that the onData() routine is actually a callback from a third-party library, which I don’t have the source code for. Therefore, I can’t just use their file descriptor; I only know that something has happened via the callback.
Right now I have a multithreaded implementation of my framework; the logic leading up to onData() occurs in a separate thread before reaching the user. This is undesirable because it necessitates error-prone mutex locks, requires expensive thread switching (this is a low-latency application), and other problems. (To clarify, each handler in the framework must be atomic with respect to each other because of the potential for race conditions in the client application.)
Has anyone else encountered this before and lived to tell the tale?
If I understand correctly : your dispatching thread is blocked on some system call (say
selectorpoll), and you would like theonDatamember function to follow the same notification path.Using a pipe seems like a good solution to me without hurting the design too much :
selectmonitors one end of the pipeThis allows for a ‘thread jump’, the only issue being that the pipe should only be used as a notification facility : the parameter to the
onDatafunction will have to be queued somewhere between the pipe notification and the processing thread wake-up.