⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketengine_kqueue.cpp

📁 WOW 服务模拟端 支持2.4.3版本 来自开源的ASCENT 自己REPACK
💻 CPP
字号:
/****************************************************************************
 *
 * Multiplatform High-Performance Async Network Library
 * Implemented epoll Socket Engine
 * Copyright (c) 2007 Burlex
 *
 * This file may be distributed under the terms of the Q Public License
 * as defined by Trolltech ASA of Norway and appearing in the file
 * COPYING included in the packaging of this file.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#include "Network.h"

#ifdef NETLIB_KQUEUE

kqueueEngine::kqueueEngine()
{
	new SocketDeleter();
	kq = kqueue();
	assert(kq != -1);
	memset(this->fds, 0, sizeof(void*) * MAX_DESCRIPTORS);
	m_running = true;
}

kqueueEngine::~kqueueEngine()
{
	close(kq);
}

void kqueueEngine::AddSocket(BaseSocket * s)
{
	assert(fds[s->GetFd()] == 0);
	fds[s->GetFd()] = s;

	struct kevent ev;
	EV_SET(&ev, s->GetFd(), s->Writable() ? EVFILT_WRITE : EVFILT_READ, EV_ADD, 0, 0, NULL);
	if(kevent(kq, &ev, 1, NULL, 0, NULL) < 0)
		printf("!! could not add kevent for fd %u\n", s->GetFd());
}

void kqueueEngine::RemoveSocket(BaseSocket * s)
{
	int a, b;
	assert(fds[s->GetFd()] == s);
	fds[s->GetFd()] = 0;

	struct kevent ke, k2;
	EV_SET(&ke, s->GetFd(), EVFILT_READ, EV_DELETE, 0, 0, NULL);
	EV_SET(&k2, s->GetFd(), EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
	if((kevent(kq, &ke, 1, NULL, 0, NULL) < 0) && (kevent(kq, &k2, 1, NULL, 0, NULL) < 0))
		printf("!! both kevent removals returned -1 for fd %u\n", s->GetFd());	
}

void kqueueEngine::WantWrite(BaseSocket * s)
{
	struct kevent ev;
	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 for fd %u\n", s->GetFd());
}

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);
			}
		}
	}
}

void kqueueEngine::Shutdown()
{
	m_running = false;
	for(int i = 0; i < MAX_DESCRIPTORS; ++i)
	{
		if(fds[i] != 0)
		{
			fds[i]->Delete();
		}
	}

	sSocketDeleter.Kill();
	delete SocketDeleter::getSingletonPtr();
	delete this;
}

void kqueueEngine::SpawnThreads()
{
	launch_thread(new SocketEngineThread(this));
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -