static void NativeModuleHost_Receive(MODULE_HANDLE moduleHandle, MESSAGE_HANDLE messageHandle) { if (moduleHandle != NULL) { MODULE_HOST* module_host = (MODULE_HOST*)moduleHandle; /*Codes_SRS_NATIVEMODULEHOST_17_030: [ NativeModuleHost_Receive shall get the loaded module's MODULE_API pointer. ]*/ const MODULE_API* module_apis = module_host->module_loader->api->GetApi(module_host->module_loader, module_host->module_library_handle); if (module_apis != NULL) { pfModule_Receive pfReceive = MODULE_RECEIVE(module_apis); if (pfReceive != NULL) { /*Codes_SRS_NATIVEMODULEHOST_17_031: [ NativeModuleHost_Receive shall call the loaded module's _Receive function, passing the messageHandle along. ]*/ (pfReceive)(module_host->module, messageHandle); } else { LogError("Module API did not have a Receive function"); } } else { LogError("Module API not found"); } } else { /*Codes_SRS_NATIVEMODULEHOST_17_029: [ NativeModuleHost_Receive shall do nothing if moduleHandle is NULL. ]*/ LogError("Given module handle is NULL"); } }
/** * This function runs for each module. It receives a pointer to a MODULE_INFO * object that describes the module. Its job is to call the Receive function on * the associated module whenever it receives a message. */ static int module_worker(void * user_data) { /*Codes_SRS_BROKER_13_026: [This function shall assign `user_data` to a local variable called `module_info` of type `BROKER_MODULEINFO*`.]*/ BROKER_MODULEINFO* module_info = (BROKER_MODULEINFO*)user_data; int should_continue = 1; while (should_continue) { /*Codes_SRS_BROKER_13_089: [ This function shall acquire the lock on module_info->socket_lock. ]*/ if (Lock(module_info->socket_lock)) { /*Codes_SRS_BROKER_02_004: [ If acquiring the lock fails, then module_worker shall return. ]*/ LogError("unable to Lock"); should_continue = 0; break; } int nn_fd = module_info->receive_socket; int nbytes; unsigned char *buf = NULL; /*Codes_SRS_BROKER_17_005: [ For every iteration of the loop, the function shall wait on the receive_socket for messages. ]*/ nbytes = nn_recv(nn_fd, (void *)&buf, NN_MSG, 0); /*Codes_SRS_BROKER_13_091: [ The function shall unlock module_info->socket_lock. ]*/ if (Unlock(module_info->socket_lock) != LOCK_OK) { /*Codes_SRS_BROKER_17_016: [ If releasing the lock fails, then module_worker shall return. ]*/ should_continue = 0; if (nbytes > 0) { /*Codes_SRS_BROKER_17_019: [ The function shall free the buffer received on the receive_socket. ]*/ nn_freemsg(buf); } break; } if (nbytes < 0) { /*Codes_SRS_BROKER_17_006: [ An error on receiving a message shall terminate the loop. ]*/ should_continue = 0; } else { if (nbytes == BROKER_GUID_SIZE && (strncmp(STRING_c_str(module_info->quit_message_guid), (const char *)buf, BROKER_GUID_SIZE-1)==0)) { /*Codes_SRS_BROKER_13_068: [ This function shall run a loop that keeps running until module_info->quit_message_guid is sent to the thread. ]*/ /* received special quit message for this module */ should_continue = 0; } else { /*Codes_SRS_BROKER_17_024: [ The function shall strip off the topic from the message. ]*/ const unsigned char*buf_bytes = (const unsigned char*)buf; buf_bytes += sizeof(MODULE_HANDLE); /*Codes_SRS_BROKER_17_017: [ The function shall deserialize the message received. ]*/ MESSAGE_HANDLE msg = Message_CreateFromByteArray(buf_bytes, nbytes - sizeof(MODULE_HANDLE)); /*Codes_SRS_BROKER_17_018: [ If the deserialization is not successful, the message loop shall continue. ]*/ if (msg != NULL) { /*Codes_SRS_BROKER_13_092: [The function shall deliver the message to the module's callback function via module_info->module_apis. ]*/ MODULE_RECEIVE(module_info->module->module_apis)(module_info->module->module_handle, msg); /*Codes_SRS_BROKER_13_093: [ The function shall destroy the message that was dequeued by calling Message_Destroy. ]*/ Message_Destroy(msg); } } /*Codes_SRS_BROKER_17_019: [ The function shall free the buffer received on the receive_socket. ]*/ nn_freemsg(buf); } } return 0; }
static MODULE_LIBRARY_HANDLE NodeModuleLoader_Load(const MODULE_LOADER* loader, const void* entrypoint) { NODE_MODULE_HANDLE_DATA* result; // loader cannot be null if (loader == NULL) { //Codes_SRS_NODE_MODULE_LOADER_13_001 : [NodeModuleLoader_Load shall return NULL if loader is NULL.] result = NULL; LogError("invalid inputs - loader = %p", loader); } else { if (loader->type != NODEJS) { //Codes_SRS_NODE_MODULE_LOADER_13_002 : [NodeModuleLoader_Load shall return NULL if loader->type is not NODEJS.] result = NULL; LogError("loader->type is not NODEJS"); } else { result = (NODE_MODULE_HANDLE_DATA*)malloc(sizeof(NODE_MODULE_HANDLE_DATA)); if (result == NULL) { //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] LogError("malloc returned NULL"); } else { result->binding_module = NodeModuleLoader_LoadBindingModule(loader); if (result->binding_module == NULL) { LogError("NodeModuleLoader_LoadBindingModule returned NULL"); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] free(result); result = NULL; } else { //Codes_SRS_NODE_MODULE_LOADER_13_033: [ NodeModuleLoader_Load shall call DynamicLibrary_FindSymbol on the binding module handle with the symbol name Module_GetApi to acquire the function that returns the module's API table. ] pfModule_GetApi pfnGetAPI = (pfModule_GetApi)DynamicLibrary_FindSymbol(result->binding_module, MODULE_GETAPI_NAME); if (pfnGetAPI == NULL) { DynamicLibrary_UnloadLibrary(result->binding_module); free(result); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] result = NULL; LogError("DynamicLibrary_FindSymbol() returned NULL"); } else { //Codes_SRS_NODE_MODULE_LOADER_13_005 : [NodeModuleLoader_Load shall return a non - NULL pointer of type MODULE_LIBRARY_HANDLE when successful.] result->api = pfnGetAPI(Module_ApiGatewayVersion); //Codes_SRS_NODE_MODULE_LOADER_13_034: [ NodeModuleLoader_Load shall return NULL if the MODULE_API pointer returned by the binding module is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_035: [ NodeModuleLoader_Load shall return NULL if MODULE_API::version is greater than Module_ApiGatewayVersion. ] //Codes_SRS_NODE_MODULE_LOADER_13_036: [ NodeModuleLoader_Load shall return NULL if the Module_Create function in MODULE_API is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_037: [ NodeModuleLoader_Load shall return NULL if the Module_Receive function in MODULE_API is NULL. ] //Codes_SRS_NODE_MODULE_LOADER_13_038: [ NodeModuleLoader_Load shall return NULL if the Module_Destroy function in MODULE_API is NULL. ] /* if any of the required functions is NULL then we have a misbehaving module */ if (result->api == NULL || result->api->version > Module_ApiGatewayVersion || MODULE_CREATE(result->api) == NULL || MODULE_DESTROY(result->api) == NULL || MODULE_RECEIVE(result->api) == NULL) { LogError( "pfnGetapi() returned an invalid MODULE_API instance. " "result->api = %p, " "result->api->version = %d, " "MODULE_CREATE(result->api) = %p, " "MODULE_DESTROY(result->api) = %p, " "MODULE_RECEIVE(result->api) = %p, ", result->api, result->api != NULL ? result->api->version : 0x0, result->api != NULL ? MODULE_CREATE(result->api) : NULL, result->api != NULL ? MODULE_DESTROY(result->api) : NULL, result->api != NULL ? MODULE_RECEIVE(result->api) : NULL ); DynamicLibrary_UnloadLibrary(result->binding_module); free(result); //Codes_SRS_NODE_MODULE_LOADER_13_003 : [NodeModuleLoader_Load shall return NULL if an underlying platform call fails.] result = NULL; } } } } } } return result; }