You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I seem to be getting a deadlock between IoTHubClient_UploadToBlobAsync and IoTHubClient_SendEventAsync when used with DeviceMethodCallback. Platform is MIPS Linux. As requested in #26 here is a repro:
#define_BSD_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include"azure_c_shared_utility/threadapi.h"
#include"azure_c_shared_utility/crt_abstractions.h"
#include"azure_c_shared_utility/platform.h"
#include"iothub_client.h"
#include"iothub_message.h"
#include"iothubtransportmqtt.h"staticint callbackCounter;
IOTHUB_CLIENT_HANDLE iotHubClientHandle;
typedefstructEVENT_INSTANCE_TAG
{
IOTHUB_MESSAGE_HANDLE messageHandle;
size_t messageTrackingId; // For tracking the messages within the user callback.
} EVENT_INSTANCE;
voidtakepicture(void);
staticintDeviceMethodCallback(constchar* method_name, constunsignedchar* payload, size_t size, unsignedchar** response, size_t* resp_size, void* userContextCallback)
{
(void)userContextCallback;
int status = 200;
printf("\r\nDevice Method called\r\n");
printf("Device Method name: %s\r\n", method_name);
printf("Device Method payload: %.*s\r\n", (int)size, (constchar*)payload);
if(strcmp(method_name,"takepicture")==0){
takepicture();
}
char* RESPONSE_STRING = "{ \"Response\": \"Nothing\" }";
printf("\r\nResponse status: %d\r\n", status);
printf("Response payload: %s\r\n\r\n", RESPONSE_STRING);
*resp_size = strlen(RESPONSE_STRING);
if ((*response = malloc(*resp_size)) == NULL)
{
status = -1;
}
else
{
(void)memcpy(*response, RESPONSE_STRING, *resp_size);
}
return status;
}
staticvoidSendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
{
EVENT_INSTANCE* eventInstance = (EVENT_INSTANCE*)userContextCallback;
(void)printf("Confirmation[%d] received for message tracking id = %zu with result = %s\r\n", callbackCounter, eventInstance->messageTrackingId, ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
callbackCounter++;
IoTHubMessage_Destroy(eventInstance->messageHandle);
}
voidtakepicture(void){
long length = 0;
unsignedchar* imagebuffer = NULL;
FILE* fo = fopen("/tmp/snap.jpg", "r");
if(fo)
{
fseek(fo, 0, SEEK_END);
length = ftell(fo);
fseek(fo, 0, SEEK_SET);
if(length)
{
imagebuffer = (unsignedchar *)malloc(length*sizeof(unsignedchar));
fread(imagebuffer, length, 1, fo);
printf("its %ld long\n",length);
if (IoTHubClient_UploadToBlobAsync(iotHubClientHandle, "file.jpg", (constunsignedchar*)imagebuffer, length, NULL, NULL) != IOTHUB_CLIENT_OK)
{
printf("Image failed to upload\n");
}
else
{
printf("Image has been created\n");
}
}
fclose(fo);
free(imagebuffer);
}
}
voidloop(void)
{
EVENT_INSTANCE messages[MESSAGE_COUNT];
int receiveContext = 0;
callbackCounter = 0;
if (platform_init() != 0)
{
fprintf(stderr,"Failed to initialize the platform.\r\n");
exit(1);
}
if ((iotHubClientHandle = IoTHubClient_CreateFromConnectionString("YOURSTRINGHERE", MQTT_Protocol)) == NULL)
{
(void)fprintf(stderr,"ERROR: iotHubClientHandle is NULL!\r\n");
exit(1);
}
bool traceOn = true;
IoTHubClient_SetOption(iotHubClientHandle, "logtrace", &traceOn);
if (IoTHubClient_SetDeviceMethodCallback(iotHubClientHandle, DeviceMethodCallback, &receiveContext) != IOTHUB_CLIENT_OK)
{
(void)fprintf(stderr,"ERROR: IoTHubClient_SetMessageCallback..........FAILED!\r\n");
exit(1);
}
(void)printf("IoTHubClient_SetMessageCallback...successful.\r\n");
/* Now that we are ready to receive commands, let's send some messages */size_t iterator = 0;
do
{
constchar* msgText = "test";
if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((constunsignedchar*)msgText, strlen(msgText))) == NULL)
{
(void)fprintf(stderr,"ERROR: iotHubMessageHandle is NULL!\r\n");
exit(1);
}
else
{
MAP_HANDLE propMap;
messages[iterator].messageTrackingId = iterator;
propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
(void)sprintf_s(propText, sizeof(propText), "PropMsg_%zu", iterator);
if (Map_AddOrUpdate(propMap, "PropName", propText) != MAP_OK)
{
(void)fprintf(stderr,"ERROR: Map_AddOrUpdate Failed!\r\n");
}
if (IoTHubClient_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle, SendConfirmationCallback, &messages[iterator]) != IOTHUB_CLIENT_OK)
{
(void)fprintf(stderr,"ERROR: IoTHubClient_SendEventAsync..........FAILED!\r\n");
exit(1);
}
else
{
(void)printf("IoTHubClient_SendEventAsync accepted message [%zu] for transmission to IoT Hub.\r\n", iterator);
}
}
}else {(void)printf("ERROR: NoDataFromGetInfo..........FAILED!\r\n");}
}
}
if(iterator % 20 == 0) {
takepicture(); // This works oddly enough
}
ThreadAPI_Sleep(20000);
iterator++;
} while (true);
IoTHubClient_Destroy(iotHubClientHandle);
platform_deinit();
}
intmain(void)
{
loop();
return0;
}
The text was updated successfully, but these errors were encountered:
I have recently checked in master branch fixes that would allow IoTHubClient_UploadToBlobAsync to be called from inside a device_method_callback function.
I am hoping this unblocks you. If you still encounter issues, please reply here.
I seem to be getting a deadlock between IoTHubClient_UploadToBlobAsync and IoTHubClient_SendEventAsync when used with DeviceMethodCallback. Platform is MIPS Linux. As requested in #26 here is a repro:
The text was updated successfully, but these errors were encountered: