void Session::HandleChannelEnablingMessage(ByteBuffer& packet) { ChannelEnablingMessage data; data.Deserialize(packet); if(data.enable) { if(!HasChannel(data.channel)) m_channels.insert(data.channel); } else RemoveChannel(data.channel); Send(ChannelEnablingChangeMessage(data.channel, data.enable)); }
void UPAConsumer::RecoverConnection() { // notify listeners that we are not connected mama_log (MAMA_LOG_LEVEL_FINE, "Recovering Connection"); NotifyListeners(false, "Recovering Connection"); // reset the channel if ((rsslConsumerChannel_ != NULL) && (rsslConsumerChannel_->socketId != -1)) { RemoveChannel(rsslConsumerChannel_); rsslConsumerChannel_ = NULL; } // and flag a reconnect shouldRecoverConnection_ = RSSL_TRUE; }
void ChatChannelList::Process() { LinkedListIterator<ChatChannel*> iterator(ChatChannels); iterator.Reset(); while(iterator.MoreElements()) { ChatChannel *CurrentChannel = iterator.GetData(); if(CurrentChannel && CurrentChannel->ReadyToDelete()) { _log(UCS__TRACE, "Empty temporary password protected channel %s being destroyed.", CurrentChannel->GetName().c_str()); RemoveChannel(CurrentChannel); } iterator.Advance(); } }
ChatChannel *ChatChannelList::RemoveClientFromChannel(std::string inChannelName, Client *c) { if(!c) return nullptr; std::string ChannelName = inChannelName; if((inChannelName.length() > 0) && isdigit(ChannelName[0])) ChannelName = c->ChannelSlotName(atoi(inChannelName.c_str())); ChatChannel *RequiredChannel = FindChannel(ChannelName); if(!RequiredChannel) return nullptr; // RemoveClient will return false if there is no-one left in the channel, and the channel is not permanent and has // no password. // if(!RequiredChannel->RemoveClient(c)) RemoveChannel(RequiredChannel); return RequiredChannel; }
/** * ParseLineArgV * * Parses and processes a line which was sent by the server. * * @param argc number of tokens * @param argv the tokens */ bool CIRCConnection::ParseLineArgV(int argc, const char **argv) { CChannel *Channel; CClientConnection *Client; m_LastResponse = g_CurrentTime; if (argc < 2) { return true; } const char *Reply = argv[0]; const char *Raw = argv[1]; char *Nick = ::NickFromHostmask(Reply); int iRaw = atoi(Raw); bool b_Me = false; if (m_CurrentNick != NULL && Nick != NULL && strcasecmp(Nick, m_CurrentNick) == 0) { b_Me = true; } free(Nick); Client = GetOwner()->GetClientConnectionMultiplexer(); // HASH values CHashCompare hashRaw(argv[1]); static CHashCompare hashPrivmsg("PRIVMSG"); static CHashCompare hashNotice("NOTICE"); static CHashCompare hashJoin("JOIN"); static CHashCompare hashPart("PART"); static CHashCompare hashKick("KICK"); static CHashCompare hashNick("NICK"); static CHashCompare hashQuit("QUIT"); static CHashCompare hashMode("MODE"); static CHashCompare hashTopic("TOPIC"); static CHashCompare hashPong("PONG"); // END of HASH values if (argc > 3 && iRaw == 433) { bool ReturnValue = ModuleEvent(argc, argv); if (ReturnValue) { if (GetCurrentNick() == NULL) { WriteLine("NICK :%s_", argv[3]); } if (m_NickCatchTimer == NULL) { m_NickCatchTimer = new CTimer(30, false, NickCatchTimer, this); } } return ReturnValue; } else if (argc > 3 && hashRaw == hashPrivmsg && Client == NULL) { const char *Host; const char *Dest = argv[2]; char *Nick = ::NickFromHostmask(Reply); Channel = GetChannel(Dest); if (Channel != NULL) { CNick *User = Channel->GetNames()->Get(Nick); if (User != NULL) { User->SetIdleSince(g_CurrentTime); } Channel->AddBacklogLine(argv[0], argv[3]); } if (!ModuleEvent(argc, argv)) { free(Nick); return false; } /* don't log ctcp requests */ if (argv[3][0] != '\1' && argv[3][strlen(argv[3]) - 1] != '\1' && Dest != NULL && Nick != NULL && m_CurrentNick != NULL && strcasecmp(Dest, m_CurrentNick) == 0 && strcasecmp(Nick, m_CurrentNick) != 0) { char *Dup; char *Delim; Dup = strdup(Reply); if (AllocFailed(Dup)) { free(Nick); return true; } Delim = strchr(Dup, '!'); if (Delim != NULL) { *Delim = '\0'; Host = Delim + 1; } GetOwner()->Log("%s (%s): %s", Dup, Delim ? Host : "<unknown host>", argv[3]); free(Dup); } free(Nick); UpdateHostHelper(Reply); return true; } else if (argc > 3 && hashRaw == hashPrivmsg && Client != NULL) { Channel = GetChannel(argv[2]); if (Channel != NULL) { Channel->AddBacklogLine(argv[0], argv[3]); } } else if (argc > 3 && hashRaw == hashNotice && Client == NULL) { const char *Dest = argv[2]; char *Nick; if (!ModuleEvent(argc, argv)) { return false; } Nick = ::NickFromHostmask(Reply); /* don't log ctcp replies */ if (argv[3][0] != '\1' && argv[3][strlen(argv[3]) - 1] != '\1' && Dest != NULL && Nick != NULL && m_CurrentNick != NULL && strcasecmp(Dest, m_CurrentNick) == 0 && strcasecmp(Nick, m_CurrentNick) != 0) { GetOwner()->Log("%s (notice): %s", Reply, argv[3]); } free(Nick); return true; } else if (argc > 2 && hashRaw == hashJoin) { if (b_Me) { AddChannel(argv[2]); /* GetOwner() can be NULL if AddChannel failed */ if (GetOwner() != NULL && Client == NULL) { WriteLine("MODE %s", argv[2]); } } Channel = GetChannel(argv[2]); if (Channel != NULL) { Nick = NickFromHostmask(Reply); if (AllocFailed(Nick)) { return false; } Channel->AddUser(Nick, '\0'); free(Nick); } UpdateHostHelper(Reply); } else if (argc > 2 && hashRaw == hashPart) { bool bRet = ModuleEvent(argc, argv); if (b_Me) { RemoveChannel(argv[2]); } else { Channel = GetChannel(argv[2]); if (Channel != NULL) { Nick = ::NickFromHostmask(Reply); if (AllocFailed(Nick)) { return false; } Channel->RemoveUser(Nick); free(Nick); } } UpdateHostHelper(Reply); return bRet; } else if (argc > 3 && hashRaw == hashKick) { bool bRet = ModuleEvent(argc, argv); if (m_CurrentNick != NULL && strcasecmp(argv[3], m_CurrentNick) == 0) { RemoveChannel(argv[2]); if (Client == NULL) { char *Dup = strdup(Reply); if (AllocFailed(Dup)) { return bRet; } char *Delim = strchr(Dup, '!'); const char *Host = NULL; if (Delim) { *Delim = '\0'; Host = Delim + 1; } GetOwner()->Log("%s (%s) kicked you from %s (%s)", Dup, Delim ? Host : "<unknown host>", argv[2], argc > 4 ? argv[4] : ""); free(Dup); } } else { Channel = GetChannel(argv[2]); if (Channel != NULL) { Channel->RemoveUser(argv[3]); } } UpdateHostHelper(Reply); return bRet; } else if (argc > 2 && iRaw == 1) { if (Client != NULL) { if (strcmp(Client->GetNick(), argv[2]) != 0) { Client->WriteLine(":%s!%s NICK :%s", Client->GetNick(), m_Site ? m_Site : "*****@*****.**", argv[2]); } } free(m_CurrentNick); m_CurrentNick = strdup(argv[2]); free(m_Server); m_Server = strdup(Reply); } else if (argc > 2 && hashRaw == hashNick) { if (b_Me) { free(m_CurrentNick); m_CurrentNick = strdup(argv[2]); } Nick = NickFromHostmask(argv[0]); int i = 0; if (!b_Me && GetOwner()->GetClientConnectionMultiplexer() == NULL) { const char *AwayNick = GetOwner()->GetAwayNick(); if (AwayNick != NULL && strcasecmp(AwayNick, Nick) == 0) { WriteLine("NICK %s", AwayNick); } } while (hash_t<CChannel *> *ChannelHash = m_Channels->Iterate(i++)) { ChannelHash->Value->RenameUser(Nick, argv[2]); } free(Nick); } else if (argc > 1 && hashRaw == hashQuit) { bool bRet = ModuleEvent(argc, argv); Nick = NickFromHostmask(argv[0]); int i = 0; while (hash_t<CChannel *> *ChannelHash = m_Channels->Iterate(i++)) { ChannelHash->Value->RemoveUser(Nick); } free(Nick); return bRet; } else if (argc > 1 && (iRaw == 422 || iRaw == 376)) { int DelayJoin = GetOwner()->GetDelayJoin(); if (m_State != State_Connected) { const CVector<CModule *> *Modules = g_Bouncer->GetModules(); for (int i = 0; i < Modules->GetLength(); i++) { (*Modules)[i]->ServerLogon(GetOwner()->GetUsername()); } const char *ClientNick; if (Client != NULL) { ClientNick = Client->GetNick(); if (strcmp(m_CurrentNick, ClientNick) != 0) { Client->ChangeNick(m_CurrentNick); } } GetOwner()->Log("You were successfully connected to an IRC server."); g_Bouncer->Log("User %s connected to an IRC server.", GetOwner()->GetUsername()); } if (DelayJoin == 1) { m_DelayJoinTimer = g_Bouncer->CreateTimer(5, false, DelayJoinTimer, this); } else if (DelayJoin == 0) { JoinChannels(); } if (Client == NULL) { bool AppendTS = (GetOwner()->GetConfig()->ReadInteger("user.ts") != 0); const char *AwayReason = GetOwner()->GetAwayText(); if (AwayReason != NULL) { WriteLine(AppendTS ? "AWAY :%s (Away since the dawn of time)" : "AWAY :%s", AwayReason); } } const char *AutoModes = GetOwner()->GetAutoModes(); const char *DropModes = GetOwner()->GetDropModes(); if (AutoModes != NULL) { WriteLine("MODE %s +%s", GetCurrentNick(), AutoModes); } if (DropModes != NULL && Client == NULL) { WriteLine("MODE %s -%s", GetCurrentNick(), DropModes); } m_State = State_Connected; } else if (argc > 1 && strcasecmp(Reply, "ERROR") == 0) { if (strstr(Raw, "throttle") != NULL) { GetOwner()->ScheduleReconnect(120); } else { GetOwner()->ScheduleReconnect(5); } if (GetCurrentNick() != NULL && GetSite() != NULL) { g_Bouncer->LogUser(GetUser(), "Error received for user %s [%s!%s]: %s", GetOwner()->GetUsername(), GetCurrentNick(), GetSite(), argv[1]); } else { g_Bouncer->LogUser(GetUser(), "Error received for user %s: %s", GetOwner()->GetUsername(), argv[1]); } } else if (argc > 3 && iRaw == 465) { if (GetCurrentNick() != NULL && GetSite() != NULL) { g_Bouncer->LogUser(GetUser(), "G/K-line reason for user %s [%s!%s]: %s", GetOwner()->GetUsername(), GetCurrentNick(), GetSite(), argv[3]); } else { g_Bouncer->LogUser(GetUser(), "G/K-line reason for user %s: %s", GetOwner()->GetUsername(), argv[3]); } } else if (argc > 5 && iRaw == 351) { free(m_ServerVersion); m_ServerVersion = strdup(argv[3]); free(m_ServerFeat); m_ServerFeat = strdup(argv[5]); } else if (argc > 3 && iRaw == 5) { for (int i = 3; i < argc - 1; i++) { char *Dup = strdup(argv[i]); if (AllocFailed(Dup)) { return false; } char *Eq = strchr(Dup, '='); if (strcasecmp(Dup, "NAMESX") == 0) { WriteLine("PROTOCTL NAMESX"); } char *Value; if (Eq) { *Eq = '\0'; Value = strdup(++Eq); } else { Value = strdup(""); } m_ISupport->Add(Dup, Value); free(Dup); } } else if (argc > 4 && iRaw == 324) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->ClearModes(); Channel->ParseModeChange(argv[0], argv[4], argc - 5, &argv[5]); Channel->SetModesValid(true); } } else if (argc > 3 && hashRaw == hashMode) { Channel = GetChannel(argv[2]); if (Channel != NULL) { Channel->ParseModeChange(argv[0], argv[3], argc - 4, &argv[4]); } else if (strcmp(m_CurrentNick, argv[2]) == 0) { bool Flip = true, WasNull; const char *Modes = argv[3]; size_t Length = strlen(Modes) + 1; if (m_Usermodes != NULL) { Length += strlen(m_Usermodes); } WasNull = (m_Usermodes != NULL) ? false : true; m_Usermodes = (char *)realloc(m_Usermodes, Length); if (AllocFailed(m_Usermodes)) { return false; } if (WasNull) { m_Usermodes[0] = '\0'; } while (*Modes != '\0') { if (*Modes == '+') { Flip = true; } else if (*Modes == '-') { Flip = false; } else { if (Flip) { size_t Position = strlen(m_Usermodes); m_Usermodes[Position] = *Modes; m_Usermodes[Position + 1] = '\0'; } else { char *CurrentModes = m_Usermodes; size_t a = 0; while (*CurrentModes != '\0') { *CurrentModes = m_Usermodes[a]; if (*CurrentModes != *Modes) { CurrentModes++; } a++; } } } Modes++; } } UpdateHostHelper(Reply); } else if (argc > 4 && iRaw == 329) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetCreationTime(atoi(argv[4])); } } else if (argc > 4 && iRaw == 332) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetTopic(argv[4]); } } else if (argc > 5 && iRaw == 333) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetTopicNick(argv[4]); Channel->SetTopicStamp(atoi(argv[5])); } } else if (argc > 3 && iRaw == 331) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetNoTopic(); } } else if (argc > 3 && hashRaw == hashTopic) { Channel = GetChannel(argv[2]); if (Channel != NULL) { Channel->SetTopic(argv[3]); Channel->SetTopicStamp(g_CurrentTime); Channel->SetTopicNick(argv[0]); } UpdateHostHelper(Reply); } else if (argc > 5 && iRaw == 353) { Channel = GetChannel(argv[4]); if (Channel != NULL) { const char *nicks; const char **nickv; nicks = ArgTokenize(argv[5]); if (AllocFailed(nicks)) { return false; } nickv = ArgToArray(nicks); if (AllocFailed(nickv)) { ArgFree(nicks); return false; } int nickc = ArgCount(nicks); for (int i = 0; i < nickc; i++) { char *Nick = strdup(nickv[i]); char *BaseNick = Nick; if (AllocFailed(Nick)) { ArgFree(nicks); return false; } StrTrim(Nick, ' '); while (IsNickPrefix(*Nick)) { Nick++; } char *Modes = NULL; if (BaseNick != Nick) { Modes = (char *)malloc(Nick - BaseNick + 1); if (!AllocFailed(Modes)) { strmcpy(Modes, BaseNick, Nick - BaseNick + 1); } } Channel->AddUser(Nick, Modes); free(BaseNick); free(Modes); } ArgFreeArray(nickv); ArgFree(nicks); } } else if (argc > 3 && iRaw == 366) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetHasNames(); } } else if (argc > 9 && iRaw == 352) { const char *Ident = argv[4]; const char *Host = argv[5]; const char *Server = argv[6]; const char *Nick = argv[7]; const char *Realname = argv[9]; char *Mask; int rc = asprintf(&Mask, "%s!%s@%s", Nick, Ident, Host); if (!RcFailed(rc)) { UpdateHostHelper(Mask); UpdateWhoHelper(Nick, Realname, Server); free(Mask); } } else if (argc > 6 && iRaw == 367) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->GetBanlist()->SetBan(argv[4], argv[5], atoi(argv[6])); } } else if (argc > 3 && iRaw == 368) { Channel = GetChannel(argv[3]); if (Channel != NULL) { Channel->SetHasBans(); } } else if (argc > 3 && iRaw == 396) { free(m_Site); m_Site = strdup(argv[3]); if (AllocFailed(m_Site)) {} } else if (argc > 3 && hashRaw == hashPong && m_Server != NULL && strcasecmp(argv[2], m_Server) == 0 && m_EatPong) { m_EatPong = false; return false; } else if (argc > 3 && iRaw == 421) { m_FloodControl->Unplug(); return false; } if (GetOwner() != NULL) { return ModuleEvent(argc, argv); } else { return true; } }
void UPAConsumer::Run() { RsslError error; struct timeval time_interval; RsslRet retval = 0; fd_set useRead; fd_set useExcept; fd_set useWrt; // get hold of the statistics logger statsLogger_ = StatisticsLogger::GetStatisticsLogger(); // todo might want to make these configurable #ifdef _WIN32 int rcvBfrSize = 65535; int sendBfrSize = 65535; #endif int selRet; FD_ZERO(&readfds_); FD_ZERO(&exceptfds_); FD_ZERO(&wrtfds_); // The outer thread loop attempts to make / remake a connection to the rssl server // // Inner loop dispatches requests from the mama queue and reads the socket for incoming responses while (runThread_) { // attempt to make connection while(shouldRecoverConnection_ && runThread_) { login_->UPAChannel(0); sourceDirectory_->UPAChannel(0); upaDictionary_->UPAChannel(0); // connect to server t42log_info("Attempting to connect to server %s:%s...\n", connectionConfig_.Host().c_str(), connectionConfig_.Port().c_str()); if ((rsslConsumerChannel_ = ConnectToRsslServer(connectionConfig_.Host(), connectionConfig_.Port(), interfaceName_, connType_, &error)) == NULL) { t42log_error("Unable to connect to RSSL server: <%s>\n",error.text); } else { if (rsslConsumerChannel_) { // connected - set up socket fds RsslSocket s = rsslConsumerChannel_->socketId; FD_SET(rsslConsumerChannel_->socketId, &readfds_); FD_SET(rsslConsumerChannel_->socketId, &wrtfds_); FD_SET(rsslConsumerChannel_->socketId, &exceptfds_); } } if (rsslConsumerChannel_ != NULL && rsslConsumerChannel_->state == RSSL_CH_STATE_ACTIVE) shouldRecoverConnection_ = RSSL_FALSE; //Wait for channel to become active. while (rsslConsumerChannel_ != NULL && rsslConsumerChannel_->state != RSSL_CH_STATE_ACTIVE && runThread_) { useRead = readfds_; useWrt = wrtfds_; useExcept = exceptfds_; /* Set a timeout value if the provider accepts the connection, but does not initialize it */ time_interval.tv_sec = 60; time_interval.tv_usec = 0; selRet = select(FD_SETSIZE, &useRead, &useWrt, &useExcept, &time_interval); // select has timed out, close the channel and attempt to reconnect if (selRet == 0) { t42log_warn("Channel initialization has timed out, attempting to reconnect...\n"); if (rsslConsumerChannel_) { FD_CLR(rsslConsumerChannel_->socketId, &readfds_); FD_CLR(rsslConsumerChannel_->socketId, &exceptfds_); if (FD_ISSET(rsslConsumerChannel_->socketId, &wrtfds_)) FD_CLR(rsslConsumerChannel_->socketId, &wrtfds_); } RecoverConnection(); } else // Received a response from the provider. if (rsslConsumerChannel_ && selRet > 0 && (FD_ISSET(rsslConsumerChannel_->socketId, &useRead) || FD_ISSET(rsslConsumerChannel_->socketId, &useWrt) || FD_ISSET(rsslConsumerChannel_->socketId, &useExcept))) { if (rsslConsumerChannel_->state == RSSL_CH_STATE_INITIALIZING) { RsslInProgInfo inProg = RSSL_INIT_IN_PROG_INFO; FD_CLR(rsslConsumerChannel_->socketId,&wrtfds_); if ((retval = rsslInitChannel(rsslConsumerChannel_, &inProg, &error)) < RSSL_RET_SUCCESS) { // channel init failed, try again t42log_warn("channelInactive fd=%d <%s>\n", rsslConsumerChannel_->socketId,error.text); RecoverConnection(); break; } else { switch ((int)retval) { case RSSL_RET_CHAN_INIT_IN_PROGRESS: if (inProg.flags & RSSL_IP_FD_CHANGE) { t42log_info("Channel In Progress - New FD: %d Old FD: %d\n",rsslConsumerChannel_->socketId, inProg.oldSocket ); FD_CLR(inProg.oldSocket,&readfds_); FD_CLR(inProg.oldSocket,&exceptfds_); FD_SET(rsslConsumerChannel_->socketId,&readfds_); FD_SET(rsslConsumerChannel_->socketId,&exceptfds_); FD_SET(rsslConsumerChannel_->socketId,&wrtfds_); } else { t42log_info("Channel %d In Progress...\n", rsslConsumerChannel_->socketId); } break; case RSSL_RET_SUCCESS: { // connected t42log_info("Channel %d Is Active\n" ,rsslConsumerChannel_->socketId); shouldRecoverConnection_ = RSSL_FALSE; RsslChannelInfo chanInfo; // log channel info if ((retval = rsslGetChannelInfo(rsslConsumerChannel_, &chanInfo, &error)) >= RSSL_RET_SUCCESS) { RsslUInt32 i; for (i = 0; i < chanInfo.componentInfoCount; i++) { t42log_info("Connected to %s device.\n", chanInfo.componentInfo[i]->componentVersion.data); } } login_->UPAChannel(rsslConsumerChannel_); sourceDirectory_->UPAChannel(rsslConsumerChannel_); upaDictionary_->UPAChannel(rsslConsumerChannel_); mama_log (MAMA_LOG_LEVEL_FINEST, "Provider returned \"Connection Successful\""); NotifyListeners(true, "Provider returned \"Connection Successful\""); } break; default: { // Connection has failed char buff[256]={0}; memset(buff,0,sizeof(buff)); sprintf(buff, "Bad return value on connection fd=%d <%s>\n", rsslConsumerChannel_->socketId,error.text); t42log_error("%s\n", buff); NotifyListeners(false, buff); runThread_ = false; } break; } } } } else if (selRet < 0) { t42log_error("Select error.\n"); runThread_ = false; break; } } // wait a while before retry if (shouldRecoverConnection_) { LogReconnection(); WaitReconnectionDelay(); } } // WINDOWS: change size of send/receive buffer since it's small by default #ifdef _WIN32 if (rsslConsumerChannel_ && rsslIoctl(rsslConsumerChannel_, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &error) != RSSL_RET_SUCCESS) { t42log_error("rsslIoctl(): failed <%s>\n", error.text); } if (rsslConsumerChannel_ && rsslIoctl(rsslConsumerChannel_, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &error) != RSSL_RET_SUCCESS) { t42log_error("rsslIoctl(): failed <%s>\n", error.text); } #endif /* Initialize ping handler */ if (rsslConsumerChannel_) InitPingHandler(rsslConsumerChannel_); int64_t queueCount = 0; /* this is the message processing loop */ while (runThread_) { // first dispatch some events off the event queue if (!PumpQueueEvents()) { break; } if ((rsslConsumerChannel_ != NULL) && (rsslConsumerChannel_->socketId != -1)) { // if we have a connection useRead = readfds_; useExcept = exceptfds_; useWrt = wrtfds_; time_interval.tv_sec = 0; time_interval.tv_usec = 100000; // look at the socket state selRet = select(FD_SETSIZE, &useRead, &useWrt, &useExcept, &time_interval); } else { // no connection, just sleep for 1s #ifdef _WIN32 Sleep(1000); #else sleep(1); #endif continue; } if (!runThread_) { // thread is stopped break; } if (selRet < 0) // no messages received, continue { #ifdef _WIN32 if (WSAGetLastError() == WSAEINTR) continue; #else if (errno == EINTR) { continue; } #endif } else if (selRet > 0) // messages received { if ((rsslConsumerChannel_ != NULL) && (rsslConsumerChannel_->socketId != -1)) { if ((FD_ISSET(rsslConsumerChannel_->socketId, &useRead)) || (FD_ISSET(rsslConsumerChannel_->socketId, &useExcept))) { // This will empty the read buffer and dispatch incoming events if (ReadFromChannel(rsslConsumerChannel_) != RSSL_RET_SUCCESS) { // the read failed so attempt to recover if required if(RSSL_TRUE == shouldRecoverConnection_) { RecoverConnection(); } else { // otherwise just run out of the thread runThread_ = false; } } } // If there's anything to be written flush the write socket if (rsslConsumerChannel_ != NULL && FD_ISSET(rsslConsumerChannel_->socketId, &useWrt) && rsslConsumerChannel_->state == RSSL_CH_STATE_ACTIVE) { if ((retval = rsslFlush(rsslConsumerChannel_, &error)) < RSSL_RET_SUCCESS) { t42log_error("rsslFlush() failed with return code %d - <%s>\n", retval, error.text); } else if (retval == RSSL_RET_SUCCESS) { // and clear the fd FD_CLR(rsslConsumerChannel_->socketId, &wrtfds_); } } } } // break out of message processing loop if should recover connection if (shouldRecoverConnection_ == RSSL_TRUE) { LogReconnection(); WaitReconnectionDelay(); break; } // check if its time to process pings if (rsslConsumerChannel_) { ProcessPings(rsslConsumerChannel_); } } } // thread has stopped RemoveChannel(rsslConsumerChannel_); t42log_debug("Exit UPAConsumer thread\n"); }