I am using the Solace C API.
I want to associate a state object (in my case a C++ object, but to the C API it's just void*
user data) when a timer fires and Solace calls my timer callback routine. I register my timer with the Solace API call solClient_context_startTimer
.
Suppose I also want to cancel the timer from another thread, knowing its timer ID which has been returned by solClient_context_startTimer
. My problem is that I also want to de-allocate the state object. So the user-data pointer becomes dangling if the timer could ever fire from the context thread.
Could a race exist between the call to solClient_context_stopTimer
and the context thread entering the callback function to the now-dead timer?
If so, could anyone suggest ways to avoid trying to access the dangling pointer? I can think of starting points, but they are all have their own gotchas:
In addition, I see the timer ID is not passed to the timer routine so it is impossible for it to check on its own whether it is executing in that racy condition.
If solClient_context_stopTimer
blocks the current thread until any in-progress callback routines finish, then it would be easy to delete the state object only after making that call. But it is not clear from the API documentation whether solClient_context_stopTimer
has such behavior.
Yes, C
does not have smart pointers. The Solace C
API takes care of this case by waiting for the context thread to complete the timer callbacks, and would return SOLCLIENT_FAIL
the wait retries are too long.
In short, the race condition is taken care of and you should not need to have complex workarounds.