ZQ_Error SslTcpClient::OnTrySendMsg() { ZQ_Error err = OS_NoErr; OSMutexLocker locker(&fMutexList); ListElement *elem = fMsgList.first; if(NULL != elem) { err = SendData((char *)elem->content, elem->size); if(err == OS_NoErr) { RefreshTimeout(); ListRemoveHead(&fMsgList); if(fMsgList.first != NULL) NotifySendMsg(); } else//add to connect list { m_clientPool->fQueue.EnQueue(&fTaskQueueElem); m_clientPool->Signal(Task::kConnectEvent); err = OS_NotEnoughSpace; qtss_printf("Try to send msg.\n"); } } return err; }
int SSLSocket_getPendingRead() { int sock = -1; if (pending_reads.count > 0) { sock = *(int*)(pending_reads.first->content); ListRemoveHead(&pending_reads); } return sock; }
/** * Add a message to the trace buffer * @param msg the message to add */ static void addToBuffer(List* buffer, char* msg) { if (buffer) { int size = strlen(msg) + 1; char *newmsg = malloc(size); int max_entries = (buffer == log_buffer) ? trace_settings.max_log_entries : trace_settings.max_trace_entries; strcpy(newmsg, msg); if (buffer->count < max_entries) ListAppend(buffer, newmsg, size); else ListRemoveHeadAddTail(buffer, newmsg, size); while (buffer->count > max_entries) ListRemoveHead(buffer); } }
/* OS_Error SslSvrSession::GenHttpRespMsg(StrPtrLen* cmdParams, const char* content, StrPtrLen *contentType, HTTPStatusCode status) { HTTPResponse httpResponse; UInt32 contentLen = content==NULL?0:strlen(content); httpResponse.CreateResponseHeader(http11Version, status); httpResponse.AppendDateField(); if(cmdParams && cmdParams->Len > 0) { httpResponse.AppendResponseHeader(httpPragmaHeader, cmdParams); } if(contentLen > 0) { httpResponse.AppendResponseHeader(httpContentTypeHeader, contentType==NULL?&HTTPBase::sContentTypeText:contentType); httpResponse.AppendContentLengthHeader(contentLen); } StrPtrLen* responseHeader = httpResponse.GetCompleteResponseHeader(); PutResponse(responseHeader->Ptr, responseHeader->Len); if(contentLen > 0) { PutResponse(content, contentLen); } return OS_NoErr; } */ SInt64 SslSvrSession::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) return -1; ZQ_Error err = ZQ_NoErr; while (this->IsLiveSession()) { // HTTP Session state machine. There are several well defined points in an HTTP request // where this session may have to return from its run function and wait for a new event. // Because of this, we need to track our current state and return to it. if(events&Task::kReadEvent) { switch(fState) { case kReadingRequest: { if ((err = fInputStream.ReadRequest(m_pssl)) == ZQ_NoErr) { // If the RequestStream returns QTSS_NoErr, it means // that we've read all outstanding data off the socket, // and still don't have a full request. Wait for more data. //+rt use the socket that reads the data, may be different now. fInputSocketP->RequestEvent(EV_RE); events -= Task::kReadEvent; break; } if ((err != ZQ_RequestArrived) && (err != E2BIG)) { // Any other error implies that the client has gone away. At this point, // we can't have 2 sockets, so we don't need to do the "half closed" check // we do below Assert(err > 0); // Assert(!this->IsLiveSession()); events -= Task::kReadEvent; break; } if (err == ZQ_RequestArrived) fState = kProcessingRequest; // If we get an E2BIG, it means our buffer was overfilled. // In that case, we can just jump into the following state, and // the code their does a check for this error and returns an error. if (err == E2BIG) fState = kCleaningUp; } case kProcessingRequest: { char* pBuffer = fInputStream.GetRequestBuffer(); UInt32 nLen = fInputStream.GetRequsetLength(); ZQ_Error err = ZQ_NoErr; while(err == ZQ_NoErr && nLen > 0) { err = ProcessRecvMsg(pBuffer, nLen); } if(ZQ_NoErr == err) { fState = kReadingRequest; return 0; // Update timer. //fTimeoutTask.RefreshTimeout(); } else { fState = kCleaningUp; } } break; case kCleaningUp: { // If we've gotten here, we've flushed all the data. Cleanup, // and wait for our next request! this->CleanupRequest(); fState = kReadingRequest; } break; }; } else if(events&Task::kWriteEvent) { OSMutexLocker locker(&fMutexList); ListElement *elem = NULL; int theLengthSent = 0; if((elem = fMsgList.first) != NULL) { // err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&fMsgList); if(NULL != fMsgList.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kZmqEvent) { events -= Task::kZmqEvent; } else { return 0; } } // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. return 0; }
SInt64 MqttServer::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) return -1; ZQ_Error err = ZQ_NoErr; while (this->IsLiveSession()) { // HTTP Session state machine. There are several well defined points in an HTTP request // where this session may have to return from its run function and wait for a new event. // Because of this, we need to track our current state and return to it. if(events&Task::kReadEvent) { if ((err = fInputStream.ReadRequest()) == ZQ_NoErr) { //+rt use the socket that reads the data, may be different now. fInputSocketP->RequestEvent(EV_RE); events -= Task::kReadEvent; continue; } if ((err != ZQ_RequestArrived) && (err != E2BIG)) { // Any other error implies that the client has gone away. At this point, // we can't have 2 sockets, so we don't need to do the "half closed" check // we do below Assert(err > 0); Assert(!this->IsLiveSession()); events -= Task::kReadEvent; break; } if (err == ZQ_RequestArrived) { char* pBuffer = fInputStream.GetRequestBuffer(); int nLen = fInputStream.GetRequsetLength(); ZQ_Error err = ZQ_NoErr; while(err == ZQ_NoErr && nLen > 0) { err = ProcessRecvMsg(pBuffer, nLen); } if(ZQ_NoErr == err) { err = fOutputStream.Flush(); if (err == EAGAIN) { UInt32 datalen = 0; char* pData = fOutputStream.GetBufferCopy(&datalen); if(pData) { OSMutexLocker locker(&fMutexList); ListAppend(&fMsgList, pData, datalen); } // If we get this error, we are currently flow-controlled and should // wait for the socket to become writeable again fSocket.RequestEvent(EV_RE | EV_WR); } } else { CleanupRequest(); } }; } else if(events&Task::kWriteEvent) { OSMutexLocker locker(&fMutexList); ListElement *elem = NULL; int theLengthSent = 0; if((elem = fMsgList.first) != NULL) { // err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&fMsgList); if(NULL != fMsgList.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kZmqEvent) { events -= Task::kZmqEvent; } else { return 0; } } // Make absolutely sure there are no resources being occupied by the session // at this point. this->CleanupRequest(); // Only delete if it is ok to delete! if (fObjectHolders == 0) return -1; // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. return 0; }
SInt64 RTTcp::Run() { EventFlags events = this->GetEvents(); this->ForceSameThread(); // Http session is short connection, need to kill session when occur TimeoutEvent. // So return -1. if(events&Task::kTimeoutEvent || events&Task::kKillEvent) { if (events&Task::kTimeoutEvent) { LI("%s timeout \n", __FUNCTION__); } else { LI("%s kill \n", __FUNCTION__); } std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this); if (it != m_mapConnectObserver.end()) { LI("Tcp::Run find Disconnection\n"); RTObserverConnection *conn = it->second; if (conn) { LI("Tcp::Run notify Disconnection\n"); conn->ConnectionDisconnected(); } } return -1; } while(this->IsLiveSession()) { if(events&Task::kReadEvent) { UInt32 readed = 0; char fRequestBuffer[kRequestBufferSizeInBytes]; while(1) { readed = 0; // We don't have any new data, get some from the socket... OS_Error sockErr = fSocket.Read(fRequestBuffer, kRequestBufferSizeInBytes - 1, &readed); if (sockErr == EAGAIN) break; if (sockErr != OS_NoErr) { Assert(!fSocket.IsConnected()); break; } if(readed > 0) { OnRecvData(fRequestBuffer, readed); } } fSocket.RequestEvent(EV_RE); events -= Task::kReadEvent; } else if(events&Task::kWriteEvent) { ListElement *elem = NULL; if((elem = m_listSend.first) != NULL) { UInt32 theLengthSent = 0; OS_Error err = fSocket.Send((char*)elem->content, elem->size, &theLengthSent); if (err == EAGAIN) { fSocket.RequestEvent(EV_RE | EV_WR); } else { ListRemoveHead(&m_listSend); if(NULL != m_listSend.first) this->Signal(kWriteEvent); } } events -= Task::kWriteEvent; } else if(events&Task::kLcsEvent) { OnLcsEvent(); events -= Task::kLcsEvent; } else if(events&Task::kPeerEvent) { OnPeerEvent(); events -= Task::kPeerEvent; } else if(events&Task::kIdleEvent) { OnTickEvent(); events -= Task::kIdleEvent; } else { return fTickTime; } } // If we are here because of a timeout, but we can't delete because someone // is holding onto a reference to this session, just reschedule the timeout. // // At this point, however, the session is DEAD. std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this); if (it != m_mapConnectObserver.end()) { LI("Tcp::Run SessionOffline find Disconnection\n"); RTObserverConnection *conn = it->second; if (conn) { LI("Tcp::Run SessionOffline notify Disconnection\n"); conn->ConnectionDisconnected(); } } return -1; }