esock_poll.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 208 行
C
208 行
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ *//* * Purpose: Hide poll() and select() behind an API so that we * can use either one. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef __WIN32__#include "esock_winsock.h"#endif#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <time.h>#include <ctype.h>#include <sys/types.h>#include <errno.h>#ifdef __WIN32__#include <process.h>#else#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <sys/time.h>#include <netdb.h>#include <arpa/inet.h>#include <fcntl.h>#endif#include "esock.h"#include "esock_ssl.h"#include "esock_utils.h"#include "esock_poll.h"#include "debuglog.h"#if !defined(USE_SELECT)/* At least on FreeBSD, we need POLLRDNORM for normal files, not POLLIN. *//* Whether this is a bug in FreeBSD, I don't know. */#ifdef POLLRDNORM#define POLL_INPUT (POLLIN | POLLRDNORM)#else#define POLL_INPUT POLLIN#endifstatic void poll_fd_set(EsockPoll *ep, FD fd, short events){ int i, j; int prev_num_fds = ep->num_fds; if (ep->num_fds <= fd) { ep->num_fds = fd + 64; ep->fd_to_poll = (int *) esock_realloc(ep->fd_to_poll, ep->num_fds*sizeof(int)); for (j = prev_num_fds; j < ep->num_fds; j++) ep->fd_to_poll[j] = -1; } i = ep->fd_to_poll[fd]; if (i > 0 && i < ep->active && ep->fds[i].fd == fd) { /* Already present in poll array */ ep->fds[i].events |= events; } else { /* Append to poll array */ if (ep->active >= ep->allocated) { ep->allocated *= 2; ep->fds = (struct pollfd *) esock_realloc(ep->fds, ep->allocated*sizeof(struct pollfd)); } ep->fd_to_poll[fd] = ep->active; ep->fds[ep->active].fd = fd; ep->fds[ep->active].events = events; ep->fds[ep->active].revents = 0; ep->active++; }}static int poll_is_set(EsockPoll *ep, FD fd, short mask){ if (fd >= ep->num_fds) { return 0; } else { int i = ep->fd_to_poll[fd]; return 0 <= i && i < ep->active && ep->fds[i].fd == fd && (ep->fds[i].revents & mask) != 0; }}#endifvoid esock_poll_init(EsockPoll *ep){#ifdef USE_SELECT /* Nothing to do here */#else ep->allocated = 2; ep->fds = (struct pollfd *) esock_malloc(ep->allocated*sizeof(struct pollfd)); ep->num_fds = 1; ep->fd_to_poll = esock_malloc(ep->num_fds*sizeof(int));#endif }void esock_poll_zero(EsockPoll *ep){#ifdef USE_SELECT FD_ZERO(&ep->readmask); FD_ZERO(&ep->writemask); FD_ZERO(&ep->exceptmask);#else int i; for (i = 0; i < ep->num_fds; i++) ep->fd_to_poll[i] = -1; ep->active = 0;#endif }void esock_poll_fd_set_read(EsockPoll *ep, FD fd){#ifdef USE_SELECT FD_SET(fd, &ep->readmask);#else poll_fd_set(ep, fd, POLL_INPUT);#endif }void esock_poll_fd_set_write(EsockPoll *ep, FD fd){#ifdef USE_SELECT FD_SET(fd, &ep->writemask);#else poll_fd_set(ep, fd, POLLOUT);#endif }int esock_poll_fd_isset_read(EsockPoll *ep, FD fd){#ifdef USE_SELECT return FD_ISSET(fd, &ep->readmask);#else return poll_is_set(ep, fd, (POLL_INPUT|POLLHUP|POLLERR|POLLNVAL));#endif }int esock_poll_fd_isset_write(EsockPoll *ep, FD fd){#ifdef USE_SELECT return FD_ISSET(fd, &ep->writemask);#else return poll_is_set(ep, fd, (POLLOUT|POLLHUP|POLLERR|POLLNVAL));#endif }#ifdef __WIN32__void esock_poll_fd_set_exception(EsockPoll *ep, FD fd){ FD_SET(fd, &ep->exceptmask);}int esock_poll_fd_isset_exception(EsockPoll *ep, FD fd){ return FD_ISSET(fd, &ep->exceptmask);}#endifint esock_poll(EsockPoll *ep, int seconds){ int sret;#ifdef USE_SELECT struct timeval tv; tv.tv_sec = seconds; tv.tv_usec = 0; sret = select(FD_SETSIZE, &ep->readmask, &ep->writemask, &ep->exceptmask, &tv); if (sret == 0) { FD_ZERO(&ep->readmask); FD_ZERO(&ep->writemask); FD_ZERO(&ep->exceptmask); }#else sret = poll(ep->fds, ep->active, 1000*seconds);#endif return sret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?