mama_status tick42rmdsBridgeMamaSubscription_create (subscriptionBridge* subscriber, const char* source, const char* symbol, mamaTransport transport, mamaQueue queue, mamaMsgCallbacks callback, mamaSubscription subscription, void* closure) { CHECK_SUBSCRIBER(subscriber); mama_status status; // get hold of the bridge implementation mamaBridgeImpl* bridgeImpl = mamaTransportImpl_getBridgeImpl(transport); if (!bridgeImpl) { mama_log (MAMA_LOG_LEVEL_ERROR, "tick42rmdsBridgeMamaSubscription_create(): Could not get bridge"); return MAMA_STATUS_PLATFORM; } RMDSBridgeImpl* upaBridge = NULL; if (MAMA_STATUS_OK != (status = mamaBridgeImpl_getClosure((mamaBridge) bridgeImpl, (void**) &upaBridge))) { mama_log (MAMA_LOG_LEVEL_ERROR, "tick42rmdsBridgeMamaSubscription_create(): Could not get UPA bridge object"); return status; } // actually lookup on the transport itself RMDSSubscriber_ptr_t sub = upaBridge->getTransportBridge(transport)->Subscriber(); sub->AddSubscription(subscriber, source, symbol, transport, queue, callback, subscription, closure); return MAMA_STATUS_OK; }
mama_status avisBridgeMamaTransport_destroy (transportBridge transport) { mama_status status; avisTransportBridge* transportBridge = (avisTransportBridge*) transport; avisBridgeImpl* avisBridge = NULL; mamaBridgeImpl* bridgeImpl = NULL; bridgeImpl = mamaTransportImpl_getBridgeImpl( avisTransport(transport)->mTransport); if (!bridgeImpl) { mama_log (MAMA_LOG_LEVEL_ERROR, "avisBridgeMamaTransport_destroy(): Could not get bridge"); free(transport); return MAMA_STATUS_PLATFORM; } status = mamaBridgeImpl_getClosure((mamaBridge) bridgeImpl, (void**) &avisBridge); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "avisBridgeMamaTransport_destroy(): Could not get Avis bridge object"); free(transport); return status; } if (1 == wInterlocked_read (&transportBridge->mDispatching)) { avisTransportBridge_stop (transportBridge); } elvin_remove_close_listener (transportBridge->mAvis, closeListener); if (!elvin_close (transportBridge->mAvis)) { /* there appears to be a race condition in Avis libs where router socket * can sometimes be closed before we receive the disconnect reply -- log * it, and continue */ log_avis_error(MAMA_LOG_LEVEL_FINE, transportBridge->mAvis); } wInterlocked_destroy (&transportBridge->mDispatching); wsem_destroy(&avisTransport(transport)->mAvisDispatchSem); free(avisTransport(transport)->mAvis); free(avisTransport(transport)); return MAMA_STATUS_OK; }
mama_status tick42rmdsBridgeMamaSubscription_destroy (subscriptionBridge subscriber) { CHECK_SUBSCRIBER(subscriber); // Get the Bridge subscription object RMDSBridgeSubscription* pSubscription = RMDSBridgeSub(subscriber); mama_status status; // get hold of the bridge implementation mamaBridgeImpl* bridgeImpl = mamaTransportImpl_getBridgeImpl(pSubscription->Transport()); if (!bridgeImpl) { mama_log (MAMA_LOG_LEVEL_ERROR, "tick42rmdsBridgeMamaSubscription_destroy(): Could not get bridge"); return MAMA_STATUS_PLATFORM; } RMDSBridgeImpl* upaBridge = NULL; if (MAMA_STATUS_OK != (status = mamaBridgeImpl_getClosure((mamaBridge) bridgeImpl, (void**) &upaBridge))) { mama_log (MAMA_LOG_LEVEL_ERROR, "tick42rmdsBridgeMamaSubscription_destroy(): Could not get UPA bridge object"); return status; } RMDSSubscriber_ptr_t sub = upaBridge->getTransportBridge(pSubscription->Transport())->Subscriber(); // grab stuff for onDestroyCB from our object before we kill it void * closure = pSubscription->Closure(); wombat_subscriptionDestroyCB destroyCb = pSubscription->Callback().onDestroy; mamaSubscription parent = pSubscription->Subscription(); sub->RemoveSubscription(pSubscription); //Invoke the subscription callback to inform that the bridge has been //destroyed. if (NULL != destroyCb) (*(wombat_subscriptionDestroyCB)destroyCb)(parent, closure); return MAMA_STATUS_OK; }
mama_status avisBridgeMamaTransport_create (transportBridge* result, const char* name, mamaTransport mamaTport ) { mama_status status; avisBridgeImpl* avisBridge = NULL; avisTransportBridge* transport = NULL; mamaBridgeImpl* bridgeImpl = NULL; const char* url = NULL; transport = (avisTransportBridge*)calloc( 1, sizeof( avisTransportBridge ) ); if (transport == NULL) return MAMA_STATUS_NOMEM; transport->mTransport = (mamaTransport) mamaTport; bridgeImpl = mamaTransportImpl_getBridgeImpl(mamaTport); if (!bridgeImpl) { mama_log (MAMA_LOG_LEVEL_ERROR, "avisBridgeMamaTransport_create(): Could not get bridge"); free(transport); return MAMA_STATUS_PLATFORM; } status = mamaBridgeImpl_getClosure((mamaBridge) bridgeImpl, (void**) &avisBridge); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "avisBridgeMamaTransport_create(): Could not get Avis bridge object"); free(transport); return status; } /* create the Elvin object */ transport->mAvis = (Elvin*)calloc (1, sizeof (Elvin)); if (transport->mAvis == NULL) { mama_log (MAMA_LOG_LEVEL_ERROR, "avisBridge_createImpl(): Could not create Elvin object"); free(transport); return MAMA_STATUS_PLATFORM; } /* open the server connection */ url = getURL(name); if (url == NULL) { mama_log (MAMA_LOG_LEVEL_NORMAL, "No %s property defined for transport : %s", TPORT_PARAM, name); return MAMA_STATUS_INVALID_ARG; } if (!elvin_open(transport->mAvis, url)) { mama_log (MAMA_LOG_LEVEL_ERROR, "open failed for %s: %s", TPORT_PARAM, name); log_avis_error(MAMA_LOG_LEVEL_ERROR, transport->mAvis); avisBridgeMamaTransport_destroy((transportBridge)transport); return MAMA_STATUS_PLATFORM; } wInterlocked_initialize (&transport->mDispatching); elvin_add_close_listener(transport->mAvis, closeListener, transport); wsem_init(&transport->mAvisDispatchSem, 0, 0); *result = (transportBridge) transport; return avisTransportBridge_start(transport); }
static mama_status _createByIndex (mamaPublisher* result, mamaTransport tport, int tportIndex, const char* symbol, const char* source, const char* root) { mama_status status = MAMA_STATUS_OK; mamaPublisherImpl* impl = NULL; mamaBridgeImpl* bridgeImpl = NULL; if (!result) { mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_create(): NULL" " publisher address"); return MAMA_STATUS_NULL_ARG; } *result = NULL; if (!tport) { mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_create(): NULL" " transport"); return MAMA_STATUS_INVALID_ARG; } mama_log (MAMA_LOG_LEVEL_FINE, "mamaPublisher_create(): " "Creating publisher for %s.%s.%s", root ? root : "", source ? source : "", symbol ? symbol : ""); /*Get the bridge impl from the transport - mandatory*/ bridgeImpl = mamaTransportImpl_getBridgeImpl (tport); if (!bridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL; impl = (mamaPublisherImpl*)calloc (1, sizeof (mamaPublisherImpl)); if (!impl) return MAMA_STATUS_NOMEM; impl->mPendingActions = list_create (sizeof(struct publisherClosure)); if (impl->mPendingActions == NULL) return MAMA_STATUS_NOMEM; impl->mBridgeImpl = bridgeImpl; impl->mTport = tport; if (MAMA_STATUS_OK!=(status=(bridgeImpl->bridgeMamaPublisherCreateByIndex ( &impl->mMamaPublisherBridgeImpl, tport, tportIndex, symbol, /* topic */ source, root, NULL, /* nativeQueueHandle */ (mamaPublisher)impl)))) /* topic */ { free (impl); return status; } mamaTransport_addPublisher(tport, impl, &impl->mTransportHandle); *result = (mamaPublisher)impl; return MAMA_STATUS_OK; }
/* Description : This function will populate the responder impl object by creating the arrays of publishers * and subscribers. Note that one of each of these objects must be created for each of the sub * transport bridges that are contained in the main transport. There will be multiple sub * transports used when load balancing. * Arguments : impl [I] The responder to populate. * Returns : MAMA_STATUS_NO_BRIDGE_IMPL * MAMA_STATUS_OK */ static mama_status populateCmResponder(mamaCmResponderImpl *impl) { /* Returns */ mama_status ret = MAMA_STATUS_NO_BRIDGE_IMPL; mamaQueue internalQueue = NULL; /* Get the default event queue from the bridgeImpl. */ mamaBridgeImpl *bridgeImpl = mamaTransportImpl_getBridgeImpl(impl->mTransport); if(bridgeImpl != NULL) { /* The same callbacks will be sent to each subscriber regardless of the bridge * transport being used. */ mamaMsgCallbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); callbacks.onCreate = createCB; callbacks.onError = errorCB; callbacks.onMsg = msgCB; callbacks.onDestroy = destroyCB; ret = mamaBridgeImpl_getInternalEventQueue((mamaBridge)bridgeImpl, &internalQueue); if (ret == MAMA_STATUS_OK) { /* Enumerate all the sub transport bridges in the transport. */ int nextTransportIndex = 0; mamaPublisher *nextPublisher = impl->publishers; mamaSubscription *nextSubscription = impl->subscriptions; while((ret == MAMA_STATUS_OK) && (nextTransportIndex < impl->numberTransportBridges)) { /* The publisher allows commands to respond to point to point requests * without creating a new publisher, this must be created using the correct * transport bridge. */ ret = mamaPublisher_createByIndex( nextPublisher, impl->mTransport, nextTransportIndex, MAMA_CM_PUB_TOPIC, NULL, NULL); if(ret == MAMA_STATUS_OK) { /* Allocate the subscription */ ret = mamaSubscription_allocate(nextSubscription); if(ret == MAMA_STATUS_OK) { /* Set the subscription's transport index to ensure that the right transport is used. */ mamaSubscription_setTransportIndex(*nextSubscription, nextTransportIndex); /* Create the subscription */ ret = mamaSubscription_createBasic( *nextSubscription, impl->mTransport, internalQueue, &callbacks, MAMA_CM_TOPIC, impl); if(ret == MAMA_STATUS_OK) { /* We don't want the CM subs to show up on the stats logger */ mamaSubscription_setLogStats(*nextSubscription, 0); } } } /* Increment the counts for the next iteration */ nextTransportIndex ++; nextPublisher ++; nextSubscription ++; } } } return ret; }