/** * @abstract called from below the link adapter to coordinate termination of a link instance * @discussion * * This is called exclusively from the Transport Link Module to instigate the removal of * an active link. The link has been flagged closing by the originator. This method * must ensure that all references to the link have been removed and then call the * instance close method to finish the operation. * * @param [in] athenaTransportLinkAdapter link adapter instance * @param [in] athenaTransportLink link instance to remove * * Example: * @code * { * * } * @endcode */ static void _athenaTransportLinkAdapter_RemoveLink(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, AthenaTransportLink *athenaTransportLink) { int linkId = -1; // if this is a listener it can simply be removed if (athenaTransportLink_IsNotRoutable(athenaTransportLink)) { if (athenaTransportLinkAdapter->listenerList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->listenerList); index++) { AthenaTransportLink *transportLink = parcArrayList_Get(athenaTransportLinkAdapter->listenerList, index); if (athenaTransportLink == transportLink) { parcArrayList_RemoveAtIndex(athenaTransportLinkAdapter->listenerList, index); _remove_from_pollfdList(athenaTransportLinkAdapter, athenaTransportLink); parcLog_Debug(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "listener removed: %s", athenaTransportLink_GetName(athenaTransportLink)); athenaTransportLink_Release(&athenaTransportLink); return; } } } } // Remove from our internal instance list. // The index entry remains to be reused by links that are added in the future. if (athenaTransportLinkAdapter->instanceList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->instanceList); index++) { AthenaTransportLink *transportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, index); if (athenaTransportLink == transportLink) { parcArrayList_Set(athenaTransportLinkAdapter->instanceList, index, NULL); _remove_from_pollfdList(athenaTransportLinkAdapter, athenaTransportLink); linkId = index; break; } } } assertFalse(linkId == -1, "Attempt to remove link not found in link adapter lists"); // Callback to notify that the link has been removed and references need to be dropped. PARCBitVector *linkVector = parcBitVector_Create(); parcBitVector_Set(linkVector, linkId); athenaTransportLinkAdapter->removeLink(athenaTransportLinkAdapter->removeLinkContext, linkVector); parcBitVector_Release(&linkVector); // we assume all references to the linkId associated with this instance have been // cleared from the PIT and FIB when removeLink returns. parcLog_Debug(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "link removed: %s", athenaTransportLink_GetName(athenaTransportLink)); athenaTransportLink_Release(&athenaTransportLink); }
void athenaTransportLink_Close(AthenaTransportLink *athenaTransportLink) { // XXX test and set if (athenaTransportLink_GetEvent(athenaTransportLink) & AthenaTransportLinkEvent_Closing) { return; } athenaTransportLink_SetEvent(athenaTransportLink, AthenaTransportLinkEvent_Closing); if (athenaTransportLink->closeMethod) { athenaTransportLink->stats.link_Closed++; athenaTransportLink->closeMethod(athenaTransportLink); } athenaTransportLink_RemoveLink(athenaTransportLink); athenaTransportLink_Release(&athenaTransportLink); }
/** * @abstract called from the link specific adapter to coordinate termination of a link instance * @discussion * * This is called exclusively from the Transport Link specific Module to instigate the * removal of an active link. The link is flagged as closing and the link module is called * to continue the operation. Eventually this should result in the link specific close * method being called, which should finish cleaning state, and deallocate the instance. * * @param [in] athenaTransportLink link adapter instance * @param [in] athenaTransportLink link instance to remove * * Example: * @code * { * * } * @endcode */ static void _athenaTransportLinkModule_RemoveLink(AthenaTransportLinkModule *athenaTransportLinkModule, AthenaTransportLink *athenaTransportLink) { // remove from our list for (int index = 0; index < parcArrayList_Size(athenaTransportLinkModule->instanceList); index++) { AthenaTransportLink *transportLink = parcArrayList_Get(athenaTransportLinkModule->instanceList, index); if (athenaTransportLink == transportLink) { AthenaTransportLink *removedInstance = parcArrayList_RemoveAtIndex(athenaTransportLinkModule->instanceList, index); assertTrue(removedInstance == athenaTransportLink, "Wrong link removed"); break; } } athenaTransportLinkModule->removeLink(athenaTransportLinkModule->removeLinkContext, athenaTransportLink); athenaTransportLink_Release(&athenaTransportLink); }
static AthenaTransportLink * _newLink(AthenaTransportLink *athenaTransportLink, _UDPLinkData *newLinkData) { // Accept a new tunnel connection. // Clone a new link from the current listener. const char *derivedLinkName = _createNameFromLinkData(&newLinkData->link); AthenaTransportLink *newTransportLink = athenaTransportLink_Clone(athenaTransportLink, derivedLinkName, _UDPSend, _UDPReceiveProxy, _UDPClose); if (newTransportLink == NULL) { parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "athenaTransportLink_Clone failed"); parcMemory_Deallocate(&derivedLinkName); _UDPLinkData_Destroy(&newLinkData); return NULL; } _setConnectLinkState(newTransportLink, newLinkData); // Send the new link up to be added. int result = athenaTransportLink_AddLink(athenaTransportLink, newTransportLink); if (result == -1) { parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "athenaTransportLink_AddLink failed: %s", strerror(errno)); _UDPLinkData_Destroy(&newLinkData); athenaTransportLink_Release(&newTransportLink); } else { parcLog_Info(athenaTransportLink_GetLogger(athenaTransportLink), "new link accepted by %s: %s %s", athenaTransportLink_GetName(athenaTransportLink), derivedLinkName, athenaTransportLink_IsNotLocal(athenaTransportLink) ? "" : "(Local)"); } parcMemory_Deallocate(&derivedLinkName); // Could pass a message back here regarding the new link. return newTransportLink; }