fdwatch.c

来自「打魔兽战网的都知道他是什么」· C语言 代码 · 共 212 行

C
212
字号
/*  * Abstraction API/layer for the various ways PvPGN can inspect sockets state  * 2003 (C)   *  * Code is based on the ideas found in thttpd project.  *  * This program is free software; you can redistribute it and/or  * modify it under the terms of the GNU General Public License  * as published by the Free Software Foundation; either version 2  * of the License, or (at your option) any later version.  *  * This program is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  * GNU General Public License for more details.  *  * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  */#include "common/setup_before.h"#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H#  include <strings.h># endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H#  include <malloc.h># endif#endif#include "common/eventlog.h"#define FDWATCH_BACKEND#include "fdwatch.h"#ifdef HAVE_SELECT#include "fdwatch_select.h"#endif#ifdef HAVE_POLL#include "fdwatch_poll.h"#endif#ifdef HAVE_KQUEUE#include "fdwatch_kqueue.h"#endif#ifdef HAVE_EPOLL#include "fdwatch_epoll.h"#endif#include "common/rlimit.h"#include "common/xalloc.h"#include "common/setup_after.h"int fdw_maxcons;t_fdwatch_fd *fdw_fds = NULL;static t_fdw_backend * fdw = NULL;static DECLARE_ELIST_INIT(freelist);static DECLARE_ELIST_INIT(uselist);extern int fdwatch_init(int maxcons){    int i, maxsys;    maxsys = get_socket_limit();    if (maxsys > 0) maxcons = (maxcons < maxsys) ? maxcons : maxsys;    if (maxcons < 32) {	eventlog(eventlog_level_fatal, __FUNCTION__, "too few sockets available (%d)",maxcons);	return -1;    }    fdw_maxcons = maxcons;    fdw_fds = xmalloc(sizeof(t_fdwatch_fd) * fdw_maxcons);    memset(fdw_fds, 0, sizeof(t_fdwatch_fd) * fdw_maxcons);    /* add all slots to the freelist */    for(i = 0; i < fdw_maxcons; i++)	elist_add_tail(&freelist,&(fdw_fds[i].freelist));#ifdef HAVE_EPOLL    fdw = &fdw_epoll;    if (!fdw->init(fdw_maxcons)) goto ok;#endif#ifdef HAVE_KQUEUE    fdw = &fdw_kqueue;    if (!fdw->init(fdw_maxcons)) goto ok;#endif#ifdef HAVE_POLL    fdw = &fdw_poll;    if (!fdw->init(fdw_maxcons)) goto ok;    goto ok;#endif#ifdef HAVE_SELECT    fdw = &fdw_select;    if (!fdw->init(fdw_maxcons)) goto ok;#endif    eventlog(eventlog_level_fatal, __FUNCTION__, "Found no working fdwatch layer");    fdw = NULL;    fdwatch_close();    return -1;ok:    return 0;}extern int fdwatch_close(void){    if (fdw) { fdw->close(); fdw = NULL; }    if (fdw_fds) { xfree((void*)fdw_fds); fdw_fds = NULL; }    elist_init(&freelist);    elist_init(&uselist);    return 0;}extern int fdwatch_add_fd(int fd, t_fdwatch_type rw, fdwatch_handler h, void *data){    t_fdwatch_fd *cfd;    if (elist_empty(&freelist)) return -1;	/* max sockets reached */    cfd = elist_entry(elist_next(&freelist),t_fdwatch_fd,freelist);    fdw_fd(cfd) = fd;    if (fdw->add_fd(fdw_idx(cfd), rw)) return -1;    /* add it to used sockets list, remove it from free list */    elist_add_tail(&uselist,&cfd->uselist);    elist_del(&cfd->freelist);    fdw_rw(cfd) = rw;    fdw_data(cfd) = data;    fdw_hnd(cfd) = h;    return fdw_idx(cfd);}extern int fdwatch_update_fd(int idx, t_fdwatch_type rw){    if (idx<0 || idx>=fdw_maxcons) {	eventlog(eventlog_level_error,__FUNCTION__,"out of bounds idx [%d] (max: %d)",idx, fdw_maxcons);	return -1;    }    /* do not allow completly reset the access because then backend codes      * can get confused */    if (!rw) {	eventlog(eventlog_level_error,__FUNCTION__,"tried to reset rw, not allowed");	return -1;    }    if (!fdw_rw(fdw_fds + idx)) {	eventlog(eventlog_level_error,__FUNCTION__,"found reseted rw");	return -1;    }    if (fdw->add_fd(idx, rw)) return -1;    fdw_rw(&fdw_fds[idx]) = rw;    return 0;}extern int fdwatch_del_fd(int idx){    t_fdwatch_fd *cfd;    if (idx<0 || idx>=fdw_maxcons) {	eventlog(eventlog_level_error,__FUNCTION__,"out of bounds idx [%d] (max: %d)",idx, fdw_maxcons);	return -1;    }    cfd = fdw_fds + idx;    if (!fdw_rw(cfd)) {	eventlog(eventlog_level_error,__FUNCTION__,"found reseted rw");	return -1;    }    fdw->del_fd(idx);    /* remove it from uselist, add it to freelist */    elist_del(&cfd->uselist);    elist_add_tail(&freelist,&cfd->freelist);    fdw_fd(cfd) = 0;    fdw_rw(cfd) = 0;    fdw_data(cfd) = NULL;    fdw_hnd(cfd) = NULL;    return 0;}extern int fdwatch(long timeout_msec){    return fdw->watch(timeout_msec);}extern void fdwatch_handle(void){    fdw->handle();}extern void fdwatch_traverse(t_fdw_cb cb, void *data){    t_elist *curr;    elist_for_each(curr,&uselist)    {	if (cb(elist_entry(curr,t_fdwatch_fd,uselist),data)) break;    }}

⌨️ 快捷键说明

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