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

📄 select.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************/
/*                                                                          */
/*       CopyrIght (c)  1993 - 1996 Accelerated Technology, Inc.            */
/*                                                                          */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject */
/* matter of this material.  All manufacturing, reproduction, use and sales */
/* rights pertaining to this subject matter are governed by the license     */
/* agreement.  The recipient of this software implicity accepts the terms   */
/* of the license.                                                          */
/*                                                                          */
/****************************************************************************/
/****************************************************************************/
/*                                                                          */
/* FILENAME                                                 VERSION         */
/*                                                                          */
/*  select.c                                                  3.2           */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*  This file contains those functions associated with the NU_Select        */
/*  service.                                                                */
/*                                                                          */
/* AUTHOR                                                                   */
/*                                                                          */
/*  MQ Qina,           Accelerated Technology Inc.                          */
/*                                                                          */
/* DATA STRUCTURES                                                          */
/*                                                                          */
/*  none                                                                    */
/*                                                                          */
/* FUNCTIONS                                                                */
/*                                                                          */
/*     NU_Select                                                            */
/*     NU_FD_Check                                                          */
/*     NU_FD_Set                                                            */
/*     NU_FD_Init                                                           */
/*     NU_FD_Reset                                                          */
/*     SEL_Check_Recv                                                       */
/*     SEL_Setup_Recv_Ports                                                 */
/*                                                                          */
/* DEPENDENCIES                                                             */
/*                                                                          */
/*                                                                          */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*    NAME              DATE        REMARKS                                 */
/*                                                                          */
/*    MQ Qina         10/06/95      Initial version.                        */
/*    Glen Johnson    07/11/97      Added the ability to select on Accept.  */
/*                                                                          */
/****************************************************************************/
#ifdef PLUS
  #include "nucleus.h"
#else /* PLUS */
  #include "nu_defs.h"
  #include "nu_extr.h"
#endif /* !PLUS */
#include "target.h"
#include "protocol.h"
#include "tcpdefs.h"
#include "socketd.h"
#include "sockext.h"
#include "netevent.h"
#include "externs.h"
#include "data.h"

/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*  NU_Select                                                               */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*  This fuction allows an application to check for data on multiple        */
/*  sockets.  Alternatively multiple server sockets (those that are         */
/*  listening for connections) can be checked for established conections.   */
/*  The calling application can choose to return immediatley, suspend, or   */
/*  specify a timeout.                                                      */
/*                                                                          */
/* AUTHOR                                                                   */
/*                                                                          */
/*  MQ Qian, Accelerated Technology Inc.                                    */
/*                                                                          */
/*  CALLED FROM                                                             */
/*                                                                          */
/*      DNS_Query                                                           */
/*      Applications                                                        */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*      SEL_Check_Recv                                                      */
/*      SEL_Setup_Recv_Ports                                                */
/*      NU_Obtain_Semaphore                                                 */
/*      NU_Release_Semaphore                                                */
/*      Stimerset                                                           */
/*      Stimerunset                                                         */
/*      NU_Current_Task_Pointer                                             */
/*      NU_Suspend                                                          */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*      max_sockets                 Maximum socket to check.                */
/*      readfs                      A bit field indicating which sockets    */
/*                                    to check for data.                    */
/*      writefs                     Not currently used.                     */
/*      exceptfs                    A bit field indicating which sockets    */
/*                                    to check for conections.              */
/*      timeout                     Indicates the timeout desired.  Either  */
/*                                    NU_SUSPEND, NU_NO_SUSPEND, or a       */
/*                                    timeout value.                        */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*      NU_SUCCESS                  Indicates successfull completion        */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*  NAME                   DATE        REMARKS                              */
/*                                                                          */
/*  MQ Qina              10/12/94      Initial version.                     */
/*  MQ Qina              11/07/94      Last modification date               */
/*  Glen Johnson         11/16/95      Modified so that a UDP socket can be */
/*                                     selected on.  Modularized the code.  */
/*                                                                          */
/****************************************************************************/
#ifdef PLUS
STATUS NU_Select(INT max_sockets,
            FD_SET *readfs, FD_SET *writefs, FD_SET *exceptfs, UNSIGNED timeout)
