mama_status avisTransportBridge_stop(avisTransportBridge* transportBridge) { CHECK_TRANSPORT(transportBridge); if (0 == wInterlocked_read (&transportBridge->mDispatching)) { mama_log (MAMA_LOG_LEVEL_WARN, "avisTransportBridge_stop(): " "Avis already stopped"); log_avis_error (MAMA_LOG_LEVEL_WARN, transportBridge->mAvis); return MAMA_STATUS_OK; } wInterlocked_set (0, &transportBridge->mDispatching); /* Dispatch a dummy notification to get the event polling to iterate * another loop and examine the mDispatching state */ elvin_invoke (transportBridge->mAvis, &closeNotification, transportBridge); while (-1 == wsem_wait(&transportBridge->mAvisDispatchSem)) { if (errno != EINTR) return MAMA_STATUS_SYSTEM_ERROR; } wthread_join (transportBridge->mThreadId, NULL); return MAMA_STATUS_OK; }
mama_status avisTransportBridge_start(avisTransportBridge* transportBridge) { /* stop Avis event loop */ int rc; CHECK_TRANSPORT(transportBridge); if (1 == wInterlocked_read (&transportBridge->mDispatching)) { mama_log (MAMA_LOG_LEVEL_WARN, "avisTransportBridge_start(): " "Avis already dispatching"); log_avis_error (MAMA_LOG_LEVEL_WARN, transportBridge->mAvis); return MAMA_STATUS_OK; } wInterlocked_set (1, &transportBridge->mDispatching); rc = wthread_create (&transportBridge->mThreadId, NULL, avisDispatchThread, transportBridge); if (0 != rc) { mama_log (MAMA_LOG_LEVEL_ERROR, "wthread_create returned %d", rc); return MAMA_STATUS_SYSTEM_ERROR; } return MAMA_STATUS_OK; }
int avisTransportBridge_isDispatching ( avisTransportBridge* transportBridge) { CHECK_TRANSPORT(transportBridge); return wInterlocked_read (&transportBridge->mDispatching); }
static void *dispatchThreadProc( void *closure ) { mamaDispatcherImpl* impl = (mamaDispatcherImpl*)closure; wInterlocked_set (1, &impl->mIsDispatching); while (wInterlocked_read (&impl->mIsDispatching) && MAMA_STATUS_OK == mamaQueue_dispatch (impl->mQueue)); wInterlocked_set (0, &impl->mIsDispatching); return NULL; }
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; }
void* avisDispatchThread(void* closure) { avisTransportBridge* transportBridge = (avisTransportBridge*) closure; while (1 == wInterlocked_read (&transportBridge->mDispatching)) { elvin_poll (transportBridge->mAvis); if (ELVIN_ERROR_TIMEOUT == transportBridge->mAvis->error.code) { /* Timeout is acceptable and expected */ elvin_error_reset (&transportBridge->mAvis->error); } } wsem_post (&transportBridge->mAvisDispatchSem); return NULL; }
mama_status mamaQueue_canDestroy(mamaQueue queue) { /* Returns. */ mama_status ret = MAMA_STATUS_NULL_ARG; if(queue != NULL) { /* Cast the queue to an impl. */ mamaQueueImpl *impl = (mamaQueueImpl *)queue; /* If the number of objects is 0 then the queue can be destroyed. */ ret = MAMA_STATUS_QUEUE_OPEN_OBJECTS; if(0 == wInterlocked_read(&impl->mNumberOpenObjects)) { ret = MAMA_STATUS_OK; } } return ret; }
mama_status mamaQueue_destroy (mamaQueue queue) { mamaQueueImpl* impl = (mamaQueueImpl*)queue; mama_status status = MAMA_STATUS_OK; mama_log (MAMA_LOG_LEVEL_FINEST, "Entering mamaQueue_destroy for queue 0x%X.", queue); impl->mIsDispatching = 0; if (!queue) { mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_destroy(): NULL queue."); return MAMA_STATUS_NULL_ARG; } /* The queue can only be destroyed if there are no open event objects. */ status = MAMA_STATUS_QUEUE_OPEN_OBJECTS; /* Only continue if the object count is 0. */ if(0 == wInterlocked_read(&impl->mNumberOpenObjects)) { if (impl->mMamaQueueBridgeImpl) { if (MAMA_STATUS_OK!=(status=impl->mBridgeImpl->bridgeMamaQueueDestroy ( impl->mMamaQueueBridgeImpl))) { mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_destroy(): Could not destroy queue bridge."); /*We should continue and free up the rest of the structure.*/ } } if (impl->mDispatcher) { /* We don't want the dispatcher to access a destroyed queue */ ((mamaDispatcherImpl*)(impl->mDispatcher))->mIsDispatching = 0; ((mamaDispatcherImpl*)(impl->mDispatcher))->mQueue = NULL; } /*Destroy the cached mamaMsg - no longer needed*/ if (impl->mMsg) mamaMsg_destroy (impl->mMsg); if (impl->mInitialStat) { mamaStat_destroy (impl->mInitialStat); impl->mInitialStat = NULL; } if (impl->mRecapStat) { mamaStat_destroy (impl->mRecapStat); impl->mRecapStat = NULL; } if (impl->mUnknownMsgStat) { mamaStat_destroy (impl->mUnknownMsgStat); impl->mUnknownMsgStat = NULL; } if (impl->mMessageStat) { mamaStat_destroy (impl->mMessageStat); impl->mMessageStat = NULL; } if (impl->mQueueSizeStat) { mamaStat_destroy (impl->mQueueSizeStat); impl->mQueueSizeStat = NULL; } if (impl->mSubscriptionStat) { mamaStat_destroy (impl->mSubscriptionStat); impl->mSubscriptionStat = NULL; } if (impl->mTimeoutStat) { mamaStat_destroy (impl->mTimeoutStat); impl->mTimeoutStat = NULL; } if (impl->mWombatMsgsStat) { mamaStat_destroy (impl->mWombatMsgsStat); impl->mWombatMsgsStat = NULL; } if (impl->mFastMsgsStat) { mamaStat_destroy (impl->mFastMsgsStat); impl->mFastMsgsStat = NULL; } if (impl->mRvMsgsStat) { mamaStat_destroy (impl->mRvMsgsStat); impl->mRvMsgsStat = NULL; } if (impl->mStatsCollector) { mamaStatsGenerator_removeStatsCollector (mamaInternal_getStatsGenerator(), impl->mStatsCollector); mamaStatsCollector_destroy (impl->mStatsCollector); impl->mStatsCollector = NULL; } if (impl->mQueueName) free ((void*)impl->mQueueName); impl->mBridgeImpl = NULL; impl->mMamaQueueBridgeImpl = NULL; impl->mMsg = NULL; /* Destroy the counter lock */ wInterlocked_destroy(&impl->mNumberOpenObjects); free (impl); mama_log (MAMA_LOG_LEVEL_FINEST, "Leaving mamaQueue_destroy for queue 0x%X.", queue); status = MAMA_STATUS_OK; } return status; }
int mamaQueueImpl_isDispatching (mamaQueue queue) { mamaQueueImpl* impl = (mamaQueueImpl*)queue; return wInterlocked_read (&impl->mIsDispatching); }