int MAMACALLTYPE
mamaQueue_pollQueueSizeCb (void* closure)
{
    size_t count = 0;
    mamaQueue queue = (mamaQueue)closure;

    mamaQueue_getEventCount (queue, &count);

    return count;
}
Exemple #2
0
bool UPAConsumer::PumpQueueEvents()
{
	// before we do anything else, process any pending subscriptions
   owner_->ProcessPendingSubcriptions();

   // Now dispatch any incoming events from the mama queue
   size_t numEvents = 0;

  mama_status status = mamaQueue_getEventCount(requestQueue_, &numEvents);
   if ((status == MAMA_STATUS_OK) && (numEvents > 0))
   {
      // although we only really want to throttle subscriptions, for simplicity throttle everything here.  
      size_t eventsDispatched = 0;

      // so keep dispatching while there are events on the queue, we haven't hit the max per cycle
      //and we haven't hit the max pending limit
      while ((numEvents > eventsDispatched)
         && (eventsDispatched < maxDispatchesPerCycle_)
         && (StreamManager().countPendingItems() < maxPendingOpens_))
      {
         if (!runThread_)
         {
            return false;
         }

         mamaQueue_dispatchEvent(requestQueue_);	
         ++eventsDispatched;
      }

      t42log_debug("dispatched %d requests \n", eventsDispatched);
   }

   // This MUST be outside the loop as there may be no further events when the final items
   // are opened
   statsLogger_->SetPendingOpens((int)StreamManager().countPendingItems());
   statsLogger_->SetPendingCloses((int)StreamManager().PendingCloses());
   statsLogger_->SetOpenItems((int)StreamManager().OpenItems());
   statsLogger_->SetRequestQueueLength((int)numEvents);
   return true;
}
Exemple #3
0
void UPAProvider::Run()
{

    struct timeval time_interval;
    RsslRet	retval = 0;

    fd_set useRead;
    fd_set useExcept;
    fd_set useWrt;


    // prime the counter for ping checking
    lastPingCheck_ = utils::time::GetMilliCount();

    FD_ZERO(&readfds_);
    FD_ZERO(&exceptfds_);
    FD_ZERO(&wrtfds_);

    RsslError error;
    if (!Bind(portno_, &error))
    {
        t42log_error("Unable to start provider thread, bind return error %d ('%s') \n",error.sysError, error.text);
        return;
    }

    while(runThread_ == true)
    {

        useRead = readfds_;
        useExcept = exceptfds_;
        useWrt = wrtfds_;

        time_interval.tv_sec = selTimeoutSec;
        time_interval.tv_usec = selTimeoutUSec;

        // now process any queued publish events

        size_t numEvents = 0;

        size_t maxDispatchesPerCycle = 50;
        size_t maxPendingOpens = 500;
        mama_status status = mamaQueue_getEventCount(requestQueue_, &numEvents);
        if ((status == MAMA_STATUS_OK) && (numEvents > 0))
        {
            // although we only really want to throttle subscriptions, for simplicity throttle everything here.  
            size_t eventsDispatched = 0;

            // so keep dispatching while there are events on the queue, we haven t hit the mac per cycle and we havent hit the max pending limit
            while (numEvents > eventsDispatched && eventsDispatched < maxDispatchesPerCycle )
            {
                mamaQueue_dispatchEvent(requestQueue_);	
                ++eventsDispatched;
            }

            t42log_info("dispatched %d requests \n", eventsDispatched);
        }

        int selRet = select(FD_SETSIZE,&useRead, &useWrt,&useExcept,&time_interval);

        if (selRet == 0)
        {
            // timed out, no messages received so publish from queue
        }
        else if ( selRet > 0)
        {
            // read from the socket
            if ((rsslServer_ != NULL) && (rsslServer_->socketId != -1) && (FD_ISSET(rsslServer_->socketId,&useRead)))
            {
                // this is on the listening socket (rsslServer_->socketId)
                CreateNewClientConnection();
            }

            // so now read on all the channels
            for( int index = 0; index < maxClientConnections; index ++)
            {
                if ((clientConnections_[index].clientChannel != NULL) && (clientConnections_[index].clientChannel->socketId != -1))
                {
                    // theres a connection on this index so check the FDs
                    if ((FD_ISSET(clientConnections_[index].clientChannel->socketId, &useRead)) || (FD_ISSET(clientConnections_[index].clientChannel->socketId, &useExcept)))
                    {
                        // Theres something to read
                        ReadFromChannel(clientConnections_[index].clientChannel);
                    }

                    // The UPA provider sample ties these 2 conditions together but the problem then is that the
                    // ping initialization does happen until there is something to write (the write fd is set) and 
                    // there is no guarantee when that will happen. So here we check for active state on the channel 
                    // and whether the ping settings have been initialized before we check the write fd. Seems safer.
                    if (clientConnections_[index].clientChannel != NULL && clientConnections_[index].clientChannel->state == RSSL_CH_STATE_ACTIVE)
                    {
                        // if we havent set the ping times already (and the channel is now active) set them from the channel settings
                        if (clientConnections_[index].pingsInitialized != RSSL_TRUE)
                        {
                            InitChannelPingTimes(&clientConnections_[index]);
                            t42log_debug("Using %d as pingTimeout for Channel %d\n", clientConnections_[index].clientChannel->pingTimeout,clientConnections_[index].clientChannel->socketId);
                        }						
                        // if there is something to write and the channel is active thne flush the write socket
                        if (clientConnections_[index].clientChannel != NULL &&	FD_ISSET(clientConnections_[index].clientChannel->socketId, &useWrt))
                        {
                            if ((retval = rsslFlush(clientConnections_[index].clientChannel, &error)) < RSSL_RET_SUCCESS)
                            {
                                // the write failed. Kill the connection
                                t42log_error("rsslFlush() failed with return code %d - <%s>\n", retval, error.text);
                                RemoveChannelConnection(clientConnections_[index].clientChannel);
                            }
                            else if (retval == RSSL_RET_SUCCESS)
                            {
                                // clear the write fd
                                FD_CLR(clientConnections_[index].clientChannel->socketId, &wrtfds_);
                            }
                        }
                    }
                    // if there is something to write and the channel is active thne flush the write socket
                    if (clientConnections_[index].clientChannel != NULL &&	FD_ISSET(clientConnections_[index].clientChannel->socketId, &useWrt) &&
                        clientConnections_[index].clientChannel->state == RSSL_CH_STATE_ACTIVE)
                    {
                        // if we havent set the ping times already (and the channel is now active) set them from the channel settings
                        if (clientConnections_[index].pingsInitialized != RSSL_TRUE)
                        {
                            InitChannelPingTimes(&clientConnections_[index]);
                            t42log_debug("Using %d as pingTimeout for Channel %d\n", clientConnections_[index].clientChannel->pingTimeout,clientConnections_[index].clientChannel->socketId);
                        }


                        if ((retval = rsslFlush(clientConnections_[index].clientChannel, &error)) < RSSL_RET_SUCCESS)
                        {
                            // the write failed. Kill the connection
                            t42log_error("rsslFlush() failed with return code %d - <%s>\n", retval, error.text);
                            RemoveChannelConnection(clientConnections_[index].clientChannel);
                        }
                        else if (retval == RSSL_RET_SUCCESS)
                        {
                            // clear the write fd
                            FD_CLR(clientConnections_[index].clientChannel->socketId, &wrtfds_);
                        }
                    }
                }
            }
        }
        else
        {
            // handle error

#ifdef _WIN32
            if (WSAGetLastError() == WSAEINTR)
            {
                continue;
            }
            else
            {
                t42log_error("select() failed with error code %d\n", WSAGetLastError());
                break;
            }
#else
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                t42log_error("select() failed with error code %d\n", errno);
                break;
            }
#endif
        }


        HandlePings();

    }
}