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

📄 su_wait.c

📁 this is simple sip stack.
💻 C
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@ingroup su_wait * * @CFILE su_wait.c   * Implementation of OS-independent socket synchronization interface. * * This looks like nth reincarnation of "reactor".  It implements the * (poll()/select()/WaitForMultipleObjects()) functionality. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * @date Created: Tue Sep 14 15:51:04 1999 ppessi * */#include <stdlib.h>#include <assert.h>#include <stdio.h>#define SU_INTERNAL_P su_root_t *#include "sofia-sip/su.h"#include "sofia-sip/su_wait.h"#include "sofia-sip/su_alloc.h"/**@defgroup su_wait Syncronization and Threading * @brief Syncronization and threading interface. * * The Sofia utility library provides simple OS-independent synchronization * interface. The synchronization interface contains primitives for managing * events, messages, timers and threads. * *//**@ingroup su_wait * @defgroup su_root_ex Example and test code for syncronization and threads * * Example programs demonstrate the su syncronization and threading * primitives. *//**@ingroup su_wait * * @page su_wait_t Wait objects * *   Wait objects are used to signal I/O events to the process. *   The events are as follows: * *   - SU_WAIT_IN       - incoming data is available on socket *   - SU_WAIT_OUT      - data can be sent on socket *   - SU_WAIT_ERR      - an error occurred on socket *   - SU_WAIT_HUP      - the socket connection was closed *   - SU_WAIT_ACCEPT   - a listening socket accepted a new connection attempt * *   It is possible to combine several events with |, binary or operator. * *   The wait objects can be managed with functions as follows: *   - su_wait_create() *   - su_wait_destroy() *   - su_wait() *   - su_wait_events() *   - su_wait_mask() * * @note *   In Unix, the wait object is @c struct @c poll. The structure contains a *   file descriptor, a mask describing expected events, and a mask *   containing the occurred events after calling @c su_wait(), ie. poll(). * * @note *   In Windows, the wait object is a @c HANDLE (a descriptor of a Windows *   kernel entity). * *//**Initialize a wait object. * * The function su_wait_init initializes a memory area of a su_wait_t * object. */void su_wait_init(su_wait_t dst[1]){  su_wait_t const src = SU_WAIT_INIT;  *dst = src;}/**Create a wait object. * * The function su_wait_create() creates a new su_wait_t object for an @a * socket, with given @a events.  The new wait object is assigned to the @a * newwait parameter. *  * @param newwait  the newly created wait object (output) * @param socket   socket * @param events   mask for events that can signal this wait object *  * @retval 0 if the call was successful, * @retval -1 upon an error.  */int su_wait_create(su_wait_t *newwait, su_socket_t socket, int events){#if SU_HAVE_WINSOCK  HANDLE h = WSACreateEvent();  if (newwait == NULL || events == 0 || socket == INVALID_SOCKET) {    su_seterrno(WSAEINVAL);    return -1;  }  *newwait = 0;  if (WSAEventSelect(socket, h, events) != 0) {    int error = su_errno();    WSACloseEvent(h);    su_seterrno(error);    return -1;  }  *newwait = h;#elif SU_HAVE_POLL  if (newwait == NULL || events == 0 || socket == INVALID_SOCKET) {    su_seterrno(EINVAL);    return -1;  }  newwait->fd = socket;  newwait->events = events;  newwait->revents = 0;#endif  return 0;}/** Destroy a wait object. * * The function su_wait_destroy() destroys a su_wait_t object. * * @param waitobj  pointer to wait object    * * @retval 0 when successful, * @retval -1 upon an error. */int su_wait_destroy(su_wait_t *waitobj){#if SU_HAVE_WINSOCK  su_wait_t w0 = NULL;  if (*waitobj)    WSACloseEvent(*waitobj);#elif SU_HAVE_POLL  su_wait_t w0 = { INVALID_SOCKET, 0, 0 };#endif  assert(waitobj != NULL);  *waitobj = w0;  return waitobj ? 0 : -1;}/**Wait for multiple events. * * The function su_wait() blocks until a event specified by wait objects in * @a wait array.  If @a timeout is not SU_WAIT_FOREVER, a timeout occurs * after @a timeout milliseconds. *  * In Unix, this is @c poll() or @c select(). *  * In Windows, this is @c WSAWaitForMultipleEvents(). *  * @param waits    array of wait objects * @param n        number of wait objects in array waits * @param timeout  timeout in milliseconds * * @retval Index of the signaled wait object, if any, * @retval SU_WAIT_TIMEOUT if timeout occurred, or * @retval -1 upon an error. */int su_wait(su_wait_t waits[], unsigned n, su_duration_t timeout){#if SU_HAVE_WINSOCK  DWORD i;  if (n > 0)    i = WSAWaitForMultipleEvents(n, waits, FALSE, timeout, FALSE);  else    return Sleep(timeout), SU_WAIT_TIMEOUT;  if (i == WSA_WAIT_TIMEOUT)    return SU_WAIT_TIMEOUT;  else if (i == WSA_WAIT_FAILED)    return SOCKET_ERROR;  else    return i;#elif SU_HAVE_POLL  for (;;) {    int i = poll(waits, n, timeout);    if (i == 0)      return SU_WAIT_TIMEOUT;    if (i > 0) {      for (i = 0; i < n; i++) {	if (waits[i].revents)	  return i;      }    }      if (errno == EINTR)      continue;    return i;  }  #endif}/** Get events. *  *   The function su_wait_events() returns an mask describing events occurred. * * @param waitobj  pointer to wait object    * @param s        socket * * @return Binary mask describing the events. */int su_wait_events(su_wait_t *waitobj, su_socket_t s){#if SU_HAVE_WINSOCK  WSANETWORKEVENTS net_events;  if (WSAEnumNetworkEvents(s, *waitobj, &net_events) != 0)    return SOCKET_ERROR;  return net_events.lNetworkEvents;#elif SU_HAVE_POLL  /* poll(e, 1, 0); */  return waitobj->revents;#endif}/** Set event mask. *  *   The function su_wait_mask() sets the mask describing events that can *   signal the wait object. * * @param waitobj  pointer to wait object    * @param s        socket * @param events   new event mask * * @retval  0 when successful,  * @retval -1 upon an error. */int su_wait_mask(su_wait_t *waitobj, su_socket_t s, int events){#if SU_HAVE_WINSOCK  HANDLE e = *waitobj;  if (WSAEventSelect(s, e, events) != 0) {    int error = WSAGetLastError();    WSACloseEvent(e);    WSASetLastError(error);    return -1;  }#elif SU_HAVE_POLL  waitobj->fd = s;  waitobj->events = events;  waitobj->revents = 0;#endif  return 0;}

⌨️ 快捷键说明

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