Beispiel #1
0
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();
}