marignotti/mselect.c

130 lines
2.2 KiB
C
Raw Normal View History

2012-05-08 02:41:13 +00:00
#include "marignotti.h"
#include <gno/kerntool.h>
#include <errno.h>
2012-05-12 01:21:29 +00:00
#include "s16debug.h"
2012-05-08 02:41:13 +00:00
#pragma noroot
#pragma optimize 79
/*
* return value is ignored.
*
*/
static boolean readable(Entry *e)
{
if (e->_SHUT_RD)
return false;
if (e->sr.srState > TCPSESTABLISHED && e->sr.srRcvQueued)
return true;
if (e->sr.srRcvQueued >= e->_RCVLOWAT)
return true;
return false;
}
static boolean writable(Entry *e)
{
if (e->_SHUT_WR)
return false;
if (e->sr.srState != TCPSESTABLISHED)
return false;
if (e->sr.srRcvQueued <= e->_SNDLOWAT)
return true;
return false;
}
static boolean exceptable(Entry *e)
{
switch (e->terr)
{
case tcperrOK:
break;
case tcperrConClosing:
case tcperrClosing:
case tcperrConReset:
if (!e->sr.srRcvQueued)
return true;
break;
}
if (e->sr.srRcvQueued)
return false;
if (e->sr.srNetworkError)
return true;
if (e->sr.srState > TCPSESTABLISHED)
return true;
return false;
}
int mselect(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
{
Word t;
Word terr;
int pid = *(int *)p2;
int flag = *(int *)p3;
*(int *)p3 = 0;
2012-05-12 01:21:29 +00:00
if (Debug > 0)
{
s16_debug_printf("select pid = %5d flag = %d", pid, flag);
}
2012-05-08 02:41:13 +00:00
IncBusy();
terr = TCPIPStatusTCP(e->ipid, &e->sr);
t = _toolErr;
if (t) terr = t;
e->terr = terr;
DecBusy();
if (e->sr.srState == TCPSLISTEN)
{
// for a listen socket, "read" means "accept".
switch (flag)
{
case 0:
if (e->sr.srAcceptCount)
*(int *)p3 = 1;
break;
}
}
else
{
switch (flag)
{
case 0:
// readable.
*(int *)p3 = readable(e);
break;
case 1:
// writable.
*(int *)p3 = writable(e);
break;
case 2:
// exception.
*(int *)p3 = exceptable(e);
break;
}
}
return 0;
}