Example #1
0
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;
}
Example #2
0
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;
}      
Example #3
0
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;   
}
Example #4
0
mama_status
mamaDispatcher_destroy (mamaDispatcher dispatcher)
{
    mamaDispatcherImpl* impl = (mamaDispatcherImpl*)dispatcher;

    if (!impl)
        return MAMA_STATUS_NULL_ARG;

    /* Set dispatching atomic so dispatcher thread is ready to exit */
    wInterlocked_set(0, &impl->mIsDispatching);

    if (impl->mQueue)
    {
        mamaQueue_stopDispatch (impl->mQueue);
    }

    /* Wait for the thread to return. */
    wthread_join (impl->mThread, NULL);
    wInterlocked_destroy (&impl->mIsDispatching);

    /* Destroy the thread handle. */
    wthread_destroy(impl->mThread);

    impl->mQueue->mDispatcher = NULL;
    impl->mThread = 0; 
    free (impl);
    return MAMA_STATUS_OK;
}
Example #5
0
mama_status
mamaQueue_create_usingNative (mamaQueue* queue,
                              mamaBridge bridgeImpl,
                              void*      nativeQueue)
{
    mama_status     status  =   MAMA_STATUS_OK;
    mamaBridgeImpl* bImpl   =   (mamaBridgeImpl*)bridgeImpl;
    mamaQueueImpl*  impl    =   NULL;

    if (!bridgeImpl)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_create(): NULL bridge.");
        return MAMA_STATUS_NO_BRIDGE_IMPL;
    }
    if (!queue)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_create(): NULL queue"
                                         " address.");
        return MAMA_STATUS_NULL_ARG;
    }

    /*Create the queue structure*/
    impl = (mamaQueueImpl*)calloc (1, sizeof (mamaQueueImpl));

    if (!impl)
        return MAMA_STATUS_NOMEM;


    impl->mBridgeImpl           =   bImpl;
    impl->mMamaQueueBridgeImpl  =   NULL;
    impl->mDispatcher           =   NULL;
    impl->mQueueName            =   strdup ("NO_NAME");
    impl->mHighWatermark        =   0;
    impl->mLowWatermark         =   1;
    impl->mQueueMonitorCallbacks.onQueueHighWatermarkExceeded =   NULL;
    impl->mQueueMonitorCallbacks.onQueueLowWatermark          =   NULL;

    impl->mQueueMonitorClosure  =   NULL;

    /* Create the counter lock. */
    wInterlocked_set(0, &impl->mNumberOpenObjects);

    mamaQueue_createReuseableMsg(impl);

    /* Call the bridge impl specific queue create function*/
    if (MAMA_STATUS_OK!=(status=impl->mBridgeImpl->bridgeMamaQueueCreateUsingNative
                (&(impl->mMamaQueueBridgeImpl),
                 impl,
                 nativeQueue)))
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "Could not create queue bridge.");
        mamaQueue_destroy ((mamaQueue)impl);
        return status;
    }

    *queue = (mamaQueue)impl;

    return MAMA_STATUS_OK;
}
Example #6
0
mama_status
mamaDispatcher_create (mamaDispatcher *result,
                       mamaQueue      queue)
{
    mamaQueueImpl*      qImpl   = (mamaQueueImpl*)queue;
    mamaDispatcherImpl* impl    = NULL;

    if (!queue)
    {
        mama_log (MAMA_LOG_LEVEL_WARN, "mamaDispatcher_create(): NULL queue.");
        return MAMA_STATUS_INVALID_ARG;
    }

    if (!result)
    {
        mama_log (MAMA_LOG_LEVEL_WARN, "mamaDispatcher_create(): Invalid "
                                        "address");
        return MAMA_STATUS_NULL_ARG;
    }

    *result = NULL;

    /*A queue can only have a single dispatcher.*/
    if (qImpl->mDispatcher)
        return MAMA_STATUS_TOO_MANY_DISPATCHERS;

    impl = (mamaDispatcherImpl*)calloc( 1, sizeof(mamaDispatcherImpl) );
    if (impl == NULL)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaDispatcher_create(): Could not "
                                         "allocate dispatcher.");
        return MAMA_STATUS_NOMEM;
    }

    wInterlocked_initialize(&impl->mIsDispatching);
    wInterlocked_set(0, &impl->mIsDispatching);

    impl->mQueue = queue;
    if (wthread_create(&impl->mThread, NULL, dispatchThreadProc, impl))
    {
        free (impl);
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaDispatcher_create(): Could not "
                                        "create dispatch thread.");
        return MAMA_STATUS_SYSTEM_ERROR;
    }

    qImpl->mDispatcher = (mamaDispatcher)impl;
    *result = (mamaDispatcher)impl;

    return MAMA_STATUS_OK;
}
Example #7
0
void closeListener(Elvin* avis, 
                   CloseReason reason, 
                   const char* message, 
                   void* closure)
{
    const char*          errMsg = NULL;
    avisTransportBridge* bridge = (avisTransportBridge*) closure;

    if (bridge == NULL) 
    {
        mama_log (MAMA_LOG_LEVEL_FINE, 
            "Avis closeListener: could not get Avis transport bridge");
        return;
    }

    switch( reason )
    {
        case REASON_CLIENT_SHUTDOWN:            
            errMsg = "Avis client shutdown";
            break;
        case REASON_ROUTER_SHUTDOWN:            
            errMsg = "Avis router shutdown";
            break;
        case REASON_PROTOCOL_VIOLATION:         
            errMsg = "Avis protocol violation"; 
            break;
        case REASON_ROUTER_STOPPED_RESPONDING:  
            errMsg = "Avis router stopped responding"; 
            break;
        default:                                
            errMsg = "Unknown Avis error";
    }

    mama_log (MAMA_LOG_LEVEL_FINE, "%s : %s", errMsg, message);

    if (REASON_PROTOCOL_VIOLATION == reason)
    {
        /* Ignore protocol violations */
        return;
    }

    mamaTransportImpl_disconnect(
        bridge->mTransport, 
        MAMA_TRANSPORT_DISCONNECT, 
        NULL, 
        NULL);

    wInterlocked_set (0, &bridge->mDispatching);
}
Example #8
0
mama_status
mamaQueue_stopDispatch (mamaQueue queue)
{
    mamaQueueImpl* impl = (mamaQueueImpl*)queue;

    if (!impl)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR,
                  "mamaQueue_stopDispatch(): NULL queue.");
        return MAMA_STATUS_NULL_ARG;
    }

    wInterlocked_set (0, &impl->mIsDispatching);
    return impl->mBridgeImpl->bridgeMamaQueueStopDispatch
                            (impl->mMamaQueueBridgeImpl);
}
Example #9
0
mama_status
mamaQueue_timedDispatch (mamaQueue queue,
                         uint64_t  timeout)
{
    mamaQueueImpl* impl   = (mamaQueueImpl*)queue;

    if (!impl)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR,
                  "mamaQueue_timedDispatch(): NULL queue.");
        return MAMA_STATUS_NULL_ARG;
    }

    wInterlocked_set (1, &impl->mIsDispatching);
    return impl->mBridgeImpl->bridgeMamaQueueTimedDispatch
                            (impl->mMamaQueueBridgeImpl, timeout);
}
Example #10
0
mama_status
mamaQueue_create (mamaQueue* queue,
                  mamaBridge bridgeImpl)
{
    mama_status     status      =   MAMA_STATUS_OK;
    mamaBridgeImpl* bImpl       =   (mamaBridgeImpl*)bridgeImpl;
    mamaQueueImpl*  impl        =   NULL;

    if (!bridgeImpl)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_create(): NULL bridge.");
        return MAMA_STATUS_NO_BRIDGE_IMPL;
    }
    if (!queue)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaQueue_create(): NULL queue"
                                         " address.");
        return MAMA_STATUS_NULL_ARG;
    }

    /*Create the queue structure*/
    impl = (mamaQueueImpl*)calloc (1, sizeof (mamaQueueImpl));

    if (!impl)
        return MAMA_STATUS_NOMEM;

    impl->mBridgeImpl           =   bImpl;
    impl->mMamaQueueBridgeImpl  =   NULL;
    impl->mDispatcher           =   NULL;
    impl->mQueueName            =   strdup ("NO_NAME");
    impl->mHighWatermark        =   0;
    impl->mLowWatermark         =   1;
    impl->mQueueMonitorCallbacks.onQueueHighWatermarkExceeded =   NULL;
    impl->mQueueMonitorCallbacks.onQueueLowWatermark          =   NULL;

    impl->mQueueMonitorClosure  =   NULL;

    /* Create the counter lock. */
    wInterlocked_initialize(&impl->mNumberOpenObjects);
    wInterlocked_set(0, &impl->mNumberOpenObjects);



	/* Call the bridge impl specific queue create function*/
	if (MAMA_STATUS_OK!=(status=impl->mBridgeImpl->bridgeMamaQueueCreate
				(&(impl->mMamaQueueBridgeImpl),
				 impl)))
	{
		mama_log (MAMA_LOG_LEVEL_ERROR, "Could not create queue bridge.");
		mamaQueue_destroy ((mamaQueue)impl);
		return status;
	}

    /* Determine if object lock tracking is enabled. */
    {
        const char *propValue = mama_getProperty(MAMAQUEUE_PROPERTY_OBJECT_LOCK_TRACKING);

        /* Only do this if it's set. */
        if(NULL != propValue)
        {
            impl->mTrackObjectLocks = strtobool(propValue);
        }
    }

    *queue = (mamaQueue)impl;

    mamaQueue_enableStats((mamaQueue)impl);
    return MAMA_STATUS_OK;
}
Example #11
0
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);

    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))
    {
        wInterlocked_set (0, &impl->mIsDispatching);

        if (impl->mDispatcher)
        {
            /* Try to ensure that the dispatcher does not restart the queue
             * dispatching after we've stopped and destroy it. */
            mamaDispatcherImpl* dispatcherImpl = (mamaDispatcherImpl*)impl->mDispatcher;
            wInterlocked_set (0, &dispatcherImpl->mIsDispatching);
            dispatcherImpl->mQueue = NULL;
        }

        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.*/
            }
        }

        /*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);
        wInterlocked_destroy(&impl->mIsDispatching);

        /* Destroy the queue counter lock */
        wInterlocked_destroy(&gQueueNumber);

        free (impl);

        mama_log (MAMA_LOG_LEVEL_FINEST, "Leaving mamaQueue_destroy for queue 0x%X.", queue);
        status = MAMA_STATUS_OK;
    }

    return status;
}