/** * @abstract add a new link instance to the AthenaTransportLinkAdapter instance list * @discussion * * When athenaTransportLinkAdapter_Open is called on a link specific module, the module instantiates * the link and then creates a new AthenaTransportLink to interface with the AthenaTransportLinkAdapter. * The AthenaTransportLinkModule passes the new AthenaTransportLink to the AthenaTransportLinkAdapter by * calling AthenaTransportLinkAdapter_AddLink with the new link AthenaTransportLink data. The AthenaTransportLinkAdapter * then places the new link instance on its internal instance list in a pending state until it has been verified and ensures * that the new link doesn't collide (i.e. by name) with any currently registered link before returning success. * * New routable links are placed into instanceList slots that have previously been vacated before being added * to the end of the instanceList. This is in order to keep bit vectors that are based on the instanceList as * small as is necessary. * * @param [in] athenaTransportLinkAdapter link adapter instance * @param [in] linkInstance instance structure created by the link specific module * @return 0 on success, -1 with errno set to indicate the error * * Example: * @code * { * } * @endcode */ static int _athenaTransportLinkAdapter_AddLink(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, AthenaTransportLink *newTransportLink) { int linkId = -1; // Check for existing linkName in listenerList if (athenaTransportLinkAdapter->listenerList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->listenerList); index++) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->listenerList, index); if (strcmp(athenaTransportLink_GetName(athenaTransportLink), athenaTransportLink_GetName(newTransportLink)) == 0) { errno = EADDRINUSE; // name is already in listenerList return -1; } } } // Check for existing linkName in the instanceList if (athenaTransportLinkAdapter->instanceList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->instanceList); index++) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, index); if (athenaTransportLink) { if (strcmp(athenaTransportLink_GetName(athenaTransportLink), athenaTransportLink_GetName(newTransportLink)) == 0) { errno = EADDRINUSE; // name is already in instanceList return -1; } } else { // remember the first available index found along the way if (linkId == -1) { linkId = index; } } } } // Add to listenerList or instanceList athenaTransportLink_Acquire(newTransportLink); if (athenaTransportLink_IsNotRoutable(newTransportLink)) { // listener bool result = parcArrayList_Add(athenaTransportLinkAdapter->listenerList, newTransportLink); assertTrue(result, "parcArrayList_Add failed to add new listener"); } else { // routable link, add to instances using the last available id if one was seen if (linkId != -1) { parcArrayList_Set(athenaTransportLinkAdapter->instanceList, linkId, newTransportLink); } else { bool result = parcArrayList_Add(athenaTransportLinkAdapter->instanceList, newTransportLink); assertTrue(result, "parcArrayList_Add failed to add new link instance"); } } // If any transport link has a registered file descriptor add it to the general polling list. int eventFd = athenaTransportLink_GetEventFd(newTransportLink); if (eventFd != -1) { _add_to_pollfdList(athenaTransportLinkAdapter, newTransportLink, eventFd); } return 0; }
/** * @abstract called from the link specific adapter to coordinate the addition of a link instance * @discussion * * @param [in] athenaTransportLink link adapter instance * @param [in] athenaTransportLink link instance to add * @return 0 if successful, -1 on failure with errno set to indicate error * * Example: * @code * { * * } * @endcode */ static int _athenaTransportLinkModule_AddLink(AthenaTransportLinkModule *athenaTransportLinkModule, AthenaTransportLink *newTransportLink) { // up call to add link to transport adapter int result = athenaTransportLinkModule->addLink(athenaTransportLinkModule->addLinkContext, newTransportLink); if (result == 0) { athenaTransportLink_Acquire(newTransportLink); parcArrayList_Add(athenaTransportLinkModule->instanceList, newTransportLink); } return result; }