1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 ****************************************************************
24 #include <sys/types.h>
25 #if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
34 static struct event
*evs
;
35 static struct event
*tevs
;
36 static struct event
*nextev
;
37 static int calctimeout
;
39 static struct event
*calctimo
__P((void));
40 #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
41 static int sgihack
__P((void));
48 struct event
*evp
, **evpp
;
49 debug3("New event fd %d type %d queued %d\n", ev
->fd
, ev
->type
, ev
->queued
);
53 if (ev
->type
== EV_TIMEOUT
)
58 for (; (evp
= *evpp
); evpp
= &evp
->next
)
59 if (ev
->pri
> evp
->pri
)
70 struct event
*evp
, **evpp
;
71 debug3("Deq event fd %d type %d queued %d\n", ev
->fd
, ev
->type
, ev
->queued
);
75 if (ev
->type
== EV_TIMEOUT
)
80 for (; (evp
= *evpp
); evpp
= &evp
->next
)
87 nextev
= nextev
->next
;
93 struct event
*ev
, *min
;
96 if ((min
= tevs
) == 0)
98 mins
= min
->timeout
.tv_sec
;
99 for (ev
= tevs
->next
; ev
; ev
= ev
->next
)
101 ASSERT(ev
->type
== EV_TIMEOUT
);
102 if (mins
< ev
->timeout
.tv_sec
)
104 if (mins
> ev
->timeout
.tv_sec
|| min
->timeout
.tv_usec
> ev
->timeout
.tv_usec
)
107 mins
= ev
->timeout
.tv_sec
;
118 struct event
*timeoutev
= 0;
119 struct timeval timeout
;
125 timeoutev
= calctimo();
128 gettimeofday(&timeout
, NULL
);
130 timeout
.tv_sec
= timeoutev
->timeout
.tv_sec
- timeout
.tv_sec
;
131 timeout
.tv_usec
= timeoutev
->timeout
.tv_usec
- timeout
.tv_usec
;
132 if (timeout
.tv_usec
< 0)
134 timeout
.tv_usec
+= 1000000;
137 if (timeout
.tv_sec
< 0)
144 debug("waiting for events");
146 debug2(" timeout %d secs %d usecs", timeout
.tv_sec
, timeout
.tv_usec
);
148 for (ev
= evs
; ev
; ev
= ev
->next
)
149 debug3(" - fd %d type %d pri %d\n", ev
->fd
, ev
->type
, ev
->pri
);
151 debug("timed events:\n");
152 for (ev
= tevs
; ev
; ev
= ev
->next
)
153 debug3(" - pri %d sec %d usec %d\n", ev
->pri
, ev
->timeout
.tv_sec
, ev
->timeout
.tv_usec
);
158 for (ev
= evs
; ev
; ev
= ev
->next
)
160 if (ev
->condpos
&& *ev
->condpos
<= (ev
->condneg
? *ev
->condneg
: 0))
162 debug2(" - cond ev fd %d type %d failed\n", ev
->fd
, ev
->type
);
165 if (ev
->type
== EV_READ
)
167 else if (ev
->type
== EV_WRITE
)
173 for (nsel
= 0; nsel
< FD_SETSIZE
; nsel
++)
174 if (FD_ISSET(nsel
, &r
))
178 for (nsel
= 0; nsel
< FD_SETSIZE
; nsel
++)
179 if (FD_ISSET(nsel
, &w
))
184 nsel
= select(FD_SETSIZE
, &r
, &w
, (fd_set
*)0, timeoutev
? &timeout
: (struct timeval
*) 0);
189 #if defined(sgi) && defined(SVR4)
190 if (errno
== EIO
&& sgihack())
193 #if defined(__osf__) || defined(M_UNIX)
194 /* OSF/1 3.x, SCO bug: EBADF */
195 /* OSF/1 4.x bug: EIO */
196 if ((errno
== EIO
|| errno
== EBADF
) && sgihack())
199 Panic(errno
, "select");
203 else if (nsel
== 0) /* timeout */
208 timeoutev
->handler(timeoutev
, timeoutev
->data
);
212 * Sequents select emulation counts a descriptor which is
213 * readable and writeable only as one hit. Waaaaa.
216 nsel
= 2 * FD_SETSIZE
;
219 for (ev
= evs
; ev
; ev
= nextev
)
222 if (ev
->type
!= EV_ALWAYS
)
224 set
= ev
->type
== EV_READ
? &r
: &w
;
225 if (nsel
== 0 || !FD_ISSET(ev
->fd
, set
))
229 if (ev
->condpos
&& *ev
->condpos
<= (ev
->condneg
? *ev
->condneg
: 0))
231 debug2(" + hit ev fd %d type %d!\n", ev
->fd
, ev
->type
);
232 ev
->handler(ev
, ev
->data
);
242 ASSERT(ev
->type
== EV_TIMEOUT
);
243 debug2("event %x new timeout %d ms\n", ev
, timo
);
244 gettimeofday(&ev
->timeout
, NULL
);
245 ev
->timeout
.tv_sec
+= timo
/ 1000;
246 ev
->timeout
.tv_usec
+= (timo
% 1000) * 1000;
247 if (ev
->timeout
.tv_usec
> 1000000)
249 ev
->timeout
.tv_usec
-= 1000000;
250 ev
->timeout
.tv_sec
++;
257 #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
259 extern struct display
*display
, *displays
;
265 debug("IRIX5.2 workaround: searching for bad display\n");
266 for (display
= displays
; display
; )
270 FD_SET(D_userfd
, &r
);
271 FD_SET(D_userfd
, &w
);
272 tv
.tv_sec
= tv
.tv_usec
= 0;
273 if (select(FD_SETSIZE
, &r
, &w
, (fd_set
*)0, &tv
) == -1)
277 Hangup(); /* goodbye display */
280 display
= display
->d_next
;