LONGBOW_TEST_CASE(Global, athena_ForwarderEngine) { // Create a new athena instance Athena *newAthena = athena_Create(AthenaDefaultContentStoreSize); assertNotNull(newAthena, "Could not create a new Athena instance"); // Add a link PARCURI *connectionURI = parcURI_Parse("tcp://localhost:50100/listener"); const char *result = athenaTransportLinkAdapter_Open(newAthena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed\n"); parcURI_Release(&connectionURI); pthread_t thread; // Passing in a reference that will be released by the new thread as the thread may not // have time to acquire a reference itself before we release our reference. int ret = pthread_create(&thread, NULL, athena_ForwarderEngine, (void *) athena_Acquire(newAthena)); assertTrue(ret == 0, "pthread_create failed"); athena_Release(&newAthena); // Create a new local instance we can send a quit message from Athena *athena = athena_Create(AthenaDefaultContentStoreSize); assertNotNull(athena, "Could not create a new Athena instance"); connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_1"); result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); PARCBitVector *linkVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_1"); parcBitVector_Set(linkVector, linkId); CCNxName *name = ccnxName_CreateFromCString(CCNxNameAthenaCommand_Quit); CCNxMetaMessage *interest = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); athena_EncodeMessage(interest); PARCBitVector *resultVector = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, interest, linkVector); assertNull(resultVector, "athenaTransportLinkAdapter_Send failed"); ccnxMetaMessage_Release(&interest); parcBitVector_Release(&linkVector); CCNxMetaMessage *response = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &resultVector, -1); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) > 0, "athenaTransportLinkAdapter_Receive failed"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&response); athenaTransportLinkAdapter_CloseByName(athena->athenaTransportLinkAdapter, "TCP_1"); pthread_join(thread, NULL); // Wait for the child athena to actually finish athena_Release(&athena); }
int main(int argc, char *argv[]) { _athenaLogo(); printf("\n"); Athena *athena = athena_Create(AthenaDefaultContentStoreSize); // Passing in a reference that will be released by athena_Process. athena_Process is used // in athena_InterestControl.c:_Control_Command as the entry point for spawned instances. // Spawned instances may not have have time to acquire a reference before our reference is // released so the reference is acquired for them. if (athena) { _parseCommandLine(athena, argc, argv); (void) athena_ForwarderEngine(athena_Acquire(athena)); } athena_Release(&athena); pthread_exit(NULL); // wait for any residual threads to exit return 0; }
static CCNxMetaMessage * _Control_Command_Spawn(Athena *athena, CCNxName *ccnxName, const char *command, const char *connectionSpecification) { CCNxMetaMessage *responseMessage; // Create a new athena instance Athena *newAthena = athena_Create(AthenaDefaultContentStoreSize); if (newAthena == NULL) { responseMessage = _create_response(athena, ccnxName, "Could not create a new Athena instance"); return responseMessage; } // Add the specified link PARCURI *connectionURI = parcURI_Parse(connectionSpecification); if (athenaTransportLinkAdapter_Open(newAthena->athenaTransportLinkAdapter, connectionURI) == NULL) { parcLog_Error(athena->log, "Unable to configure an interface. Exiting..."); responseMessage = _create_response(athena, ccnxName, "Unable to configure an Athena interface for thread"); parcURI_Release(&connectionURI); athena_Release(&newAthena); return responseMessage; } parcURI_Release(&connectionURI); pthread_t thread; // Passing in a reference that will be released by the new thread as the thread may not // have time to acquire a reference itself before we release our reference. if (pthread_create(&thread, NULL, _start_forwarder_instance, (void *) athena_Acquire(newAthena)) != 0) { responseMessage = _create_response(athena, ccnxName, "Athena process thread creation failed"); return responseMessage; } athena_Release(&newAthena); athenaInterestControl_LogConfigurationChange(athena, ccnxName, "%s", connectionSpecification); responseMessage = _create_response(athena, ccnxName, "Athena process thread started on %s", connectionSpecification); return responseMessage; }