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;
}
Exemple #3
0
/*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;
}