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

📄 selectlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/* selectLib.c - UNIX BSD 4.3 select library *//* Copyright 1984-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01x,10jul97,dgp  doc: fix SPR 6476, correct no. bits examined by select()01w,09jul97,dgp  doc: add max number of file descripters (SPR 7695)01v,13feb95,jdi  doc tweaks.01u,03feb93,jdi  doc changes based on review by rdc.01t,21jan93,jdi  documentation cleanup for 5.1.01s,23aug92,jcf  added tyLib select stuff here to make tyLib standalone.01r,18jul92,smb  Changed errno.h to errnoLib.h.01q,04jul92,jcf  scalable/ANSI/cleanup effort.01p,26may92,rrr  the tree shuffle01o,10jan92,rdc  Fixed bug in selNodeAdd - release semaphore after malloc error.01n,09jan92,rdc  integrated fix from 5.0.2 that fixed timeout bug in select		 causing incorrect return fdsets.01m,13dec91,gae  ANSI cleanup.01l,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed includes to have absolute path from h/		  -changed VOID to void		  -changed copyright notice01k,01aug91,yao  fixed to pass 6 args to excJobAdd() call.01j,29apr91,hdn  changed how quitTime is calculated to optimize code01i,05apr91,jdi	 documentation -- removed header parens and x-ref numbers;		 doc review by rdc.01h,24mar91,jaa  documentation cleanup.01g,25oct90,dnw  deleted include of utime.h.01f,01aug90,jcf  changed tcb selWakeupNode to pSelWakeupNode.01e,13jul90,rdc  added mechanism to clean up after tasks that get deleted		 while pended in select.01d,26jun90,jcf  changed binary semaphore interface01c,17may90,rdc  changed to use binary sem's and timeouts instead of WDOGS.01b,14apr90,jcf  removed tcb extension dependencies.01a,02jan90,rdc  written.*//*DESCRIPTIONThis library provides a BSD 4.3 compatible \f2select\fP facility to waitfor activity on a set of file descriptors.  selectLib provides a mechanismthat gives a driver the ability to detect pended tasks that are awaitingactivity on the driver's device.  This allows a driver's interrupt serviceroutine to wake up such tasks directly, eliminating the need for polling.The maximum number of file descriptors supported is 256.Applications can use select() with pipes and serial devices, in additionto sockets.  Also, select() examines \f2write\f1 file descriptors in additionto \f2read\f1 file descriptors; however, exception file descriptors remainunsupported.Typically, application developers need concern themselves only with theselect() call.  However, driver developers should become familiar with theother routines that may be used with select(), if they wish to support theselect() mechanism.INCLUDE FILES: selectLib.hSEE ALSO:.pG "I/O System"*/#include "vxWorks.h"#include "ioLib.h"#include "memLib.h"#include "errnoLib.h"#include "vwModNum.h"#include "net/systm.h"#include "semLib.h"#include "logLib.h"#include "string.h"#include "sysLib.h"#include "intLib.h"#include "stdlib.h"#include "taskHookLib.h"#include "selectLib.h"#include "tyLib.h"#include "private/funcBindP.h"/* global variables */int mutexOptionsSelectLib = SEM_Q_FIFO | SEM_DELETE_SAFE;/* forward declarations */void selWakeupAll ();/* forward static functions */LOCAL void selTyAdd (TY_DEV *pTyDev, int arg);LOCAL void selTyDelete (TY_DEV *pTyDev, int arg);LOCAL void selTaskDeleteHook (WIND_TCB *pTcb);LOCAL STATUS selDoIoctls (fd_set *pFdSet, int fdSetWidth, int ioctlFunc,		           SEL_WAKEUP_NODE *pWakeupNode, BOOL stopOnErr);/********************************************************************************* selectInit - initialize the select facility** This routine initializes the UNIX BSD 4.3 select facility.  It should be* called only once, and typically is called from the root task, usrRoot(),* in usrConfig.c.  It installs a task delete hook that cleans up after a* task if the task is deleted while pended in select().** RETURNS: N/A*/void selectInit (void)    {    _func_selTyAdd		= (FUNCPTR) selTyAdd;    _func_selTyDelete		= (FUNCPTR) selTyDelete;    _func_selWakeupAll		= (FUNCPTR) selWakeupAll;    _func_selWakeupListInit	= (FUNCPTR) selWakeupListInit;    if (taskDeleteHookAdd ((FUNCPTR) selTaskDeleteHook) != OK)	{	logMsg ("selectInit: couldn't install task delete hook!\n",		0, 0, 0, 0, 0, 0);	}    }/********************************************************************************* select - pend on a set of file descriptors** This routine permits a task to pend until one of a set of file descriptors* becomes ready.  Three parameters -- <pReadFds>, <pWriteFds>, and* <pExceptFds> -- point to file descriptor sets in which each bit* corresponds to a particular file descriptor.   Bits set in the read file* descriptor set (<pReadFds>) will cause select() to pend until data is* available on any of the corresponding file descriptors, while bits set in* the write file descriptor set (<pWriteFds>) will cause select() to pend* until any of the corresponding file descriptors become writable.  (The* <pExceptFds> parameter is currently unused, but is provided for UNIX call* compatibility.)** The following macros are available for setting the appropriate bits* in the file descriptor set structure:* .CS*     FD_SET(fd, &fdset)*     FD_CLR(fd, &fdset)*     FD_ZERO(&fdset)* .CE** If either <pReadFds> or <pWriteFds> is NULL, they are ignored.  The* <width> parameter defines how many bits will be examined in the file* descriptor sets, and should be set to either the maximum file descriptor* value in use plus one, or simply to FD_SETSIZE.  When select() returns, * it zeros out the file descriptor sets, and sets only the bits that * correspond to file descriptors that are ready.  The FD_ISSET macro may * be used to determine which bits are set.** If <pTimeOut> is NULL, select() will block indefinitely.  If <pTimeOut> is* not NULL, but points to a `timeval' structure with an effective time of* zero, the file descriptors in the file descriptor sets will be polled and* the results returned immediately.  If the effective time value is greater* than zero, select() will return after the specified time has elapsed, even* if none of the file descriptors are ready.** Applications can use select() with pipes and serial devices, in addition* to sockets.  Also, select() now examines write file descriptors in* addition to read file descriptors; however, exception file descriptors* remain unsupported.** Driver developers should consult the * .I "VxWorks Programmer's Guide: I/O System"* for details on writing drivers that will use select().** RETURNS:* The number of file descriptors with activity, 0 if timed out, or* ERROR if an error occurred when the driver's select() routine* was invoked via ioctl().** SEE ALSO:* .pG "I/O System"*/int select    (    int             width,      /* number of bits to examine from 0 */    FAST fd_set    *pReadFds,   /* read fds */    FAST fd_set    *pWriteFds,  /* write fds */    fd_set         *pExceptFds, /* exception fds (unsupported) */    struct timeval *pTimeOut    /* max time to wait, NULL = forever */    )    {    FAST int fd;    FAST int partMask;    SEL_WAKEUP_NODE wakeupNode;    fd_set copyOfReadFds;    fd_set copyOfWriteFds;    int widthInBytes;    int status;    int numFound = 0;    int quitTime = 0;    int clockRate;    if (pReadFds != NULL)	copyOfReadFds = *pReadFds;    else	FD_ZERO (&copyOfReadFds);    if (pWriteFds != NULL)	copyOfWriteFds = *pWriteFds;    else	FD_ZERO (&copyOfWriteFds);    if (pTimeOut != NULL)	{	clockRate = sysClkRateGet ();	/* convert to ticks */	quitTime = (pTimeOut->tv_sec * clockRate) +            ((((pTimeOut->tv_usec * clockRate) / 100)/100)/100);	}    wakeupNode.pReadFds   = pReadFds;    wakeupNode.pWriteFds  = pWriteFds;    wakeupNode.pExceptFds = pExceptFds;    wakeupNode.pOrigReadFds = &copyOfReadFds;    wakeupNode.pOrigWriteFds = &copyOfWriteFds;    wakeupNode.taskId     = taskIdSelf ();    semBInit (&taskIdCurrent->selectSem, SEM_Q_PRIORITY, SEM_EMPTY);    wakeupNode.wakeupSem  = &taskIdCurrent->selectSem;    /* we don't use FD_ZERO to maintain backward compatibility     * with 4.2 select     */    widthInBytes = howmany(width, NFDBITS) * sizeof (fd_mask);    if (pReadFds != NULL)	bzero ((char *)pReadFds, widthInBytes);    if (pWriteFds != NULL)	bzero ((char *)pWriteFds, widthInBytes);    if (pExceptFds != NULL)	bzero ((char *)pExceptFds, widthInBytes);    status = OK;    /* do the read fd's */    if (pReadFds != NULL)	{	wakeupNode.type = SELREAD;	if (selDoIoctls (&copyOfReadFds, width,			 FIOSELECT, &wakeupNode, TRUE) != OK)	    {	    status = ERROR;	    }	}    /* do the write fd's */    if (status != ERROR)	if (pWriteFds != NULL)	    {	    wakeupNode.type = SELWRITE;	    if (selDoIoctls (&copyOfWriteFds, width,			     FIOSELECT, &wakeupNode, TRUE) != OK)		{		status = ERROR;		}	    }    if (status != OK)	{	status = errnoGet ();	wakeupNode.type = SELREAD;	selDoIoctls (&copyOfReadFds, width, FIOUNSELECT, &wakeupNode, FALSE);	wakeupNode.type = SELWRITE;	selDoIoctls (&copyOfWriteFds, width, FIOUNSELECT, &wakeupNode, FALSE);	/* if no select support in driver, inform the naive user */	if (status == S_ioLib_UNKNOWN_REQUEST)	    errnoSet (S_selectLib_NO_SELECT_SUPPORT_IN_DRIVER);	return (ERROR);	}    /* if the user specified a zero quittime, we don't pend.     * a NULL pointer indicates wait for ever     */    if ((pTimeOut != NULL) && (quitTime == 0))	quitTime = NO_WAIT;    else	if (pTimeOut == NULL)	    quitTime = WAIT_FOREVER;    /* stash a pointer to the wake-up node in the task's tcb, so we can     * clean up if the task get's deleted while we're pended in select     */    taskIdCurrent->pSelWakeupNode = &wakeupNode;    semTake (wakeupNode.wakeupSem, quitTime);    /* clean up after ourselves */    /* first the read fd's ... */    status = OK;    if (pReadFds != NULL)	{	wakeupNode.type = SELREAD;	if (selDoIoctls (&copyOfReadFds, width,			 FIOUNSELECT, &wakeupNode, FALSE) != OK)	    {	    status = ERROR;	    }	}    /* ... now the write fd's. */    if (pWriteFds != NULL)	{	wakeupNode.type = SELWRITE;	if (selDoIoctls (&copyOfWriteFds, width,			 FIOUNSELECT, &wakeupNode, FALSE) != OK)	    {	    status = ERROR;	    }	}    /* clear the pointer to the selWakup node in the task's tcb now     * that we're all cleaned up.     */    taskIdCurrent->pSelWakeupNode = NULL;    if (status == ERROR)	return (ERROR);    /* find out how many bits are set in the read and write fd sets */    if (pReadFds != NULL)	for (fd = 0; fd < width; fd++)	    {	    /* look at the fd_set a long word at a time */	    partMask = pReadFds->fds_bits[((unsigned)fd) / NFDBITS];	    if (partMask == 0)		{		fd += NFDBITS - 1;		}	    else if (partMask & (1 << (((unsigned) fd) % NFDBITS)))		{		numFound++;

⌨️ 快捷键说明

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