📄 select.c
字号:
/***********************************************************************//* *//* Module: select.c *//* Release: 2001.3 *//* Version: 99.0 *//* Purpose: select() implementation *//* *//*---------------------------------------------------------------------*//* *//* Copyright 1999, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "../tcp_ipp.h"/***********************************************************************//* Symbol Definitions *//***********************************************************************/#define TESTING 0#define RETURNING 1/***********************************************************************//* Macro Definitions *//***********************************************************************/#define Us2Ticks(us) ((us) * OsTicksPerSec / 1000000)#define Secs2Ticks(sec) ((sec) * OsTicksPerSec)/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* sock_loop: Sweep over sockets, applying tests to specified set *//* *//* Inputs: numsock = number of sockets to check *//* mode = looking for any match or exclude non-matching *//* reads = socket set to check for nonblocking read *//* writes = socket set to check for nonblocking write *//* excepts = socket set to check for urgent data *//* *//* Returns: TRUE, FALSE, or -1 (error) if testing. Else number of *//* sockets meeting the nonblocking access condition. *//* *//***********************************************************************/static int sock_loop(int numsock, int mode, fd_set *reads, fd_set *writes, fd_set *excepts){ int s, n = 0; int readf, writef, exceptf; /*-------------------------------------------------------------------*/ /* Test each socket. */ /*-------------------------------------------------------------------*/ for (s = 1; s <= numsock; ++s) { SOCKET sock = &Socks[s - 1]; /*-----------------------------------------------------------------*/ /* Clear read, write, and exception flags anew for each socket. */ /*-----------------------------------------------------------------*/ readf = writef = exceptf = FALSE; /*-----------------------------------------------------------------*/ /* Check if read tests requested and requested for this socket. */ /*-----------------------------------------------------------------*/ if (reads && FD_ISSET(s, reads)) { /*---------------------------------------------------------------*/ /* Check for UDP socket. */ /*---------------------------------------------------------------*/ if (sock->type == SOCK_DGRAM) { /*-------------------------------------------------------------*/ /* Set all event bits we would wait for. */ /*-------------------------------------------------------------*/ sock->sel_evnts |= SE_DATA_RCVD | SE_RCV_SHUT | SE_CLOSED; /*-------------------------------------------------------------*/ /* Check for waiting datagram or shutdown for receives. */ /*-------------------------------------------------------------*/ if (sock->rq_head || (sock->flags & SF_RCV_SHUT)) readf = TRUE; } /*---------------------------------------------------------------*/ /* Check for TCP socket passively waiting for connection. */ /*---------------------------------------------------------------*/ else if (sock->state == SS_LISTEN) { /*-------------------------------------------------------------*/ /* Set all event bits we would wait for. */ /*-------------------------------------------------------------*/ sock->sel_evnts |= SE_ACCEPTED | SE_CLOSED; /*-------------------------------------------------------------*/ /* Check if incoming connection is pending. */ /*-------------------------------------------------------------*/ if (sock->lq_head) readf = TRUE; } /*---------------------------------------------------------------*/ /* Else expecting TCP socket with active connection. */ /*---------------------------------------------------------------*/ else { /*-------------------------------------------------------------*/ /* Set all event bits we would wait for. */ /*-------------------------------------------------------------*/ sock->sel_evnts |= SE_CLOSED | SE_DATA_RCVD | SE_GOT_FIN | SE_URGENT | SE_RCV_SHUT; /*-------------------------------------------------------------*/ /* Check if socket is unconnected, has data, received FIN, or */ /* or has been shutdown for receives. */ /*-------------------------------------------------------------*/ if (((sock->flags & SF_CONNECTED) == FALSE) || sock->rb_count || (sock->flags & SF_GOTFIN) || (sock->flags & SF_RCV_SHUT)) { readf = TRUE; } } /*---------------------------------------------------------------*/ /* If testing and any test passed, return TRUE. Else if final */ /* loop and read tests failed, exclude socket from output list. */ /*---------------------------------------------------------------*/ if (mode == TESTING) { if (readf) return TRUE; } else /* mode == RETURNING */ { if (readf == FALSE) FD_CLR(s, reads); } } /*-----------------------------------------------------------------*/ /* Check if write tests requested and requested for this socket. */ /*-----------------------------------------------------------------*/ if (writes && FD_ISSET(s, writes)) { /*---------------------------------------------------------------*/ /* UDP sockets are always ready for a write. */ /*---------------------------------------------------------------*/ if (sock->type == SOCK_DGRAM) { writef = TRUE; } /*---------------------------------------------------------------*/ /* Else checking TCP socket. */ /*---------------------------------------------------------------*/ else { /*-------------------------------------------------------------*/ /* Set all event bits we would wait for. */ /*-------------------------------------------------------------*/ sock->sel_evnts |= SE_CLOSED | SE_DATA_ACKED | SE_SND_SHUT; /*-------------------------------------------------------------*/ /* Check if socket is unconnected, has buffer space, or has */ /* been shutdown for sends. */ /*-------------------------------------------------------------*/ if (((sock->flags & SF_CONNECTED) == FALSE) || (sock->sb_size > sock->sb_count) || (sock->flags & SF_SND_SHUT)) { writef = TRUE; } } /*---------------------------------------------------------------*/ /* If testing and any test passed, return TRUE. Else if final */ /* loop and write test failed, excluded socket from output list. */ /*---------------------------------------------------------------*/ if (mode == TESTING) { if (writef) return TRUE; } else /* mode == RETURNING */ { if (writef == FALSE) FD_CLR(s, writes); } } /*-----------------------------------------------------------------*/ /* Check if OOB tests requested and requested for this socket. */ /*-----------------------------------------------------------------*/ if (excepts && FD_ISSET(s, excepts)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -