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

📄 select.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    PORT           *pprt;
    struct uport   *uprt;
#ifdef PLUS
    NU_TASK     *Task_ID;        /* current task pointer */
#else
    sint         Task_ID;        /* current task id */
#endif
    INT         server_port;
    struct TASK_TABLE_STRUCT   *Task_Entry = NU_NULL;


    /* Preserve the current state of readfs.  It may be needed below. */
    NU_FD_Init(&tmpfs);
    memcpy(&tmpfs, readfs, sizeof(FD_SET));

    for (i = 0; i < max_sockets; i++)
    {
        /* Is the bit for socket i set. */
        if (NU_FD_Check(i, readfs)==NU_NULL)
            continue;

        /*  Pick up a pointer to the socket list. */
        if ((sockptr = socket_list[i]) == NU_NULL)
            continue;

        if (sockptr->protocol == NU_PROTO_TCP)
        {
            /* Check to see if this is a server socket or communication
               socket. */
            if (sockptr->listener == NU_FALSE)
            {
                pnum = NU_GetPnum(sockptr);
                if (pnum<0)
                {
                    NU_FD_Reset(i, readfs);
                    continue;
                }

                pprt = portlist[pnum];
                if ( pprt == NU_NULL ||
                     ((pprt->state != SEST) && (pprt->state != SCWAIT)) )
                {
                    NU_FD_Reset(i, readfs);
                    continue;
                }

                /* verify there are data in and no other task using this socket
                   and make sure no other process accessing it now ! */
#ifdef PLUS                                                                     /* necessary ? */
                if (pprt->RXTask==NU_NULL && (pprt->in.contain>0))
#else  /* PLUS */
                if (pprt->RXTask==NU_SYSTEM || (pprt->in.contain>0))
#endif /* !PLUS */
                    return_status = NU_SUCCESS;
                else
                    NU_FD_Reset(i, readfs);
            }
            else
            {
                /* This is a server socket, acepting connections. */
                /* get the current task id for the next 2 service calls */
#ifdef PLUS
                Task_ID = NU_Current_Task_Pointer();
#else
                Task_ID = NU_Current_Task_ID();
#endif

                /* retrieve the local port number from the socket descriptor
                   for comparison to the task table */
                server_port = sockptr->local_addr.port_num;

                /* search the task table for this port number/task id */
                if ( NU_SearchTaskList(Task_Entry, Task_ID, server_port,
                                        SEST, -1) != NU_NULL)
                    return_status = NU_SUCCESS;
                else
                    NU_FD_Reset(i, readfs);
            }

        } /* end this is a TCP socket. */
        else if (sockptr->protocol == NU_PROTO_UDP)
        {
            if(!sockptr->local_addr.port_num)
            {
                NU_FD_Reset(i, readfs);
                continue;
            }

            if((pnum = NU_Get_UDP_Pnum(sockptr)) == NU_IGNORE_VALUE)
            {
                if ((pnum = makeuport(sockptr->local_addr.port_num)) < 0)
                {
                    NU_FD_Reset(i, readfs);
                    continue;
                }
            }

            uprt = uportlist[pnum];

            if( (uprt->RXTask == NU_NULL) && (uprt->in_dgrams))
                return_status = NU_SUCCESS;
            else
                NU_FD_Reset(i, readfs);

        }  /* end this is a UDP socket */
    } /* for (i=0; i<max_sockets; i++) */

    if(return_status != NU_SUCCESS)
        memcpy(readfs, &tmpfs, sizeof(FD_SET));

    return(return_status);

} /* end SEL_Check_Recv */

/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*  SEL_Setup_Recv_Ports                                                    */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*  This function marks the specified ports so that if data arrives on any  */
/*  of them the current task will be resumed.                               */
/*                                                                          */
/* AUTHOR                                                                   */
/*                                                                          */
/*  Glen Johnson, Accelerated Technology Inc.                               */
/*                                                                          */
/*  CALLED FROM                                                             */
/*                                                                          */
/*      NU_Select                                                           */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*      NU_FD_Check                                                         */
/*      NU_GetPnum                                                          */
/*      NU_Get_UDP_Pnum                                                     */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*      Returns the socket index of the last socket setup.                  */
/*                                                                          */
/* HISTORY                                                                  */
/*                                                                          */
/*  NAME                   DATE        REMARKS                              */
/*                                                                          */
/*  Glen Johnson         11/16/95      Initial version.                     */
/*                                                                          */
/****************************************************************************/
#ifdef PLUS
STATUS SEL_Setup_Recv_Ports(INT max_sockets, FD_SET *readfs, NU_TASK *Task_ID)
#else
INT SEL_Setup_Recv_Ports(INT max_sockets, FD_SET *readfs, int16 Task_ID)
#endif
{
    INT     i;
    int16   pnum;                  /* local machine's port number */
    struct sock_struct *sockptr; /* pointer to current socket */
    PORT           *pprt;
    struct uport   *uprt;
    STATUS          return_status = -1;
    INT                         server_port;
    struct TASK_TABLE_STRUCT    *Task_Entry = NU_NULL;

    /* we need to assign the current thread to each (!!!) port
        we are checking, then NU_EventsDispatcher() could wake up
        this task when any of these ports gets data */
    for (i = 0; i < max_sockets; i++)
    {
        if (NU_FD_Check(i, readfs)==NU_NULL)
            continue;

        if ((sockptr = socket_list[i]) == NU_NULL)
            continue;

        if (sockptr->protocol == NU_PROTO_TCP)
        {
            /* Check to see if this is a server socket or communication
               socket. */
            if (sockptr->listener == NU_FALSE)
            {
                if ((pnum=NU_GetPnum(sockptr)) < 0)
                    continue;
                if ((pprt=portlist[pnum]) == NU_NULL)
                    continue;

                pprt->RXTask = Task_ID;
                return_status = NU_SUCCESS;
            }
            else
            {
                /* retrieve the local port number from the socket descriptor
                   for comparison to the task table */
                server_port = sockptr->local_addr.port_num;

                /* start at the head of the list */
                Task_Entry = Task_Head;

                /* verify that the list is not empty */
                while (Task_Entry != NU_NULL)
                {
                    /* discontinue searching if a match is found */
                    if ((Task_Entry->Task_ID == Task_ID) &&
                      (Task_Entry->local_port_num == server_port))
                    {
                        break;
                    }

                    /* continue checking the next structure */
                    Task_Entry = Task_Entry->next;
                }

                /* If an entry was found, set it up. */
                if (Task_Entry)
                {
                    /* Should the accept flag be set or cleared. */
                    if (Task_ID)
                        Task_Entry->acceptFlag = 1;
                    else
                        Task_Entry->acceptFlag = 0;

                    /* Setup the Task ID field so that this task can be resumed. */
                    Task_Entry->Task_ID = Task_ID;

                    return_status = NU_SUCCESS;
                }
            }
        }
        else if(sockptr->protocol == NU_PROTO_UDP)
        {
            if ((pnum = NU_Get_UDP_Pnum(sockptr)) == NU_IGNORE_VALUE)
                continue;

            if ((uprt = uportlist[pnum]) == NU_NULL)
                continue;

            uprt->RXTask = Task_ID;
            return_status = NU_SUCCESS;
        }
    } /* end for i to max_sockets */

    return (return_status);
} /* SEL_Setup_Recv_Ports */

⌨️ 快捷键说明

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