int MAMACALLTYPE mamaQueue_pollQueueSizeCb (void* closure) { size_t count = 0; mamaQueue queue = (mamaQueue)closure; mamaQueue_getEventCount (queue, &count); return count; }
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; }
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(); } }