home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
memacs400_src.lzh
/
MEMACS400
/
SRC
/
select.c
< prev
next >
Wrap
Text File
|
1993-01-16
|
4KB
|
139 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 <errno.h>
#include <signal.h>
#define reg register
#define READY_SIG (31) /* tune this ... */
#define ONLYRDY (1) /* select only on reading */
static char sigarrived = 0; /* READY_SIG occured ? */
static void
sighand()
{
sigarrived = 1;
}
/*
* S E L E C T
* returns # of fd's ready for read/write/exeption, -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;
reg int *rdp, *wrp, *exp;
struct timeval *timeout;
{
reg int i;
reg unsigned int shift;
int tout;
reg int rd, wr, ex;
int leave = 0;
int tmp = 0;
int signaled = 0;
signal( READY_SIG, sighand);
/* Calculate the timeout in Ticks ..
* add one tick (for the polling case)
* if timeout == (struct timeval *)0 set to 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;
while( leave == 0) {
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++;
}
#ifndef ONLYRDY
/* if data is available for writing mark it as ready */
if( *wrp & shift && ( _gs_wrdy(i) > 0 || (errno == E_UNKSVC))) {
wr |= shift;
leave++;
}
/* if exeption condition is ready mark it as ready */
if( *exp & shift && ( _gs_erdy(i) > 0 || (errno == E_UNKSVC))) {
ex |= shift;
leave++;
}
#endif
}
if( leave == 0) {
/* 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;
}
#ifndef ONLYRDY
if( *wrp & shift) {
_ss_wssig(i, READY_SIG);
signaled |= shift;
}
if( *exp & shift) {
_ss_essig(i, READY_SIG);
signaled |= shift;
}
#endif
}
/* wait specified timeout (implicit unblock signal !!) */
i = tsleep(tout);
/* if we are interupted, or timed-out get out of here */
if( sigarrived == 0) {
if( i < 0)
leave = -1;
break;
}
}
}
/* 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;
return leave;
}