CPipeState_Listening::CPipeState_Listening(CSyncPipe* pPipe,SOCKET Socket) :CPipeState_Busy(pPipe,Socket) { CPipeState* pState=GetPipe()->m_pState; GetPipe()->m_pState=NULL; delete pState; GetPipe()->m_pState=this; #ifdef _WIN32 SQR_TRY { m_Event.Create(m_Socket); } SQR_CATCH(exp) { LogExp(exp); closesocket(m_Socket); throw; } SQR_TRY_END; #endif Register(); if( listen(m_Socket,SOMAXCONN) ) { ostringstream strm; strm<<"listen failed with error code:"<<SocketGetLastError()<<"."; GenErr(strm.str()); } }
/* * Read a pkt from a Named Pipe * * @param hPipe the Named Pipe to read from * @param pktBuffer the destination buffer, the pkt will be in this buffer * * @return Type of pkt (ERR, KD_PKT, FASTBREAK_PKT) */ KdPacketType ReadKDPipe(HANDLE hPipe, KD_PACKET_T *pktBuffer) { DWORD numBytesRead = 0; BOOL result; UINT8 firstCMD = 0x00; do{ bool dataRead = GetPipeTry(hPipe, &firstCMD, sizeof(uint8_t), true); if (dataRead == false){ return KdNoPacket; } } while (firstCMD != TYPE1_SHORTLEADER && firstCMD != TYPE2_SHORTLEADER && firstCMD != BREAKIN_SHORTLEADER); if (firstCMD == BREAKIN_SHORTLEADER){ //This is a BreakIn short packet return KdBreakinPacket; } //Read the end of the Leader uint32_t LeaderEnd = 0; GetPipe(hPipe, (uint8_t*)&LeaderEnd, 3); uint32_t u32Leader = (firstCMD << 24) | LeaderEnd; if (u32Leader == TYPE1_LONGLEADER || u32Leader == TYPE2_LONGLEADER){ pktBuffer->Leader = u32Leader; //Read header GetPipe(hPipe, (uint8_t*)&(pktBuffer->Type), 12); //TODO: function ! uint32_t bytesToRead = pktBuffer->Length; uint32_t bytesAlreadyRead = 0; while (bytesToRead > 0){ result = ReadFile(hPipe, pktBuffer->data + bytesAlreadyRead, bytesToRead, &numBytesRead, NULL); bytesToRead = bytesToRead - numBytesRead; bytesAlreadyRead = bytesAlreadyRead + numBytesRead; } //END_OF_DATA if (pktBuffer->Length > 0){ //Trick to avoid segfault on Windows 7 ??? uint8_t tmpBuffer[1024]; DWORD test = 0; if (ReadFile(hPipe, tmpBuffer, 1, &test, NULL) == false){ printf("Error while reading file !\n"); } } if (DEBUG_PKT){ ParseKDPkt(pktBuffer); } return KdKdPacket; }else{ UINT16 type = Get16Pipe(hPipe); printf("Unknown Leader %08x\n", u32Leader); printf("type: %04x\n", type); } return KdErrorPacket; }
void CPipeState_Listening::ProcessEvent(bool bRead,bool /*bWrite*/,bool /*bError*/) { if( !bRead ) return; for(;;) { SOCKET Socket = accept( m_Socket , NULL , NULL ); if( INVALID_SOCKET == Socket ) { int nErrorCode=SocketGetLastError(); switch(nErrorCode) { #ifndef _WIN32 case ECONNABORTED: case EMFILE: #endif case EWOULDBLOCK: return; } ostringstream strm; strm<<"accept failed with error code:"<<nErrorCode<<"."; GenErr(strm.str()); } u_long uParam=1; if( SOCKET_ERROR == ioctlsocket( Socket , FIONBIO , &uParam ) ) { closesocket( Socket ); ostringstream strm; strm<<"ioctlsocket failed with error code "<< SocketGetLastError() <<"."; GenErr(strm.str()); } bool bDisconnected; CSyncPipe* pNewPipe = new CSyncPipe( NULL , GetPipe()->m_OutBuffer.OutBufferGetSize() , GetPipe()->m_InBuffer.InBufferGetSize(),Socket , GetPipe()->m_uCreationFlag,bDisconnected ); if( bDisconnected ) { delete pNewPipe; } else { GetPipe()->AddEventAccepted( pNewPipe ); } } }
void CPipeState_Connecting::ShutDown(bool IfCallback) { CSyncPipe* pPipe=GetPipe(); new CPipeState_Disconnected(pPipe); if (IfCallback) pPipe->AddEventConnectFailed(ePCFR_CANCELED); }
void CPipeState_Listening::Unregister() { if( !GetPipe()->m_pReactor ) return; #ifdef _WIN32 EventDel(); #else EpollCtl(EPOLL_CTL_DEL,0); #endif }
void CPipeState_Listening::Register() { if(!GetPipe()->m_pReactor) return; #ifdef _WIN32 EventAdd(FD_ACCEPT); #else EpollCtl(EPOLL_CTL_ADD,EPOLLIN); #endif }
void CPipeState_Connecting::Register() { if(!GetPipe()->m_pReactor) return; #ifndef _WIN32 EpollCtl(EPOLL_CTL_ADD,EPOLLOUT|EPOLLERR); #else EventAdd(FD_CONNECT|FD_CLOSE); #endif }
void CleanUpEverything() { auto glbl = globalStruct::GetGlobals(); if (!glbl) return; auto svr = glbl->GetServer(); if (svr) { svr->Stop(); } auto strm = glbl->GetStreamer(); if (strm) { strm->stopStream(); } auto pipe = glbl->GetPipe(); if (pipe) { pipe->Cleanup(); } glbl->work_guard.reset(); auto svc = glbl->GetService(); glbl->ResetAllPointers(); svr.reset(); strm.reset(); pipe.reset(); if (svc && !svc->stopped()) { svc->stop(); } std::for_each(glbl->globalThreads.begin(), glbl->globalThreads.end(), [](decltype(*glbl->globalThreads.begin())& thr) { thr.join(); }); svc.reset(); auto trkr = glbl->GetTracker(); if (trkr) { trkr->WaitUntilThreadVecEmpty(); trkr.reset(); std::shared_ptr<FunctionUsageTracker> resetTracker; std::atomic_store(&glbl->fcnTracker, resetTracker); std::this_thread::sleep_for(std::chrono::seconds(10)); // Wait some time for threads to exit } glbl.reset(); globalStruct::nullifyGlobals(); }
bool CPipeState_Connecting::SwitchToConnected() { CSyncPipe* pPipe=GetPipe(); Unregister(); SOCKET Socket=m_Socket; m_Socket=0;//赋值后再CPipeState_Busy析构的时候,就不会close这个socket bool bDisconnected; new CPipeState_Connected( pPipe,Socket,bDisconnected); pPipe->AddEventConnected(); if( bDisconnected ) { new CPipeState_Disconnected( pPipe ); pPipe->AddEventDisconnected( ePDR_ERROR,false ); return false; } return true; }
void CConnClient::OnConnectFailed(EPipeConnFailedReason eReason) { CConnMgrClient* pMgr=CConnMgrClient::Inst(); if(pMgr->GetHandler()) { EConnConnectFailedReason eConnReason; switch( eReason ) { case ePCFR_UNREACHABLE: eConnReason=eCCFR_UNREACHABLE; break; case ePCFR_REFUSED: eConnReason=eCCFR_REFUSED; break; case ePCFR_INVALIDADDR: eConnReason=eCCFR_INVALIDADDR; break; case ePCFR_OSERROR: eConnReason=eCCFR_OSERROR; break; default: GenErr("ConnClient收到不合理的回调"); } pMgr->GetHandler()->OnConnectFailed(this,eConnReason); } if( IsShuttingDown() ) { return; } pMgr->m_listAllConn.erase(m_itListConn); GetPipe()->Release(); delete this; }
void CPipeState_Listening::ShutDown(bool IfCallback) { new CPipeState_Disconnected(GetPipe()); }
// ------------------------------------------------------------------------- // // *�DoConnect( void ) // ------------------------------------------------------------------------- // void TDCLDockLink::DoConnect( void ) { // TDCLLink fait la premi�re partie du boulot. TDCLLink::DoConnect(); // Ouverture de la session. TSmartPtr<TDCLDockCommand> theNewtMessage; KUInt32 theChallenge[2]; // Envoi de kDDesktopInfo { // Je dis que je suis NCU. // Structure NewtonScript pour ce gros mensonge. TDCLNSFrame theDesktopAppFrame; // Tableau NewtonScript avec les informations. TDCLNSArray theDesktopAppsArray; // Le nom. theDesktopAppFrame.Set( "name", TDCLNSRef::MakeString( "Newton Connection Utilities" ) ); // L'ID (2, c'est NCU) theDesktopAppFrame.Set( "id", TDCLNSRef::MakeInt( 2 ) ); // La version. theDesktopAppFrame.Set( "version", TDCLNSRef::MakeInt( 1 ) ); // Si on permet l'auto-dock. // theDesktopAppFrame.Set( "doesAuto", TDCLNSRef::kTRUEREF ); // Cette structure va dans le tableau. theDesktopAppsArray.Add( TDCLNSRef( theDesktopAppFrame ) ); // Le d�fi est constitu� de deux nombres al�atoires // Il faut donc initialiser le g�n�rateur al�atoire. time_t theTime; (void) ::time( &theTime ); ::srand( (unsigned int) theTime ); // On cr�e le d�fi. TDCLDockCmdPassword::CreateChallenge( theChallenge ); // Et on envoie l'information. // Cr�ation de la commande. TDCLDockCmdDesktopInfo theDesktopInfoMessage( theDesktopAppsArray, theChallenge[0], theChallenge[1], true, // selective sync TDCLDockCommand::kSettingUp_SType, GetApplication()->GetFilesIntf() ->GetKind() ); // Envoi. theDesktopInfoMessage.SendCommand( GetPipe() ); } KUInt32 theNewtonChallenge[2]; // R�ception de kDNewtonInfo { theNewtMessage = TDCLDockCommand::ReceiveCommand( GetPipe() ); // V�rification que c'est bien une commande kDNewtonName. if (theNewtMessage->GetCommand() != TDCLDockCommand::kDNewtonInfo) { // Duh! // Je devrais regarder si ce n'est pas un message d'erreur venant // du Newton (on ne sait jamais) throw DCLUnexpDockCmd; } // C'est bien une structure TDCLDockCmdNewtonInfo TDCLDockCmdNewtonInfo* theNewtonInfo = (TDCLDockCmdNewtonInfo*) theNewtMessage.Get(); // Je sauvegarde la clef pour le DES. theNewtonChallenge[0] = theNewtonInfo->GetChallenge()[0]; theNewtonChallenge[1] = theNewtonInfo->GetChallenge()[1]; // Lib�ration du message. theNewtMessage.Delete(); } // Envoi de kDWhichIcons. { // Cr�ation. TDCLDockCmdSingleLong theWhichIconMessage( TDCLDockCommand::kDWhichIcons, mIcons ); // Envoi. theWhichIconMessage.SendCommand( GetPipe() ); } // R�ception de kDResult. { theNewtMessage = TDCLDockCommand::ReceiveCommand( GetPipe() ); // V�rification que c'est bien une commande kDResult. if (theNewtMessage->GetCommand() != TDCLDockCommand::kDResult) { // Duh! throw DCLUnexpDockCmd; } // C'est bien une structure TDCLDockCmdSingleLong TDCLDockCmdSingleLong* theResult = (TDCLDockCmdSingleLong*) theNewtMessage.Get(); // On l�ve une exception si le code n'est pas 0. KSInt32 theResultInt = (KSInt32) theResult->GetLong(); if (theResultInt) { throw DCLNewton( theResultInt ); } // Lib�ration. theNewtMessage.Delete(); } // Envoi de kDSetTimeout. { // R�cup�ration de la temporisation de l'interface de // communication. long theTimeout = GetPipe()->GetTimeout(); if (theTimeout < 0) { // Valeur par d�faut. theTimeout = kDefaultTimeout; } // Cr�ation. TDCLDockCmdSingleLong theSetTimeoutMessage( TDCLDockCommand::kDSetTimeout, (KUInt32) theTimeout ); // Envoi. theSetTimeoutMessage.SendCommand( GetPipe() ); } // R�cup�ration de la commande kDPassword. // Le Newton a droit � 3 essais. { int indexAttempts; for (indexAttempts = 0; indexAttempts < 3; indexAttempts++) { theNewtMessage = TDCLDockCommand::ReceiveCommand( GetPipe() ); // V�rification que c'est bien une commande kDPassword. if (theNewtMessage->GetCommand() != TDCLDockCommand::kDPassword) { throw DCLUnexpDockCmd; } // C'est bien une structure TDCLDockCmdPassword. TDCLDockCmdPassword* thePassword = (TDCLDockCmdPassword*) theNewtMessage.Get(); // Je v�rifie le mot de passe. Boolean correct = thePassword->VerifyPassword( theChallenge, GetPassword() ); theNewtMessage.Delete(); // Lib�ration. if (correct) { break; } // On dit au Newton qu'il a encore un essai ou pas. if (indexAttempts < 2) { // Envoi de kRetryPassword_Err TDCLDockCmdSingleLong theRetryPasswordCmd( TDCLDockCommand::kDResult, TDCLDockCommand::kRetryPassword_Err ); theRetryPasswordCmd.SendCommand( GetPipe() ); } else { // Envoi de kBadPassword_Err TDCLDockCmdSingleLong theRetryPasswordCmd( TDCLDockCommand::kDResult, TDCLDockCommand::kBadPassword_Err ); theRetryPasswordCmd.SendCommand( GetPipe() ); #warning fix this? throw DCLBadDockCmd; } } } // Envoi de kDPassword. { TDCLDockCmdPassword thePasswordCmd( theNewtonChallenge, GetPassword() ); thePasswordCmd.SendCommand( GetPipe() ); } }
void CPipeState_Connecting::ProcessEvent(bool bRead,bool bWrite,bool bError) { EPipeConnFailedReason eReason = ePCFR_UNREACHABLE; if(bError) { int nErrorCode; socklen_t nLength=sizeof(nErrorCode); int nResult; nResult=getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,reinterpret_cast<char*>(&nErrorCode),&nLength); if(nResult) { stringstream strm; strm<<"getsockopt failed with error code "<<nResult<<"."; GenErr(strm.str()); } switch(nErrorCode) { case ECONNRESET: case ECONNREFUSED: eReason=ePCFR_REFUSED; break; case EADDRNOTAVAIL: eReason=ePCFR_INVALIDADDR; break; case ECONNABORTED: eReason=ePCFR_OSERROR; break; case ETIMEDOUT: case ENOTCONN: case EHOSTUNREACH: case ENETUNREACH: eReason=ePCFR_UNREACHABLE; break; default: { ostringstream strm; strm<<"connect failed with error code:"<<nErrorCode; GenErr(strm.str()); } break; } CSyncPipe* pPipe=GetPipe(); new CPipeState_Disconnected(pPipe); pPipe->AddEventConnectFailed(eReason); return; } if(bWrite) { #ifndef _WIN32 int nErrorCode; socklen_t nLength=sizeof(nErrorCode); int nResult; nResult=getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,reinterpret_cast<char*>(&nErrorCode),&nLength); if(nResult) { stringstream strm; strm<<"getsockopt failed with error code "<<nResult<<"."; GenErr(strm.str()); } switch(nErrorCode) { case 0: { #endif SwitchToConnected(); return; #ifndef _WIN32 } case ECONNREFUSED: eReason=ePCFR_REFUSED; break; case ETIMEDOUT: eReason=ePCFR_TIMEDOUT; break; case EADDRNOTAVAIL: eReason=ePCFR_INVALIDADDR; break; case EHOSTUNREACH: case ENETUNREACH: eReason=ePCFR_UNREACHABLE; break; default: { ostringstream strm; strm<<"connect failed with error code:"<<nErrorCode; GenErr(strm.str()); } break; } CSyncPipe* pPipe=GetPipe(); new CPipeState_Disconnected(pPipe); pPipe->AddEventConnectFailed(eReason); return; #endif } }
CPipeState_Connecting::CPipeState_Connecting(CSyncPipe* pPipe,const CAddress& Address,uint32& uResult) :CPipeState_Busy(pPipe) { pPipe->m_OutBuffer.OutBufferClear(); pPipe->m_InBuffer.InBufferClear(); CPipeState* pState=GetPipe()->m_pState; GetPipe()->m_pState=NULL; delete pState; GetPipe()->m_pState=this; const SOCKET& Socket=m_Socket; #ifdef _WIN32 SQR_TRY { m_Event.Create(Socket); } SQR_CATCH (exp) { LogExp(exp); closesocket(m_Socket); throw; } SQR_TRY_END; #endif Register(); sockaddr_in saiAddress; ::memset(&saiAddress,0,sizeof(saiAddress)); saiAddress.sin_addr.s_addr = inet_addr(Address.GetAddress()); saiAddress.sin_port = htons(static_cast<u_short>(Address.GetPort())); saiAddress.sin_family = AF_INET; //连接 int nResult; nResult=connect(Socket,reinterpret_cast<sockaddr*>(&saiAddress),sizeof(sockaddr)); if(SOCKET_ERROR!=nResult) { uResult=0; } else { int nError=SocketGetLastError(); switch(nError) { #if defined(__linux__) case EINPROGRESS: #elif defined(_WIN32) case EWOULDBLOCK: #endif uResult=1; break; #ifdef _WIN32 case ECONNABORTED://Windows下还真会出现这种情况 case ENOBUFS: uResult=2; GetPipe()->AddEventConnectFailed(ePCFR_OSERROR); return; #endif case ECONNRESET: case ECONNREFUSED: uResult=2; GetPipe()->AddEventConnectFailed(ePCFR_REFUSED); return; case ETIMEDOUT: case ENETRESET: case EHOSTUNREACH: case ENETUNREACH: uResult=2; GetPipe()->AddEventConnectFailed(ePCFR_UNREACHABLE); return; default: closesocket(m_Socket); stringstream strm; strm<<"connect failed with error code "<<nError<<"."; GenErr(strm.str()); } } m_RemoteAddress=Address; }
DisplayError ResourceDefault::Prepare(Handle display_ctx, HWLayers *hw_layers) { DisplayResourceContext *display_resource_ctx = reinterpret_cast<DisplayResourceContext *>(display_ctx); DisplayError error = kErrorNone; const struct HWLayersInfo &layer_info = hw_layers->info; HWBlockType hw_block_id = display_resource_ctx->hw_block_id; DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id); if (layer_info.hw_layers.size() > 1) { DLOGV_IF(kTagResources, "More than one FB layers"); return kErrorResources; } const Layer &layer = layer_info.hw_layers.at(0); if (layer.composition != kCompositionGPUTarget) { DLOGV_IF(kTagResources, "Not an FB layer"); return kErrorParameters; } error = Config(display_resource_ctx, hw_layers); if (error != kErrorNone) { DLOGV_IF(kTagResources, "Resource config failed"); return error; } for (uint32_t i = 0; i < num_pipe_; i++) { if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) { src_pipes_[i].ResetState(); } } uint32_t left_index = num_pipe_; uint32_t right_index = num_pipe_; bool need_scale = false; struct HWLayerConfig &layer_config = hw_layers->config[0]; HWPipeInfo *left_pipe = &layer_config.left_pipe; HWPipeInfo *right_pipe = &layer_config.right_pipe; // left pipe is needed if (left_pipe->valid) { need_scale = IsScalingNeeded(left_pipe); left_index = GetPipe(hw_block_id, need_scale); if (left_index >= num_pipe_) { DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id, need_scale); ResourceStateLog(); goto CleanupOnError; } } error = SetDecimationFactor(left_pipe); if (error != kErrorNone) { goto CleanupOnError; } if (!right_pipe->valid) { // assign single pipe if (left_index < num_pipe_) { left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id; } DLOGV_IF(kTagResources, "1 pipe acquired for FB layer, left_pipe = %x", left_pipe->pipe_id); return kErrorNone; } need_scale = IsScalingNeeded(right_pipe); right_index = GetPipe(hw_block_id, need_scale); if (right_index >= num_pipe_) { DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id, need_scale); ResourceStateLog(); goto CleanupOnError; } if (src_pipes_[right_index].priority < src_pipes_[left_index].priority) { // Swap pipe based on priority std::swap(left_index, right_index); } // assign dual pipes left_pipe->pipe_id = src_pipes_[left_index].mdss_pipe_id; right_pipe->pipe_id = src_pipes_[right_index].mdss_pipe_id; error = SetDecimationFactor(right_pipe); if (error != kErrorNone) { goto CleanupOnError; } DLOGV_IF(kTagResources, "2 pipes acquired for FB layer, left_pipe = %x, right_pipe = %x", left_pipe->pipe_id, right_pipe->pipe_id); return kErrorNone; CleanupOnError: DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id); return kErrorResources; }
bool CConnClient::IsConnected()const { return GetPipe()->IsConnected() && m_bGlobalTimeSynced; }