I have a C++ project that uses SDL, in particular SDL Events. I would like to use the event system for incoming network messages just as it is used for UI events. I can define a new event type and attach some arbitrary data (see this example). This is what I would do if I was using ordinary pointers:
Uint32 message_event_type = SDL_RegisterEvents(1);
/* In the main event loop */
while (SDL_Poll(&evt)) {
if (evt.type == message_event_type) {
Message *msg = evt.user.data1;
handle_message(msg);
}
}
/* Networking code, possibly in another thread */
Message *msg = read_message_from_network();
SDL_Event evt;
evt.type = message_event_type;
evt.user.data1 = msg;
SDL_PostEvent(evt);
Instead, I've been using shared_ptr<Message>
up to now. Messages are read-only objects once constructed, and might be used in lots of places while being handled, so I thought to use shared_ptr for them.
I would like to use a shared_ptr to the message in the network side, and also on the event handling side. If I do this:
// in networking code:
shared_ptr<Message> msg = ...
evt.user.data1 = msg.get();
// later, in event handling:
shared_ptr<Message> msg(evt.user.data1);
then there are two independent shared_ptrs and either one could delete the Message object while the either is still using it. I would need to somehow pass the shared_ptr through the SDL_UserEvent struct, which only has a couple of void *
and int fields.
Additional. Note that SDL_PostEvent
returns immediately; the event itself is put on a queue. The event may be popped from the queue by the handler well after a shared_ptr to the message has gone out of scope in the networking code. So I can't pass the address of a local shared_ptr to copy from. By the time the copying occurs, it's likely to no longer be valid.
Has anyone faced a similar problem and knows of a nice solution?