#else
STATUS NU_Select(INT max_sockets,
            FD_SET *readfs, FD_SET *writefs, FD_SET *exceptfs, sint timeout)
#endif
{
    int16 read_flag = 0;
    int16 i, j=0;
    STATUS return_status = NU_NO_DATA;  /* initialized to error status */
    NU_TASK     *Task_ID;

    /*  Clean up warnings.  This parameter is used for socket compatibility
       but we are currently not making any use of it.  */

    if((max_sockets == 0) || (max_sockets > NSOCKETS))
        return(NU_NO_SOCKETS);

    if ( readfs == NU_NULL )
        return(NU_NO_SOCKETS);

    /* Make sure that at least one bit is set. */
    for(i=0; i<FD_ELEMENTS; i++)
    {
        if (readfs && (readfs->words[i] != 0))
        {
            read_flag = 1;
        }
    }

    /* Was at least one bit found to be set in the read group. */
    if ( !read_flag )
        return(NU_NO_SOCKETS);

    while (1)
	{
        /*  Don't let anyone else in until we are through.  */
#ifdef PLUS                                                                     /* necessary ? */
		NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else  /* PLUS */
		NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif /* !PLUS */

        /* Check to see if any of the sockets are data ready.  If so readfs will
           be returned with only the bits associated with the ready sockets set.
           Else readfs will be returned with no bits changed.
        */
        return_status = SEL_Check_Recv(max_sockets, readfs);

        /* If at least one socket was data ready then break out of this while
           loop and return.  Break also if suspension was not desired, or if j =
           1.  Note that j is only set to one if a timeout is desired but not
           unconditional suspension.  If unconditional suspension was specified
           then we will only return when a data ready socket is found, even if
           this task is some how inadvertantly woken up.
         */
#ifdef PLUS
        if ( (return_status == NU_SUCCESS) || (timeout == NU_NO_SUSPEND) || j)
#else
        if ( (return_status == NU_SUCCESS) || (timeout == NU_NO_TIMEOUT) || j)
#endif
			break;

        /* Go ahead and retrieve the current task pointer once.  It is used in
           several places below. */
        Task_ID = NU_Current_Task_Pointer();

        return_status = -1;

        if(read_flag)
#ifdef PLUS
            return_status = SEL_Setup_Recv_Ports(max_sockets, readfs, Task_ID);
#else
            return_status = SEL_Setup_Recv_Ports(max_sockets, readfs,
                                               NU_Current_Task_ID());
#endif
        /* If we did not successfully setup a recv port then get out.
           There is no point in continuing. */
        if ( return_status != NU_SUCCESS )
            break;

#ifdef PLUS
        if (timeout != NU_SUSPEND)
#else
        if (timeout != NU_WAIT_FOREVER)
#endif
        {
            /* Set up the timer to wake us up if the event never occurs. */
            Stimerset(CONCLASS, SELECT, (UNSIGNED)Task_ID, timeout, 0);
            j = 1;
        }

        /* Let others in while we are waiting for the connection. */
#ifdef PLUS
        NU_Release_Semaphore(&TCP_Resource);

        /* suspend the current task until data ready */
        NU_Suspend_Task(Task_ID);
#else
        NU_Release_Resource(TCP_Resource);

        /* suspend the current task until data ready */
        NU_Stop(NU_Current_Task_ID());
#endif

#ifdef PLUS
        if (timeout != NU_SUSPEND)
#else
        if (timeout != NU_WAIT_FOREVER)
#endif
        {
            /* At this point there is no way to tell if we were resumed because
               of a timeout or because the event we are waitting on ocurred.  In
               the former case the event will already be cleared.  Try to clear
               it here anyway. */
            Stimerunset(CONCLASS, SELECT, (UNSIGNED)Task_ID, (int32)1);
        }

        /* We need to clean these RXTask's after waking up */
        if (read_flag)

⌨️ 快捷键说明

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