paho.mqtt.c icon indicating copy to clipboard operation
paho.mqtt.c copied to clipboard

Is there any race between original thread and new thread for callback calling?

Open z16166 opened this issue 3 years ago • 2 comments

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;
}

z16166 avatar Jun 14 '22 08:06 z16166

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()?

z16166 avatar Jun 15 '22 01:06 z16166

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.

icraggs avatar Jul 04 '22 10:07 icraggs

If there's a join, it should go in the disconnect call as per #1294

icraggs avatar Nov 27 '22 17:11 icraggs

A fix to #1294 has been added to the develop branch. The disconnect call synchronizes on the call to connectionLost.

icraggs avatar Nov 28 '22 13:11 icraggs