Is there any race between original thread and new thread for callback calling?
hi,
sometimes I got a crash in MQTT internal function connectionLost_call( ) when network fails or timeouts.
I just read the related code and find out that MQTT creates a new thread to call my connectionLost callback, and passes a pointer to the new thread. Is there any race condition for this pointer? for example, the new thread is using the pointer "m", while the original thread modifies/frees the pointer "m" or part of its fields.
MQTTClient_closeSession(m->c, reason, props);
exit:
if (stop)
MQTTClient_stop();
if (call_connection_lost && m->cl && was_connected)
{
Log(TRACE_MIN, -1, "Calling connectionLost for client %s", m->c->clientID);
Thread_start(connectionLost_call, m);
}
FUNC_EXIT_RC(rc);
static thread_return_type WINAPI connectionLost_call(void* context)
{
MQTTClients* m = (MQTTClients*)context;
(*(m->cl))(m->context, NULL);
return 0;
}
well, I have figured out that if I call MQTTClient_destroy() before MQTT calls my connection_lost callback, it will crash.
But I can't control when MQTT will call my connection_lost callback, so I can't wait/join its newly created thread.
Can you add a join in MQTTClient_destroy()?
Wouldn't the connectionLost call indicate that the connection failed so it's ok to call destroy? If you're not using the connectionLost callback to indicate that, you could just not set it.
If there's a join, it should go in the disconnect call as per #1294
A fix to #1294 has been added to the develop branch. The disconnect call synchronizes on the call to connectionLost.