📄 select.c
字号:
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 + -