static bool signal_end_worker_thread(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_HANDLE clientHandle) { bool okToJoin; void* element = VECTOR_find_if(transportData->clients, find_by_handle, clientHandle); if (element != NULL) { /*Codes_SRS_IOTHUBTRANSPORT_17_026: [ IoTHubTransport_EndWorkerThread shall remove clientHandlehandle from handle list. ]*/ VECTOR_erase(transportData->clients, element, 1); } /*Codes_SRS_IOTHUBTRANSPORT_17_025: [ If the worker thread does not exist, then IoTHubTransport_EndWorkerThread shall return. ]*/ if (transportData->workerThreadHandle != NULL) { if (VECTOR_size(transportData->clients) == 0) { stop_worker_thread(transportData); okToJoin = true; } else { okToJoin = false; } } else { okToJoin = false; } return okToJoin; }
MODULE_LOADER* ModuleLoader_FindByName(const char* name) { MODULE_LOADER* result; if (name == NULL) { LogError("name is NULL"); /*Codes_SRS_MODULE_LOADER_13_036: [ ModuleLoader_FindByName shall return NULL if name is NULL. ]*/ result = NULL; } else { if (g_module_loaders.lock == NULL || g_module_loaders.module_loaders == NULL) { LogError("ModuleLoader_Initialize has not been called yet"); /*Codes_SRS_MODULE_LOADER_13_037: [ ModuleLoader_FindByName shall return NULL if g_module_loaders.lock is NULL. ]*/ /*Codes_SRS_MODULE_LOADER_13_038: [ ModuleLoader_FindByName shall return NULL if g_module_loaders.module_loaders is NULL.]*/ result = NULL; } else { /*Codes_SRS_MODULE_LOADER_13_040: [ ModuleLoader_FindByName shall lock g_module_loaders.lock. ]*/ if (Lock(g_module_loaders.lock) != LOCK_OK) { LogError("Lock failed"); /*Codes_SRS_MODULE_LOADER_13_039: [ ModuleLoader_FindByName shall return NULL if an underlying platform call fails. ]*/ result = NULL; } else { /*Codes_SRS_MODULE_LOADER_13_041: [ ModuleLoader_FindByName shall search for a module loader whose name is equal to name. The comparison is case sensitive. ]*/ /*Codes_SRS_MODULE_LOADER_13_042: [ ModuleLoader_FindByName shall return NULL if a matching module loader is not found. ]*/ /*Codes_SRS_MODULE_LOADER_13_043: [ ModuleLoader_FindByName shall return a pointer to the MODULE_LOADER if a matching entry is found. ]*/ MODULE_LOADER** loader_ref = (MODULE_LOADER**)VECTOR_find_if( g_module_loaders.module_loaders, find_module_loader_predicate, name ); result = loader_ref == NULL ? NULL : *loader_ref; /*Codes_SRS_MODULE_LOADER_13_044: [ ModuleLoader_FindByName shall unlock g_module_loaders.lock. ]*/ Unlock(g_module_loaders.lock); } } } return result; }
/*obs: value is already cloned at the time of calling this function */ static int createOrUpdateOption(HTTPAPIEX_HANDLE_DATA* handleData, const char* optionName, const void* value) { /*this function is called after the option value has been saved (cloned)*/ int result; /*decide bwtween update or create*/ HTTPAPIEX_SAVED_OPTION* whereIsIt = VECTOR_find_if(handleData->savedOptions, sameName, optionName); if (whereIsIt != NULL) { free((void*)(whereIsIt->value)); whereIsIt->value = value; result = 0; } else { HTTPAPIEX_SAVED_OPTION newOption; if (mallocAndStrcpy_s((char**)&(newOption.optionName), optionName) != 0) { free((void*)value); result = __LINE__; } else { newOption.value = value; if (VECTOR_push_back(handleData->savedOptions, &newOption, 1) != 0) { LogError("unable to VECTOR_push_back\r\n"); free((void*)newOption.optionName); free((void*)value); result = __LINE__; } else { result = 0; } } } return result; }
static IOTHUB_CLIENT_RESULT start_worker_if_needed(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_HANDLE clientHandle) { IOTHUB_CLIENT_RESULT result; if (transportData->workerThreadHandle == NULL) { /*Codes_SRS_IOTHUBTRANSPORT_17_018: [ If the worker thread does not exist, IoTHubTransport_StartWorkerThread shall start the thread using ThreadAPI_Create. ]*/ transportData->stopThread = 0; if (ThreadAPI_Create(&transportData->workerThreadHandle, transport_worker_thread, transportData) != THREADAPI_OK) { transportData->workerThreadHandle = NULL; } } if (transportData->workerThreadHandle != NULL) { /*Codes_SRS_IOTHUBTRANSPORT_17_020: [ IoTHubTransport_StartWorkerThread shall search for IoTHubClient clientHandle in the list of IoTHubClient handles. ]*/ bool addToList = ((VECTOR_size(transportData->clients) == 0) || (VECTOR_find_if(transportData->clients, find_by_handle, clientHandle) == NULL)); if (addToList) { /*Codes_SRS_IOTHUBTRANSPORT_17_021: [ If handle is not found, then clientHandle shall be added to the list. ]*/ if (VECTOR_push_back(transportData->clients, &clientHandle, 1) != 0) { /*Codes_SRS_IOTHUBTRANSPORT_17_042: [ If Adding to the client list fails, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_ERROR. ]*/ result = IOTHUB_CLIENT_ERROR; } else { result = IOTHUB_CLIENT_OK; } } else { result = IOTHUB_CLIENT_OK; } } else { result = IOTHUB_CLIENT_ERROR; } return result; }
DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data) { DATA_PUBLISHER_RESULT result; /*Codes_SRS_DATA_PUBLISHER_02_009: [ If argument transactionHandle is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ /*Codes_SRS_DATA_PUBLISHER_02_010: [ If argument reportedPropertyPath is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ /*Codes_SRS_DATA_PUBLISHER_02_011: [ If argument data is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ if ( (transactionHandle == NULL) || (reportedPropertyPath == NULL) || (data == NULL) ) { LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%p, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data); result = DATA_PUBLISHER_INVALID_ARG; } else { REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle; /*Codes_SRS_DATA_PUBLISHER_02_012: [ DataPublisher_PublishTransacted_ReportedProperty shall verify that a reported property having the path reportedPropertyPath exists in the model by calling Schema_ModelReportedPropertyByPathExists ]*/ if (!Schema_ModelReportedPropertyByPathExists(handleData->DataPublisherInstance->ModelHandle, reportedPropertyPath)) { /*Codes_SRS_DATA_PUBLISHER_02_013: [ If a reported property with path reportedPropertyPath does not exist in the model then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ LogError("unable to find a reported property by path \"%s\"", reportedPropertyPath); result = DATA_PUBLISHER_INVALID_ARG; } else { DATA_MARSHALLER_VALUE** existingValue = VECTOR_find_if(handleData->value, reportedPropertyExistsByPath, reportedPropertyPath); if(existingValue != NULL) { /*Codes_SRS_DATA_PUBLISHER_02_014: [ If the same (by reportedPropertypath) reported property has already been added to the transaction, then DataPublisher_PublishTransacted_ReportedProperty shall overwrite the previous reported property. ]*/ AGENT_DATA_TYPE *clone = (AGENT_DATA_TYPE *)malloc(sizeof(AGENT_DATA_TYPE)); if(clone == NULL) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ LogError("unable to malloc"); result = DATA_PUBLISHER_ERROR; } else { if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(clone, data) != AGENT_DATA_TYPES_OK) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE"); free(clone); result = DATA_PUBLISHER_ERROR; } else { /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/ Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)((*existingValue)->Value)); free((void*)((*existingValue)->Value)); (*existingValue)->Value = clone; result = DATA_PUBLISHER_OK; } } } else { /*totally new reported property*/ DATA_MARSHALLER_VALUE* newValue = (DATA_MARSHALLER_VALUE*)malloc(sizeof(DATA_MARSHALLER_VALUE)); if (newValue == NULL) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ LogError("unable to malloc"); result = DATA_PUBLISHER_ERROR; } else { if (mallocAndStrcpy_s((char**)&(newValue->PropertyPath), reportedPropertyPath) != 0) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ LogError("unable to mallocAndStrcpy_s"); free(newValue); result = DATA_PUBLISHER_ERROR; } else { if ((newValue->Value = (AGENT_DATA_TYPE*)malloc(sizeof(AGENT_DATA_TYPE))) == NULL) { LogError("unable to malloc"); free((void*)newValue->PropertyPath); free(newValue); result = DATA_PUBLISHER_ERROR; } else { if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value, data) != AGENT_DATA_TYPES_OK) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE"); free((void*)newValue->Value); free((void*)newValue->PropertyPath); free(newValue); result = DATA_PUBLISHER_ERROR; } else { /*Codes_SRS_DATA_PUBLISHER_02_015: [ DataPublisher_PublishTransacted_ReportedProperty shall add a new DATA_MARSHALLER_VALUE to the VECTOR_HANDLE. ]*/ if (VECTOR_push_back(handleData->value, &newValue, 1) != 0) { /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. */ LogError("unable to VECTOR_push_back"); Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value); free((void*)newValue->Value); free((void*)newValue->PropertyPath); free(newValue); result = DATA_PUBLISHER_ERROR; } else { /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/ result = DATA_PUBLISHER_OK; } } } } } } } } return result; }