home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
NETWORK
/
ISP
/
bind.4.8.3.lzh
/
BIND483
/
RES
/
select.c.old
< prev
next >
Wrap
Text File
|
1994-09-22
|
6KB
|
194 lines
/* ------------------------------------------------------------------- *
|
| OS9Lib: select()
|
|
| Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
| Ulli Dessauer, Germering and
| Reimer Mellin, Muenchen
| (W-Germany)
|
| This programm can be copied and distributed freely for any
| non-commercial purposes. It can only be incorporated into
| commercial software with the written permission of the authors.
|
| If you should modify this program, the authors would appreciate
| a notice about the changes. Please send a (context) diff or the
| complete source to:
* ----------------------------------------------------------------- */
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#define READY_SIG (1999)
#define ALM_SIG (2000)
/*#define SEL_PRT_FLG*/
static int sigarrived = 0; /* READY_SIG occurred ? */
static int pid, clk_tck = 0;
extern int ev_id;
static void sighand(sig)
int sig;
{
sigarrived = sig;
}
/*
* S E L E C T
* returns # of fd's ready for read/write/network, -1 if interrupted or
* a bad fd was encountered or 0 if none fd is ready for the action.
*/
int select(fds, rdp, wrp, exp, timeout)
int fds, *wrp;
register int *rdp, *exp;
register struct timeval *timeout;
{
register int i;
register unsigned int shift;
int tout;
register int rd, wr, ex;
int leave = 0;
int tmp = 0;
int signaled = 0;
int alm_id, pollflag;
int ev_value = 0;
if ( clk_tck == 0 ) {
pid = getpid();
clk_tck = CLK_TCK;
}
signal(READY_SIG, sighand);
signal(ALM_SIG, sighand);
/* Calculate the timeout in Ticks .. add one tick (for the polling case)
* if timeout == (struct timeval *)0 set to 0, */
pollflag = timeout && (timeout->tv_sec == 0) && (timeout->tv_usec == 0);
tout = timeout ? (1 + timeout->tv_sec * clk_tck + (timeout->tv_usec *
clk_tck) / 1000000) : 0;
/* set pointers to dummy value if unspecified */
if (rdp == 0)
rdp = &tmp;
if (wrp == 0)
wrp = &tmp;
if (exp == 0)
exp = &tmp;
rd = wr = ex = 0;
sigarrived = 0;
do {
shift = (1 << (fds - 1));
for (i = fds - 1; i >= 0; shift >>= 1, --i) {
/* if data is available for reading mark it as ready */
if (*rdp & shift && (_gs_rdy(i) > 0 || (errno == E_UNKSVC))) {
rd |= shift;
leave++;
}
/* if network condition is ready mark it as ready */
if (*exp & shift && (ev_value > 0)) {
ex |= shift;
leave++;
}
}
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): leave %d ev_id %u\n", pid, leave, ev_id);
#endif
if (pollflag || leave)
break;
/* prepare for waiting .., block signals */
sigmask(1);
shift = (1 << (fds - 1));
for (i = fds - 1; i >= 0; shift >>= 1, --i) {
if (*rdp & shift) {
_ss_ssig(i, READY_SIG);
signaled |= shift;
}
if (*exp & shift)
signaled |= shift;
}
/* wait specified timeout (implicit unblock signal !!) */
if (*exp == 0) {
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): about to sleep %d ticks\n", pid, tout);
#endif
i = tsleep(tout);
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): signal %d\n", pid, sigarrived);
#endif
/* if we are interrupted, or timed-out get out of here */
if (sigarrived == 0) {
if (i < 0) { /* error in tsleep, no clock */
leave = -1;
} else if (i == 0) {/* no ticks left */
if (tout == 0) { /* but..infinite timout was requested */
leave = -1;
errno = EINTR;
} else { /* must have timed out */
leave = 0;
break;
}
} else { /* ticks remain ? pretend interrupt */
leave = -1;
errno = EINTR;
}
break;
}
/* signal arrived, go check data */
} else { /* exp != 0, wait also on network */
if (tout < 2)
tout = 2;
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): about to wait %d ticks\n", pid, tout);
#endif
alm_id = alm_set(ALM_SIG, tout);
ev_value = _ev_wait(ev_id, 1, 32767);
sigmask(0);
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): signal %d event %d\n", \
pid, sigarrived, ev_value);
#endif
alm_delete(alm_id);
if (sigarrived == ALM_SIG) /* time out, leave = 0 */
break;
else if (sigarrived == READY_SIG) /* non-net data present, check */
continue;
else if ( ev_value > 0 ) { /* net data ready */
leave++;
ex = *exp;
} else { /* we were interrupted ... */
leave = -1;
errno = EINTR;
}
} /* *exp != 0, end of wait on network */
} while ( leave == 0 );
/* reset signals .. */
shift = (1 << (fds - 1));
for (i = fds - 1; i >= 0; shift >>= 1, --i)
if (signaled & shift)
_ss_rel(i);
/* get results.. */
*rdp = rd;
*wrp = wr;
*exp = ex;
#ifdef SEL_PRT_FLG
fprintf(stderr, "====== select(%d): results %x %x\n", pid, rd, ex);
#endif
return leave;
}