/**
 * @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);
}
示例#2
0
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);
}
示例#3
0
/**
 * @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;
}