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

📄 server-loop.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * server-loop.c - server loop implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * * This 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, or (at your option) * any later version. *  * This software 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 package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: server-loop.c,v 1.5 2001/05/22 21:06:42 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#ifdef _AIX# undef _NO_PROTO# ifndef _USE_IRS#  define _USE_IRS 1# endif# define _XOPEN_SOURCE_EXTENDED 1# define _ALL_SOURCE 1#endif /* _AIX */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <time.h>#if HAVE_SYS_TIME_H# include <sys/time.h>#endif#include <sys/types.h>#if HAVE_UNISTD_H# include <unistd.h>#endif#if HAVE_SYS_POLL_H# include <sys/poll.h>#endif#if HAVE_STRINGS_H# include <strings.h>#endif#ifdef __MINGW32__# include <winsock2.h>#endif#include "libserveez/alloc.h"#include "libserveez/util.h"#include "libserveez/socket.h"#include "libserveez/pipe-socket.h"#include "libserveez/server-core.h"#include "libserveez/server-loop.h"#ifndef __MINGW32__/* * Check the server and client sockets for incoming connections  * and data, and process outgoing data. */static intsvz_check_sockets_select (void){  int nfds;			/* count of file descriptors to check */  fd_set read_fds;		/* bitmasks for file descriptors to check */  fd_set write_fds;		/* ditto */  fd_set except_fds;		/* ditto */  struct timeval wait;		/* used for timeout in select() */  svz_socket_t *sock;  /*   * Prepare the file handle sets for the select() call below.   */  FD_ZERO (&read_fds);  FD_ZERO (&except_fds);  FD_ZERO (&write_fds);  nfds = 0;  /*   * Here we set the bitmaps for all clients we handle.   */  svz_sock_foreach (sock)    {      /* Put only those SOCKs into fd set not yet killed and skip files. */      if (sock->flags & SOCK_FLAG_KILLED)	continue;      /* If socket is a file descriptor, then read it here. */      if (sock->flags & SOCK_FLAG_FILE)	{	  if (sock->read_socket)	    if (sock->read_socket (sock))	      svz_sock_schedule_for_shutdown (sock);	}      /* Handle pipes. */      if (sock->flags & SOCK_FLAG_PIPE)	{	  /* Do not handle listening pipes here. */	  if (sock->flags & SOCK_FLAG_LISTENING)	    continue;	  /* 	   * Put a pipe's descriptor into WRITE and EXCEPT set.	   */	  if (sock->flags & SOCK_FLAG_SEND_PIPE)	    {	      FD_SET (sock->pipe_desc[WRITE], &except_fds);	      if (sock->pipe_desc[WRITE] > nfds)		nfds = sock->pipe_desc[WRITE];	      if (sock->send_buffer_fill > 0)		FD_SET (sock->pipe_desc[WRITE], &write_fds);	    }	  /* 	   * Put a pipe's descriptor into READ set for getting data.	   */	  if (sock->flags & SOCK_FLAG_RECV_PIPE)	    {	      FD_SET (sock->pipe_desc[READ], &except_fds);	      FD_SET (sock->pipe_desc[READ], &read_fds);	      if (sock->pipe_desc[READ] > nfds)		nfds = sock->pipe_desc[READ];	    }	}      /* Handle sockets. */      if (sock->flags & SOCK_FLAG_SOCK)	{	  /* Is the socket descriptor currently unavailable ? */	  if (sock->unavailable)	    {	      if (time (NULL) >= sock->unavailable)		sock->unavailable = 0;	    }	  /* Put every client's socket into EXCEPT. */	  FD_SET (sock->sock_desc, &except_fds);	  if (sock->sock_desc > (SOCKET) nfds)	    nfds = sock->sock_desc;	  /* Put socket into READ if necessary. */	  if (!(sock->flags & SOCK_FLAG_CONNECTING))	    {	      FD_SET (sock->sock_desc, &read_fds);	    }	  /* Put a socket into WRITE if necessary and possible. */	  if (!sock->unavailable && (sock->send_buffer_fill > 0 || 				     sock->flags & SOCK_FLAG_CONNECTING))	    {	      FD_SET (sock->sock_desc, &write_fds);	    }	}    }    nfds++;  /*   * Adjust timeout value, so we won't wait longer than we want.   */  wait.tv_sec = svz_notify - time (NULL);  if (wait.tv_sec < 0)    wait.tv_sec = 0;  wait.tv_usec = 0;  if ((nfds = select (nfds, &read_fds, &write_fds, &except_fds, &wait)) <= 0)    {      if (nfds < 0)	{	  svz_log (LOG_ERROR, "select: %s\n", NET_ERROR);	  if (errno == EBADF)	    svz_sock_check_bogus ();	  return -1;	}      else 	{	  /*	   * select() timed out, so we can do some administrative stuff.	   */	  svz_periodic_tasks ();	}    }  /*    * Go through all enqueued SOCKs and check if these have been    * select()ed or could be handle in any other way.   */  svz_sock_foreach (sock)    {      if (sock->flags & SOCK_FLAG_KILLED)	continue;      /* Handle pipes. */      if (sock->flags & SOCK_FLAG_PIPE)	{	  /* Make listening pipe servers listen. */	  if (sock->flags & SOCK_FLAG_LISTENING)	    {	      if (!(sock->flags & SOCK_FLAG_INITED))		if (sock->read_socket)		  if (sock->read_socket (sock))		    svz_sock_schedule_for_shutdown (sock);	      continue;	    }	  /* Handle receiving pipes. */	  if (sock->flags & SOCK_FLAG_RECV_PIPE)	    {	      if (FD_ISSET (sock->pipe_desc[READ], &except_fds))		{		  svz_log (LOG_ERROR, "exception on receiving pipe %d \n",			   sock->pipe_desc[READ]);		  svz_sock_schedule_for_shutdown (sock);		}	      if (FD_ISSET (sock->pipe_desc[READ], &read_fds))		{		  if (sock->read_socket)		    if (sock->read_socket (sock))		      svz_sock_schedule_for_shutdown (sock);		}	    }	  /* Handle sending pipes. */	  if (sock->flags & SOCK_FLAG_SEND_PIPE)	    {	      if (FD_ISSET (sock->pipe_desc[WRITE], &except_fds))		{		  svz_log (LOG_ERROR, "exception on sending pipe %d \n",			   sock->pipe_desc[WRITE]);		  svz_sock_schedule_for_shutdown (sock);		}	      if (FD_ISSET (sock->pipe_desc[WRITE], &write_fds))		{		  if (sock->write_socket)		    if (sock->write_socket (sock))		      svz_sock_schedule_for_shutdown (sock);		}	    }	}      /* Handle usual sockets. Socket in the exception set ? */      if (sock->flags & SOCK_FLAG_SOCK)	{	  if (FD_ISSET (sock->sock_desc, &except_fds))	    {	      if (sock->flags & SOCK_FLAG_CONNECTING)		{		  svz_log (LOG_ERROR, "exception connecting socket %d\n",			   sock->sock_desc);		}	      else		{		  svz_log (LOG_ERROR, "exception on socket %d\n",			   sock->sock_desc);		}	      svz_sock_error_info (sock);	      svz_sock_schedule_for_shutdown (sock);	      continue;	    }	  	  /* Is socket readable ? */	  if (FD_ISSET (sock->sock_desc, &read_fds))	    {	      if (sock->read_socket)		if (sock->read_socket (sock))		  {		    svz_sock_schedule_for_shutdown (sock);		    continue;		  }	    }	  	  /* Is socket writable ? */	  if (FD_ISSET (sock->sock_desc, &write_fds))	    {	      /* Socket connecting ? */	      if (sock->flags & SOCK_FLAG_CONNECTING)		{		  if (sock->connected_socket)		    if (sock->connected_socket (sock))		      {			svz_sock_schedule_for_shutdown (sock);			continue;		      }		}	      /* No. Just writable. */	      else 		{		  if (sock->write_socket)		    if (sock->write_socket (sock))		      {			svz_sock_schedule_for_shutdown (sock);			continue;		      }		}	    }	}    }  /*   * We had no chance to time out so we have to explicitly call the   * timeout handler.   */  if (time (NULL) > svz_notify)    {      svz_periodic_tasks ();    }    return 0;}#endif /* not __MINGW32__ */#if HAVE_POLL && ENABLE_POLL /* configured *//* re-allocate static buffers if necessary */#define FD_EXPAND()                                                 \  if (nfds >= max_nfds) {                                           \    max_nfds++;                                                     \    ufds = svz_prealloc (ufds, sizeof (struct pollfd) * max_nfds);  \    memset (&ufds[max_nfds-1], 0, sizeof (struct pollfd));          \    sfds = svz_prealloc (sfds, sizeof (svz_socket_t *) * max_nfds); \    memset (&sfds[max_nfds-1], 0, sizeof (svz_socket_t *));         \  }                                                                 \/* check for incoming data */#define FD_POLL_IN(fd, sock)                 \  {                                          \    FD_EXPAND();                             \    ufds[nfds].fd = fd;                      \    ufds[nfds].events |= (POLLIN | POLLPRI); \    sfds[nfds] = sock;                       \  }                                          \/* process outgoing data */#define FD_POLL_OUT(fd, sock)     \  {                               \    FD_EXPAND();                  \    ufds[nfds].fd = fd;           \    ufds[nfds].events |= POLLOUT; \    sfds[nfds] = sock;            \  }                               \/* clear polling buffers */#define FD_POLL_CLR(ufds, sfds)                           \  if (ufds) {                                             \    memset (ufds, 0, sizeof (struct pollfd) * max_nfds);  \    memset (sfds, 0, sizeof (svz_socket_t *) * max_nfds); \  }                                                       \/* * Same routine as the above check_sockets_select() routine. Here we are  * using poll() instead of select(). This might solve the builtin file  * descriptor limit of the (g)libc select(). This routine will NOT be * available under Win32. */static intsvz_check_sockets_poll (void){  static unsigned int max_nfds = 0;   /* maximum number of file descriptors */  unsigned int nfds, fd;              /* number of fds */  static struct pollfd *ufds = NULL;  /* poll fd array */  static svz_socket_t **sfds = NULL;  /* referring socket structures */  int timeout;                        /* timeout in milliseconds */  int polled;                         /* amount of polled fds */  svz_socket_t *sock;                 /* socket structure */  /* clear polling structures */  nfds = 0;  FD_POLL_CLR (ufds, sfds);  /* go through all sockets */  svz_sock_foreach (sock)    {      /* skip already killed sockets */      if (sock->flags & SOCK_FLAG_KILLED)	continue;      /* process files */      if (sock->flags & SOCK_FLAG_FILE)	{	  if (sock->read_socket)	    if (sock->read_socket (sock))	      svz_sock_schedule_for_shutdown (sock);	}      /* process pipes */      if (sock->flags & SOCK_FLAG_PIPE)	{	  /* handle listening pipe */	  if (sock->flags & SOCK_FLAG_LISTENING)	    {

⌨️ 快捷键说明

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