void TRawServer :: handleEvent(TPollEvent * pevents, int n) { for( int i = 0; i < n; i++ ) { int err = SOCKERR_NONE; TSocket * skp = (TSocket *)(pevents[i].data.ptr); UINT32 SelectFlags = skp->getSelectFlags(); waitevents_t wevt = pevents[i].events; if( (wevt & (EPOLLIN|EPOLLERR)) && (SelectFlags & SF_ACCEPT) == SF_ACCEPT) { wevt = XPOLLACC; } if( (wevt & (EPOLLOUT|EPOLLERR)) && (SelectFlags & SF_CONNECT) == SF_CONNECT) { socklen_t errlen = sizeof(err); getsockopt(skp->getHandle(), SOL_SOCKET, SO_ERROR, &err, &errlen); wevt = XPOLLCNX; } if(wevt & EPOLLERR) { wevt = SelectFlags; } if( WAIT_EVENT_READ( wevt ) ) { cout << "WAIT EVENT READ" << endl; skp->handleRead(); skp->setMaskRead(false); skp->setMaskWrite(true); m_poller->modSocket(skp); } else if( WAIT_EVENT_WRITE( wevt ) ) { cout << "WAIT EVENT WRITE" << endl; skp->handleWrite(); // pevents[i].data.ptr = NULL; m_poller->delSocket(skp); // delete skp; if( m_sparesockets.size() >= MAX_SPARE_SOCKETS ) { delete skp; } else { skp->closeSocket(); skp->setMaskRead(false); skp->setMaskWrite(false); m_sparesockets.push_back(skp); } } else if( WAIT_EVENT_ACCEPT( wevt ) ) { cout << "WAIT EVENT ACCEPT" << endl; string ipaddr; UINT16 port; sockobj_t sock = dynamic_cast<ListenSocket*>(m_listensocket)->Accept(ipaddr, port); if(INVALID_SOCKET != sock ) { TSocket *skp = NULL; if( !m_sparesockets.empty() ) { skp = m_sparesockets.front(); m_sparesockets.pop_front(); } else { skp = new TcpSocket(); } skp->attach(sock); skp->setMaskRead(true); m_poller->addSocket(skp); LOG(1)("connection from %s:%d\n", ipaddr.c_str(), port); cout <<"connection from " << ipaddr << ":"<< port << endl; } } else if( WAIT_EVENT_CONNECT( wevt ) ) { cout << "WAIT EVENT CONNECT" << endl; } else if( WAIT_EVENT_EXCEPT( wevt ) ) { cout << "WAIT EVENT EXCEPT" << endl; } } }
void CKEventThread::ThreadProcMain(void) { if( Init() ) { while( !m_bWantStop ) { // Figure out how long we can remain in poll/WFMO, possibly forever waittimer_t nTimeout = INFTIM; if( m_nTimers ) { assert( m_ppTimers[1] ); nTimeout = m_ppTimers[1]->GetTimeout() - CKTimer::CurrentTime(); if( nTimeout < 0 || nTimeout > 0x7FFFFFFF ) nTimeout = 0; // Wrap - it's late } #ifdef _UNIX int rc = poll( m_pWaitObjs, m_nSocks, nTimeout ); if( rc < 0 ) { dbgout( "poll() failed: error = %i (%s)", errno, strerror(errno) ); break; } #endif #ifdef _WIN32 DWORD rc = ::WaitForMultipleObjects( m_nSocks, m_pWaitObjs, FALSE, nTimeout ); if( rc == WAIT_FAILED ) { dbgout( "WFMO failed: error = %u", ::GetLastError() ); break; } rc = (rc == WAIT_TIMEOUT) ? 0 : 1; #endif if( rc == 0 && m_nTimers ) { assert( m_nTimers && m_nTimerAlloc >= 2 && m_ppTimers[1] ); CKTimer* pTimer = m_ppTimers[1]; if( pTimer->GetMode() == CKTimer::Repeating ) { pTimer->m_next += pTimer->m_interval; } else { pTimer->m_mode = CKTimer::Disabled; m_ppTimers[1] = m_ppTimers[m_nTimers--]; } Heapify( CKTimer::CurrentTime(), 1 ); pTimer->GetResponse()->OnTimer(); } if( rc > 0 ) { UINT n; for( n = 0; n < m_nSocks; n++ ) { assert( WAITOBJ_IS_VALID( m_pWaitObjs[n] ) && NULL != m_ppSocks[n] ); int err = SOCKERR_NONE; waitevents_t wevt; CKSocket* pSock = m_ppSocks[n]; #ifdef _UNIX wevt = m_pWaitObjs[n].revents; if( (wevt & (POLLIN|POLLERR)) && (pSock->m_uSelectFlags & SF_ACCEPT) == SF_ACCEPT ) { wevt = XPOLLACC; } if( (wevt & (POLLOUT|POLLERR)) && (pSock->m_uSelectFlags & SF_CONNECT) == SF_CONNECT ) { socklen_t errlen = sizeof(err); #if defined(_SOLARIS) && (_SOLARIS < 58) getsockopt( pSock->GetHandle(), SOL_SOCKET, SO_ERROR, (char*)&err, &errlen ); #else getsockopt( pSock->GetHandle(), SOL_SOCKET, SO_ERROR, &err, &errlen ); #endif wevt = XPOLLCNX; } if( (wevt & POLLERR) ) { wevt = pSock->m_uSelectFlags; } #endif #ifdef _WIN32 ::WSAEnumNetworkEvents( pSock->GetHandle(), m_pWaitObjs[n], &wevt ); if( wevt.lNetworkEvents & FD_CONNECT ) { err = wevt.iErrorCode[FD_CONNECT_BIT]; } if( wevt.lNetworkEvents & FD_CLOSE ) { wevt.lNetworkEvents = FD_READ; DelStream( pSock ); pSock->GetNotify()->OnClosed(); } #endif if( WAIT_EVENT_READ( wevt ) ) { pSock->GetNotify()->OnReadReady(); } else if( WAIT_EVENT_WRITE( wevt ) ) { pSock->GetNotify()->OnWriteReady(); } else if( WAIT_EVENT_ACCEPT( wevt ) ) { CKListenSocket* pListen = (CKListenSocket*)pSock; sockaddr_in sa; socklen_t salen = sizeof(sa); sockobj_t sock = accept( pListen->GetHandle(), (sockaddr*)&sa, &salen ); if( INVALID_SOCKET != sock ) { #ifdef _WIN32 // Cancel selections (they are inherited in Win32) ::WSAEventSelect( sock, 0, 0 ); #endif CKTcpSocket* pNew = new CKTcpSocket(); pNew->m_sock = sock; pListen->m_pAcceptNotify->OnConnection( pNew ); } } else if( WAIT_EVENT_CONNECT( wevt ) ) { pSock->GetNotify()->OnConnectDone( err ); } else if( WAIT_EVENT_EXCEPT( wevt ) ) { pSock->GetNotify()->OnExceptReady(); } } } } } Exit(); }