This is a producer-consumer scenario, and my preference is to implement a blocking queue.
The event handler pushes messages onto the queue. The worker thread blocks on the queue when it is empty, and wakes up when there is something to process.
The messages can be allocated and freed, but it's usually better if they are drawn from a free list. Messages are simply a union of types, with a type field and an id in common. Nice and simple.
Extending to multiple worker threads and/or new message types is straightforward.
You can easily find pre-written code for a blocking queue of this kind in your language of choice.
[There may be something about your constraints that don't fit this approach, but if so please edit your question to make it clear.]
There are three basic strategies for a variable length blocking queue in C++. Assume that a message is a union of different types of different sizes.
- The messages on the queue are fixed in size and contain a pointer to a message. Each message is allocated and freed as needed.
- The messages on the queue are fixed in size and contain a pointer to a message. Messages are kept in pools (free lists/arrays) to avoid allocation overhead.
- The messages on the queue are variable in size. They consist of a stream of bytes pushed onto the queue, with a length to know how much to pop off.
You can easily find sample code and full working examples by searching for "blocking queue variable length C++" or similar.