in iothub_client/src/iothub_client_core.c [1223:1380]
void IoTHubClientCore_Destroy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle)
{
if (iotHubClientHandle != NULL)
{
bool joinClientThread;
bool joinTransportThread;
size_t vector_size;
IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
if (iotHubClientInstance->TransportHandle != NULL)
{
joinTransportThread = IoTHubTransport_SignalEndWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
}
else
{
joinTransportThread = false;
}
if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
{
LogError("unable to Lock - - will still proceed to try to end the thread without locking");
}
if (iotHubClientInstance->ThreadHandle != NULL)
{
iotHubClientInstance->StopThread = 1;
joinClientThread = true;
}
else
{
joinClientThread = false;
}
if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
{
LogError("unable to Unlock");
}
if (joinClientThread == true)
{
int res;
if (ThreadAPI_Join(iotHubClientInstance->ThreadHandle, &res) != THREADAPI_OK)
{
LogError("ThreadAPI_Join failed");
}
}
if (joinTransportThread == true)
{
IoTHubTransport_JoinWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
}
if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
{
LogError("unable to Lock - - will still proceed to try to end the thread without locking");
}
/*wait for all uploading threads to finish*/
while (singlylinkedlist_get_head_item(iotHubClientInstance->httpWorkerThreadInfoList) != NULL)
{
// Sleep between runs of the garbage collector in order to give the httpWorker threads time to execute.
// Otherwise we end up in a spin loop here.
unsigned int sleeptime_in_ms = (unsigned int)iotHubClientInstance->do_work_freq_ms;
Unlock(iotHubClientInstance->LockHandle);
ThreadAPI_Sleep(sleeptime_in_ms);
if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
{
LogError("unable to Lock - - will still proceed to try to end the thread without locking");
}
garbageCollectorImpl(iotHubClientInstance);
}
if (iotHubClientInstance->httpWorkerThreadInfoList != NULL)
{
singlylinkedlist_destroy(iotHubClientInstance->httpWorkerThreadInfoList);
}
IoTHubClientCore_LL_Destroy(iotHubClientInstance->IoTHubClientLLHandle);
if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
{
LogError("unable to Unlock");
}
vector_size = VECTOR_size(iotHubClientInstance->saved_user_callback_list);
size_t index = 0;
for (index = 0; index < vector_size; index++)
{
USER_CALLBACK_INFO* queue_cb_info = (USER_CALLBACK_INFO*)VECTOR_element(iotHubClientInstance->saved_user_callback_list, index);
if (queue_cb_info != NULL)
{
if ((queue_cb_info->type == CALLBACK_TYPE_DEVICE_METHOD) || (queue_cb_info->type == CALLBACK_TYPE_INBOUND_DEVICE_METHOD))
{
STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
}
else if (queue_cb_info->type == CALLBACK_TYPE_DEVICE_TWIN)
{
if (queue_cb_info->iothub_callback.dev_twin_cb_info.userCallback)
{
queue_cb_info->iothub_callback.dev_twin_cb_info.userCallback(
queue_cb_info->iothub_callback.dev_twin_cb_info.update_state,
queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad,
queue_cb_info->iothub_callback.dev_twin_cb_info.size,
queue_cb_info->iothub_callback.dev_twin_cb_info.userContext
);
}
if (queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad != NULL)
{
free(queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad);
}
}
else if (queue_cb_info->type == CALLBACK_TYPE_EVENT_CONFIRM)
{
if (queue_cb_info->iothub_callback.event_confirm_cb_info.eventConfirmationCallback)
{
queue_cb_info->iothub_callback.event_confirm_cb_info.eventConfirmationCallback(queue_cb_info->iothub_callback.event_confirm_cb_info.confirm_result, queue_cb_info->userContextCallback);
}
}
else if (queue_cb_info->type == CALLBACK_TYPE_REPORTED_STATE)
{
if (queue_cb_info->iothub_callback.reported_state_cb_info.reportedStateCallback)
{
queue_cb_info->iothub_callback.reported_state_cb_info.reportedStateCallback(queue_cb_info->iothub_callback.reported_state_cb_info.status_code, queue_cb_info->userContextCallback);
}
}
}
}
VECTOR_destroy(iotHubClientInstance->saved_user_callback_list);
if (iotHubClientInstance->TransportHandle == NULL)
{
Lock_Deinit(iotHubClientInstance->LockHandle);
}
if (iotHubClientInstance->devicetwin_user_context != NULL)
{
free(iotHubClientInstance->devicetwin_user_context);
}
if (iotHubClientInstance->connection_status_user_context != NULL)
{
free(iotHubClientInstance->connection_status_user_context);
}
if (iotHubClientInstance->message_user_context != NULL)
{
free(iotHubClientInstance->message_user_context);
}
if (iotHubClientInstance->method_user_context != NULL)
{
free(iotHubClientInstance->method_user_context);
}
free(iotHubClientInstance);
}
}