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

📄 event.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 2 页
字号:
{  struct po_set *pos = (struct po_set *) es;  ASSERT (pos->fast);  pos->n_events = 0;}static voidpo_del (struct event_set *es, event_t event){  struct po_set *pos = (struct po_set *) es;  ASSERT (!pos->fast);  ASSERT (0); // JYFIXME -- implement po_del}static voidpo_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg){  struct po_set *pos = (struct po_set *) es;  msg (D_EVENT_WAIT, "PO_CTL rwflags=0x%04x ev=%d arg=" ptr_format,       rwflags, (int)event, (ptr_type)arg);  if (pos->fast)    {      if (pos->n_events < pos->capacity)	{	  struct pollfd *pfdp = &pos->events[pos->n_events];	  pfdp->fd = event;	  pfdp->events = pfdp->revents = 0;	  pos->args[pos->n_events] = arg;	  if (rwflags & EVENT_WRITE)	    pfdp->events |= POLLOUT;	  if (rwflags & EVENT_READ)	    pfdp->events |= (POLLIN|POLLPRI);	  ++pos->n_events;	}      else	goto err;    }  else    {      ASSERT (0); // JYFIXME -- implement po_ctl for !fast    }  return; err:  msg (D_EVENT_ERRORS, "Error: poll: too many I/O wait events");}static intpo_wait (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen){  struct po_set *pos = (struct po_set *) es;  int stat;  stat = poll (pos->events, pos->n_events, tv_to_ms_timeout (tv));  // JYFIXME -- show extra debug info after poll() call#if 0  msg (D_EVENT_WAIT, "PO_WAIT DEBUG stat=%d pos->n_events=%d",       stat, pos->n_events);#endif  ASSERT (stat <= pos->n_events);  if (stat > 0)    {      int i, j=0;      const struct pollfd *pfdp = pos->events;      for (i = 0; i < pos->n_events && j < outlen; ++i)	{	  if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP|POLLOUT))	    {	      out->rwflags = 0;	      if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP))		out->rwflags |= EVENT_READ;	      if (pfdp->revents & POLLOUT)		out->rwflags |= EVENT_WRITE;	      out->arg = pos->args[i];	      msg (D_EVENT_WAIT, "PO_WAIT[%d,%d] fd=%d rev=0x%08x rwflags=0x%04x arg=" ptr_format,		   i, j, pfdp->fd, pfdp->revents, out->rwflags, (ptr_type)out->arg);	      ++out;	      ++j;	    }	  ++pfdp;	}      return j;    }  return stat;}static struct event_set *po_init (int *maxevents, unsigned int flags){  struct po_set *pos;  msg (D_EVENT_WAIT, "PO_INIT maxevents=%d flags=0x%08x", *maxevents, flags);  ALLOC_OBJ_CLEAR (pos, struct po_set);  /* set dispatch functions */  pos->func.free = po_free;  pos->func.reset = po_reset;  pos->func.del = po_del;  pos->func.ctl = po_ctl;  pos->func.wait = po_wait;  if (flags & EVENT_METHOD_FAST)    pos->fast = true;  pos->n_events = 0;  /* Figure our event capacity */  ASSERT (*maxevents > 0);  pos->capacity = *maxevents;  /* Allocate space for pollfd structures to be passed to poll() */  ALLOC_ARRAY_CLEAR (pos->events, struct pollfd, pos->capacity);  /* Allocate space for event_set_return objects */  ALLOC_ARRAY_CLEAR (pos->args, void *, pos->capacity);  return (struct event_set *) pos;}#endif /* POLL */#if SELECTstruct se_set{  struct event_set_functions func;  bool fast;  fd_set readfds;  fd_set writefds;  void **args;  int maxfd;  int capacity;};static voidse_free (struct event_set *es){  struct se_set *ses = (struct se_set *) es;  free (ses->args);  free (ses);}static voidse_reset (struct event_set *es){  struct se_set *ses = (struct se_set *) es;  int i;  ASSERT (ses->fast);    FD_ZERO (&ses->readfds);  FD_ZERO (&ses->writefds);  for (i = 0; i <= ses->maxfd; ++i)    ses->args[i] = NULL;  ses->maxfd = -1;}static voidse_del (struct event_set *es, event_t event){  struct se_set *ses = (struct se_set *) es;  ASSERT (!ses->fast);  if (event >= 0 && event < ses->capacity)    {      FD_CLR (event, &ses->readfds);      FD_CLR (event, &ses->writefds);      ses->args[event] = NULL;    }  else    msg (D_EVENT_ERRORS, "Error: select/se_del: too many I/O wait events");  return;}static voidse_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg){  struct se_set *ses = (struct se_set *) es;  msg (D_EVENT_WAIT, "SE_CTL rwflags=0x%04x ev=%d arg=" ptr_format,       rwflags, (int)event, (ptr_type)arg);  if (event >= 0 && event < ses->capacity)    {      ses->maxfd = max_int (event, ses->maxfd);      ses->args[event] = arg;      if (ses->fast)	{	  if (rwflags & EVENT_READ)	    FD_SET (event, &ses->readfds);	  if (rwflags & EVENT_WRITE)	    FD_SET (event, &ses->writefds);	}      else	{	  if (rwflags & EVENT_READ)	    FD_SET (event, &ses->readfds);	  else	    FD_CLR (event, &ses->readfds);	  if (rwflags & EVENT_WRITE)	    FD_SET (event, &ses->writefds);	  else	    FD_CLR (event, &ses->writefds);	}    }  else    {      msg (D_EVENT_ERRORS, "Error: select: too many I/O wait events");    }}static intse_wait_return (struct se_set *ses,		fd_set *read,		fd_set *write,		struct event_set_return *out,		int outlen){  int i, j = 0;  for (i = 0; i <= ses->maxfd && j < outlen; ++i)    {      const bool r = FD_ISSET (i, read);      const bool w = FD_ISSET (i, write);      if (r || w)	{	  out->rwflags = 0;	  if (r)	    out->rwflags |= EVENT_READ;	  if (w)	    out->rwflags |= EVENT_WRITE;	  out->arg = ses->args[i];	  msg (D_EVENT_WAIT, "SE_WAIT[%d,%d] rwflags=0x%04x arg=" ptr_format,	       i, j, out->rwflags, (ptr_type)out->arg);	  ++out;	  ++j;	}    }  return j;}static intse_wait_fast (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen){  struct se_set *ses = (struct se_set *) es;  struct timeval tv_tmp = *tv;  int stat;  stat = select (ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);  if (stat > 0)    stat = se_wait_return (ses, &ses->readfds, &ses->writefds, out, outlen);  return stat;}static intse_wait_scalable (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen){  struct se_set *ses = (struct se_set *) es;  struct timeval tv_tmp = *tv;  fd_set read = ses->readfds;  fd_set write = ses->writefds;  int stat;  stat = select (ses->maxfd + 1, &read, &write, NULL, &tv_tmp);  if (stat > 0)    stat = se_wait_return (ses, &read, &write, out, outlen);  return stat;}static struct event_set *se_init (int *maxevents, unsigned int flags){  const int maximum_fds = 256; // JYFIXME -- figure out the minimum on all OSes which OpenVPN supports  struct se_set *ses;  msg (D_EVENT_WAIT, "SE_INIT maxevents=%d flags=0x%08x", *maxevents, flags);  ALLOC_OBJ_CLEAR (ses, struct se_set);  /* set dispatch functions */  ses->func.free = se_free;  ses->func.reset = se_reset;  ses->func.del = se_del;  ses->func.ctl = se_ctl;  ses->func.wait = se_wait_scalable;  if (flags & EVENT_METHOD_FAST)    {      ses->fast = true;      ses->func.wait = se_wait_fast;    }  /* Select needs to be passed this value + 1 */  ses->maxfd = -1;  /* Figure our event capacity */  ASSERT (*maxevents > 0);  *maxevents = min_int (*maxevents, maximum_fds);  ses->capacity = *maxevents + 10;  /* Allocate space for event_set_return void * args */  ALLOC_ARRAY_CLEAR (ses->args, void *, ses->capacity);  return (struct event_set *) ses;}#endif /* SELECT */static struct event_set *event_set_init_simple (int *maxevents, unsigned int flags){  struct event_set *ret = NULL;#ifdef WIN32  ret = we_init (maxevents, flags);#elif POLL && SELECT  if (flags & EVENT_METHOD_US_TIMEOUT)    ret = se_init (maxevents, flags); # ifdef SELECT_PREFERRED_OVER_POLL   if (!ret)     ret = se_init (maxevents, flags);   if (!ret)     ret = po_init (maxevents, flags);# else   if (!ret)     ret = po_init (maxevents, flags);   if (!ret)     ret = se_init (maxevents, flags);# endif#elif POLL  ret = po_init (maxevents, flags);#elif SELECT  ret = se_init (maxevents, flags);#else#error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel#endif  ASSERT (ret);  return ret;}static struct event_set *event_set_init_scalable (int *maxevents, unsigned int flags){  struct event_set *ret = NULL;#if EPOLL  ret = ep_init (maxevents, flags);  if (!ret)    {      msg (M_WARN, "Note: sys_epoll API is unavailable, falling back to poll/select API");      ret = event_set_init_simple (maxevents, flags);    }#else  ret = event_set_init_simple (maxevents, flags);#endif  ASSERT (ret);  return ret;}struct event_set *event_set_init (int *maxevents, unsigned int flags){  if (flags & EVENT_METHOD_FAST)    return event_set_init_simple (maxevents, flags);  else    return event_set_init_scalable (maxevents, flags);}

⌨️ 快捷键说明

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