sched.c (screen-4.8.0) | : | sched.c (screen-4.9.0) | ||
---|---|---|---|---|
skipping to change at line 50 | skipping to change at line 50 | |||
static struct event *tevs; | static struct event *tevs; | |||
static struct event *nextev; | static struct event *nextev; | |||
static int calctimeout; | static int calctimeout; | |||
static struct event *calctimo __P((void)); | static struct event *calctimo __P((void)); | |||
#if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX) | #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX) | |||
static int sgihack __P((void)); | static int sgihack __P((void)); | |||
#endif | #endif | |||
void | void | |||
evenq(ev) | evenq(struct event *ev) | |||
struct event *ev; | ||||
{ | { | |||
struct event *evp, **evpp; | struct event *evp, **evpp; | |||
debug3("New event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued); | debug3("New event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> | |||
if (ev->queued) | queued); | |||
return; | if (ev->queued) | |||
evpp = &evs; | return; | |||
if (ev->type == EV_TIMEOUT) | evpp = &evs; | |||
{ | if (ev->type == EV_TIMEOUT) { | |||
calctimeout = 1; | calctimeout = 1; | |||
evpp = &tevs; | evpp = &tevs; | |||
} | } | |||
for (; (evp = *evpp); evpp = &evp->next) | for (; (evp = *evpp); evpp = &evp->next) | |||
if (ev->pri > evp->pri) | if (ev->pri > evp->pri) | |||
break; | break; | |||
ev->next = evp; | ev->next = evp; | |||
*evpp = ev; | *evpp = ev; | |||
ev->queued = 1; | ev->queued = 1; | |||
} | } | |||
void | void | |||
evdeq(ev) | evdeq(struct event *ev) | |||
struct event *ev; | ||||
{ | { | |||
struct event *evp, **evpp; | struct event *evp, **evpp; | |||
debug3("Deq event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued); | debug3("Deq event fd %d type %d queued %d\n", ev -> fd, ev -> type, ev -> | |||
if (!ev->queued) | queued); | |||
return; | if (!ev->queued) | |||
evpp = &evs; | return; | |||
if (ev->type == EV_TIMEOUT) | evpp = &evs; | |||
{ | if (ev->type == EV_TIMEOUT) { | |||
calctimeout = 1; | calctimeout = 1; | |||
evpp = &tevs; | evpp = &tevs; | |||
} | } | |||
for (; (evp = *evpp); evpp = &evp->next) | for (; (evp = *evpp); evpp = &evp->next) | |||
if (evp == ev) | if (evp == ev) | |||
break; | break; | |||
ASSERT(evp); | ASSERT(evp); | |||
*evpp = ev->next; | *evpp = ev->next; | |||
ev->queued = 0; | ev->queued = 0; | |||
if (ev == nextev) | if (ev == nextev) | |||
nextev = nextev->next; | nextev = nextev->next; | |||
} | } | |||
static struct event * | static struct event * | |||
calctimo() | calctimo() | |||
{ | { | |||
struct event *ev, *min; | struct event *ev, *min; | |||
long mins; | long mins; | |||
if ((min = tevs) == 0) | if ((min = tevs) == 0) | |||
return 0; | return 0; | |||
mins = min->timeout.tv_sec; | mins = min->timeout.tv_sec; | |||
for (ev = tevs->next; ev; ev = ev->next) | for (ev = tevs->next; ev; ev = ev->next) { | |||
{ | ASSERT(ev->type == EV_TIMEOUT); | |||
ASSERT(ev->type == EV_TIMEOUT); | if (mins < ev->timeout.tv_sec) | |||
if (mins < ev->timeout.tv_sec) | continue; | |||
continue; | if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeo | |||
if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_use | ut.tv_usec) { | |||
c) | min = ev; | |||
{ | mins = ev->timeout.tv_sec; | |||
min = ev; | } | |||
mins = ev->timeout.tv_sec; | ||||
} | } | |||
} | return min; | |||
return min; | ||||
} | } | |||
void | void | |||
sched() | sched() | |||
{ | { | |||
struct event *ev; | struct event *ev; | |||
fd_set r, w, *set; | fd_set r, w, *set; | |||
struct event *timeoutev = 0; | struct event *timeoutev = 0; | |||
struct timeval timeout; | struct timeval timeout; | |||
int nsel; | int nsel; | |||
for (;;) | for (;;) { | |||
{ | if (calctimeout) | |||
if (calctimeout) | timeoutev = calctimo(); | |||
timeoutev = calctimo(); | if (timeoutev) { | |||
if (timeoutev) | gettimeofday(&timeout, NULL); | |||
{ | /* tp - timeout */ | |||
gettimeofday(&timeout, NULL); | timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_s | |||
/* tp - timeout */ | ec; | |||
timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec; | timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv | |||
timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec; | _usec; | |||
if (timeout.tv_usec < 0) | ||||
{ | if (timeout.tv_usec < 0) { | |||
timeout.tv_usec += 1000000; | timeout.tv_usec += 1000000; | |||
timeout.tv_sec--; | timeout.tv_sec--; | |||
} | } | |||
if (timeout.tv_sec < 0) | if (timeout.tv_sec < 0) { | |||
{ | timeout.tv_usec = 0; | |||
timeout.tv_usec = 0; | timeout.tv_sec = 0; | |||
timeout.tv_sec = 0; | } | |||
} | } | |||
} | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
debug("waiting for events"); | debug("waiting for events"); | |||
if (timeoutev) | if (timeoutev) | |||
debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeout.tv_usec); | debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeo | |||
debug(":\n"); | ut.tv_usec); | |||
for (ev = evs; ev; ev = ev->next) | debug(":\n"); | |||
debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri); | for (ev = evs; ev; ev = ev->next) | |||
if (tevs) | debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev- | |||
debug("timed events:\n"); | >pri); | |||
for (ev = tevs; ev; ev = ev->next) | if (tevs) | |||
debug3(" - pri %d sec %d usec %d\n", ev->pri, ev->timeout.tv_sec, ev->ti | debug("timed events:\n"); | |||
meout.tv_usec); | for (ev = tevs; ev; ev = ev->next) | |||
#endif | debug3(" - pri %d sec %d usec %d\n", ev->pri, | |||
ev->timeout.tv_sec, ev->timeout.tv_usec); | ||||
FD_ZERO(&r); | #endif | |||
FD_ZERO(&w); | ||||
for (ev = evs; ev; ev = ev->next) | FD_ZERO(&r); | |||
{ | FD_ZERO(&w); | |||
if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) | for (ev = evs; ev; ev = ev->next) { | |||
{ | if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->co | |||
debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type); | ndneg : 0)) { | |||
continue; | debug2(" - cond ev fd %d type %d failed\n", ev->f | |||
} | d, ev->type); | |||
if (ev->type == EV_READ) | continue; | |||
FD_SET(ev->fd, &r); | } | |||
else if (ev->type == EV_WRITE) | if (ev->type == EV_READ) | |||
FD_SET(ev->fd, &w); | FD_SET(ev->fd, &r); | |||
} | else if (ev->type == EV_WRITE) | |||
FD_SET(ev->fd, &w); | ||||
} | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
debug("readfds:"); | debug("readfds:"); | |||
for (nsel = 0; nsel < FD_SETSIZE; nsel++) | for (nsel = 0; nsel < FD_SETSIZE; nsel++) | |||
if (FD_ISSET(nsel, &r)) | if (FD_ISSET(nsel, &r)) | |||
debug1(" %d", nsel); | debug1(" %d", nsel); | |||
debug("\n"); | debug("\n"); | |||
debug("writefds:"); | debug("writefds:"); | |||
for (nsel = 0; nsel < FD_SETSIZE; nsel++) | for (nsel = 0; nsel < FD_SETSIZE; nsel++) | |||
if (FD_ISSET(nsel, &w)) | if (FD_ISSET(nsel, &w)) | |||
debug1(" %d", nsel); | debug1(" %d", nsel); | |||
debug("\n"); | debug("\n"); | |||
#endif | #endif | |||
nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (str | nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeo | |||
uct timeval *) 0); | ut : (struct timeval *)0); | |||
if (nsel < 0) | if (nsel < 0) { | |||
{ | if (errno != EINTR) { | |||
if (errno != EINTR) | ||||
{ | ||||
#if defined(sgi) && defined(SVR4) | #if defined(sgi) && defined(SVR4) | |||
if (errno == EIO && sgihack()) | if (errno == EIO && sgihack()) | |||
continue; | continue; | |||
#endif | #endif | |||
#if defined(__osf__) || defined(M_UNIX) | #if defined(__osf__) || defined(M_UNIX) | |||
/* OSF/1 3.x, SCO bug: EBADF */ | /* OSF/1 3.x, SCO bug: EBADF */ | |||
/* OSF/1 4.x bug: EIO */ | /* OSF/1 4.x bug: EIO */ | |||
if ((errno == EIO || errno == EBADF) && sgihack()) | if ((errno == EIO || errno == EBADF) && sgihack() | |||
continue; | ) | |||
#endif | continue; | |||
Panic(errno, "select"); | #endif | |||
} | Panic(errno, "select"); | |||
nsel = 0; | } | |||
} | nsel = 0; | |||
else if (nsel == 0) /* timeout */ | } else if (nsel == 0) { /* timeout */ | |||
{ | debug("TIMEOUT!\n"); | |||
debug("TIMEOUT!\n"); | ASSERT(timeoutev); | |||
ASSERT(timeoutev); | evdeq(timeoutev); | |||
evdeq(timeoutev); | timeoutev->handler(timeoutev, timeoutev->data); | |||
timeoutev->handler(timeoutev, timeoutev->data); | } | |||
} | ||||
#ifdef SELECT_BROKEN | #ifdef SELECT_BROKEN | |||
/* | /* | |||
* Sequents select emulation counts a descriptor which is | * Sequents select emulation counts a descriptor which is | |||
* readable and writeable only as one hit. Waaaaa. | * readable and writeable only as one hit. Waaaaa. | |||
*/ | */ | |||
if (nsel) | if (nsel) | |||
nsel = 2 * FD_SETSIZE; | nsel = 2 * FD_SETSIZE; | |||
#endif | #endif | |||
for (ev = evs; ev; ev = nextev) | for (ev = evs; ev; ev = nextev) { | |||
{ | nextev = ev->next; | |||
nextev = ev->next; | if (ev->type != EV_ALWAYS) { | |||
if (ev->type != EV_ALWAYS) | set = ev->type == EV_READ ? &r : &w; | |||
{ | if (nsel == 0 || !FD_ISSET(ev->fd, set)) | |||
set = ev->type == EV_READ ? &r : &w; | continue; | |||
if (nsel == 0 || !FD_ISSET(ev->fd, set)) | nsel--; | |||
continue; | } | |||
nsel--; | if (ev->condpos && | |||
} | *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) | |||
if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0)) | continue; | |||
continue; | debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type); | |||
debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type); | ev->handler(ev, ev->data); | |||
ev->handler(ev, ev->data); | } | |||
} | } | |||
} | ||||
} | } | |||
void | void | |||
SetTimeout(ev, timo) | SetTimeout(struct event *ev, int timo) | |||
struct event *ev; | { | |||
int timo; | ASSERT(ev->type == EV_TIMEOUT); | |||
{ | debug2("event %x new timeout %d ms\n", ev, timo); | |||
ASSERT(ev->type == EV_TIMEOUT); | gettimeofday(&ev->timeout, NULL); | |||
debug2("event %x new timeout %d ms\n", ev, timo); | ev->timeout.tv_sec += timo / 1000; | |||
gettimeofday(&ev->timeout, NULL); | ev->timeout.tv_usec += (timo % 1000) * 1000; | |||
ev->timeout.tv_sec += timo / 1000; | ||||
ev->timeout.tv_usec += (timo % 1000) * 1000; | if (ev->timeout.tv_usec > 1000000) { | |||
if (ev->timeout.tv_usec > 1000000) | ev->timeout.tv_usec -= 1000000; | |||
{ | ev->timeout.tv_sec++; | |||
ev->timeout.tv_usec -= 1000000; | } | |||
ev->timeout.tv_sec++; | if (ev->queued) | |||
} | calctimeout = 1; | |||
if (ev->queued) | ||||
calctimeout = 1; | ||||
} | } | |||
#if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX) | #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX) | |||
/* do we still need it? | ||||
@anaumov */ | ||||
extern struct display *display, *displays; | extern struct display *display, *displays; | |||
static int sgihack() | static int | |||
sgihack() | ||||
{ | { | |||
fd_set r, w; | fd_set r, w; | |||
struct timeval tv; | struct timeval tv; | |||
debug("IRIX5.2 workaround: searching for bad display\n"); | debug("IRIX5.2 workaround: searching for bad display\n"); | |||
for (display = displays; display; ) | for (display = displays; display;) { | |||
{ | FD_ZERO(&r); | |||
FD_ZERO(&r); | FD_ZERO(&w); | |||
FD_ZERO(&w); | FD_SET(D_userfd, &r); | |||
FD_SET(D_userfd, &r); | FD_SET(D_userfd, &w); | |||
FD_SET(D_userfd, &w); | tv.tv_sec = tv.tv_usec = 0; | |||
tv.tv_sec = tv.tv_usec = 0; | if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1) { | |||
if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1) | if (errno == EINTR) | |||
{ | continue; | |||
if (errno == EINTR) | Hangup(); /* goodbye display */ | |||
continue; | return 1; | |||
Hangup(); /* goodbye display */ | } | |||
return 1; | display = display->d_next; | |||
} | } | |||
display = display->d_next; | return 0; | |||
} | ||||
return 0; | ||||
} | } | |||
#endif | #endif | |||
End of changes. 19 change blocks. | ||||
201 lines changed or deleted | 192 lines changed or added |