コード例 #1
0
ファイル: DataQueue.cpp プロジェクト: hkg36/My_EXLIB
void CDataQueue::WriteData(const char* buffer,int buffersize)
{
	while(buffersize)
	{
		char* writepos;
		int towrite;
		WantWrite(&writepos,buffersize,&towrite);
		memcpy(writepos,buffer,towrite);
		buffer+=towrite;
		buffersize-=towrite;
		WriteMoveNext(towrite);
	}
}
コード例 #2
0
void epollEngine::MessageLoop()
{
	const static int maxevents = 1024;
	struct epoll_event events[1024];
	int nfds, i;
	BaseSocket * s;
	while(m_running)
	{
        	nfds = epoll_wait(epoll_fd, events, maxevents, 1000);
		for(i = 0; i < nfds; ++i)
		{
	            s = fds[events[i].data.fd];
			if(s == 0)
			{
				printf("epoll returned invalid fd %u\n", events[i].data.fd);
				continue;
			}

			if(events[i].events & EPOLLHUP || events[i].events & EPOLLERR)
			{
				s->OnError(errno);
			}
			else if(events[i].events & EPOLLIN)
			{
				s->OnRead(0);
				if(s->Writable() && !s->m_writeLock)
				{
					++s->m_writeLock;
					WantWrite(s);
				}
			}
			else if(events[i].events & EPOLLOUT)
			{
				s->OnWrite(0);
				if(!s->Writable())
				{
					/* change back to read state */
					struct epoll_event ev;
					memset(&ev, 0, sizeof(epoll_event));
					ev.data.fd = s->GetFd();
					ev.events = EPOLLIN | EPOLLET;

					epoll_ctl(epoll_fd, EPOLL_CTL_MOD, s->GetFd(), &ev);
					--s->m_writeLock;
				}
			}
		}
	}
}
コード例 #3
0
ファイル: client.cpp プロジェクト: AlanXie1991/Server
//core algorithm !!
bool Client::StatusMachine()
{
    std::string::size_type newline;
    
    PluginStatus  plugin_status;
    RequestStatus request_status;
    
    while (true)
    {
        switch (m_status)
        {
            case BEFORE_REQUEST:  //transitional status
                if (!PluginBeforeRequest()) {
                    return false;
                }
                
                WantRead();
                SetStatus(ON_REQUEST);
                break;
            case ON_REQUEST:      //lasting status
                if (!PluginOnRequest()) {
                    return false;
                }
                
                request_status = GetHttpRequest();
                
                if (request_status == REQ_ERROR) {
                    return false;
                } 
                else if (request_status == REQ_IS_COMPLETE) {
                    SetStatus(AFTER_REQUEST);
                    break;
                }
                else {
                    return true;
                }
            case AFTER_REQUEST:   //transitional status
                if (!PluginAfterRequest()) {
                    return false;
                }
                NotWantRead();
                SetStatus(BEFORE_RESPONSE);
                break;
            case BEFORE_RESPONSE: //transitional status
                if (!PluginBeforeResponse()) {
                    return false;
                }
                WantWrite();
                SetStatus(ON_RESPONSE);
                break;
            case ON_RESPONSE:    //lasting status
                plugin_status = PluginOnResponse();
                
                if (plugin_status == ERROR) { //need to send back 500(Server Internal Error)
                    SetStatus(BEFORE_ERROR);
                    continue;
                }
                else if (plugin_status == NOT_OK) { //Plugin isn't ready, we continue with other client
                    return true;
                }
                
                //All Plugins have been finished, Send out the response.
                m_outbuf += m_response.SerializeResponse(); 
                
                SetStatus(AFTER_RESPONSE);
                break;
            case AFTER_RESPONSE:  //transitional status
                if (!PluginAfterResponse()) {
                    return false;
                }
                
                delete m_request;
                m_request = NULL;
                
                m_response.ResetResponse();
                
                NotWantWrite();
                SetStatus(BEFORE_REQUEST);
                break;
            case BEFORE_ERROR:
                m_response.ResetResponse();
                
                m_response.m_code = 500;
                m_response.m_explain = "Server Error";
                m_response.m_headers["Date"] = "Fri, 27 October 2012 15:45:00 GMT";
        
                m_outbuf += m_response.SerializeResponse();

                SetStatus(ON_ERROR);
                break;
            case ON_ERROR:
                if (!m_outbuf.size()) //keep write event to check if 500 response has been sent away
                {
                    return false;     //let the client leave, error 500 has been sent away.
                }
                return true;
        }
    }

    return true;
}
コード例 #4
0
bool IOCPEngine::AddFd(EventHandler* eh)
{
	/* Does it at least look valid? */
	if (!eh)
		return false;

	int* fake_fd = new int(GenerateFd(eh->GetFd()));
	int is_accept = 0;
	int opt_len = sizeof(int);

	/* In range? */
	if ((*fake_fd < 0) || (*fake_fd > MAX_DESCRIPTORS))
	{
		delete fake_fd;
		return false;
	}

	/* Already an entry here */
	if (ref[*fake_fd])
	{
		delete fake_fd;
		return false;
	}

	/* are we a listen socket? */
	getsockopt(eh->GetFd(), SOL_SOCKET, SO_ACCEPTCONN, (char*)&is_accept, &opt_len);

	/* set up the read event so the socket can actually receive data :P */
	eh->Extend("internal_fd", fake_fd);

	unsigned long completion_key = (ULONG_PTR)*fake_fd;
	/* assign the socket to the completion port */
	if (!CreateIoCompletionPort((HANDLE)eh->GetFd(), m_completionPort, completion_key, 0))
		return false;

	/* setup initial events */
	if(is_accept)
		PostAcceptEvent(eh);
	else
		PostReadEvent(eh);

	/* log message */
	ServerInstance->Logs->Log("SOCKET",DEBUG, "New fake fd: %u, real fd: %u, address 0x%p", *fake_fd, eh->GetFd(), eh);

	/* post a write event if there is data to be written */
	if(eh->Writeable())
		WantWrite(eh);

	/* we're all good =) */
	try
	{
		m_binding.insert( std::map<int, EventHandler*>::value_type( eh->GetFd(), eh ) );
	}
	catch (...)
	{
		/* Ohshi-, map::insert failed :/ */
		return false;
	}

	++CurrentSetSize;
	ref[*fake_fd] = eh;

	return true;
}
コード例 #5
0
bool TcpServer::_StartUpLin()
{
#ifndef WIN32
    int loop_times = 0;
    const int timer_check_point = 10; //达到指定循环次数即开始timer检查

	while(m_bRun) 
	{
		int res = epoll_wait(m_epoll_fd, m_epev_arr, EVENT_TOTAL_COUNT, 100);
		if ( res < 0) {
            //及时退出,否则会导致 CPU 100% 
			if (EINTR == errno)
				continue;
			log_debug("epoll_wait return false, errno = %d\n", errno);
			break;
		}
		else if (0 == res) { //timeout
            loop_times = 0;
			run_timer();
		}
        else {
            //间隔一定次数即开始检查定时器的超时事件
            if (++loop_times >= timer_check_point) {
                loop_times = 0;
                //驱动定时器处理
                run_timer();
            }
        }
		
		for(int i=0; i<res; i++)
		{
			if(m_epev_arr[i].data.fd == m_listen_fd)
			{
				handle_accept();
                continue;
			}
            int fd = (uint32_t)m_epev_arr[i].data.u64; /* mask out the lower 32 bits */
            uint32 index = (uint32_t)(m_epev_arr[i].data.u64 >> 32);
            TcpHandler* s = fds[fd];
            if( s == 0 || s->get_fd_index() != index )
            {                      
                continue;       // epoll returned invalid fd 
            }
            if( m_epev_arr[i].events & ( EPOLLHUP | EPOLLERR ))
            {    
                handle_close(s);
                continue;
            }
			else if(m_epev_arr[i].events & EPOLLIN )
			{				
                if(s->handle_read() == -1)
				{
					handle_close(s);
					continue;
				}
                if( s->Writable() )
                    WantWrite(s);
			}
			else if(m_epev_arr[i].events&EPOLLOUT)
			{
				if(s->handle_output() == -1)
				{
					handle_close(s);
					continue;
				}
                if(!s->Writable())
                    WantRead(s);
			}
		}
	}
#endif 
	return true;
}
コード例 #6
0
void kqueueEngine::MessageLoop()
{
	const static int maxevents = MAX_DESCRIPTORS;
	timespec timeout;
	timeout.tv_sec = 1;
	timeout.tv_nsec = 0;
	struct kevent events[MAX_DESCRIPTORS];
	struct kevent ev;
	int nfds, i;
	BaseSocket * s;
	while(m_running)
	{
		nfds = kevent(kq, 0, 0, events, maxevents, &timeout);
		for(i = 0; i < nfds; ++i)
		{
	        s = fds[events[i].ident];
			if(s == 0)
			{
				printf("kqueue returned invalid fd %u\n", events[i].ident);
				continue;
			}

			if(events[i].flags & EV_EOF || events[i].flags & EV_ERROR)
			{
				s->OnError(events[i].fflags);
				continue;
			}

			if(events[i].filter == EVFILT_READ)
			{
				s->OnRead(0);
                if(s->Writable() && !s->m_writeLock)
				{
					++s->m_writeLock;
					WantWrite(s);
				}
			}
			else if(events[i].filter == EVFILT_WRITE)
			{
				s->OnWrite(0);
				if(!s->Writable())
				{
					--s->m_writeLock;
					EV_SET(&ev, s->GetFd(), EVFILT_READ, EV_ADD, 0, 0, NULL);
					if(kevent(kq, &ev, 1, NULL, 0, NULL) < 0)
						printf("!! could not modify kevent (to read) for fd %u\n", s->GetFd());
				}
				else
				{
					EV_SET(&ev, s->GetFd(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, NULL);
                    if(kevent(kq, &ev, 1, NULL, 0, NULL) < 0)
	                    printf("!! could not modify kevent (to write) for fd %u\n", s->GetFd());
				}

			}
			else
			{
				printf("Unknwon filter: %u Fflags: %u, fd: %u, flags: %u\n", events[i].filter, events[i].fflags, events[i].ident, events[i].flags);
			}
		}
	}
}