1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include <sys/types.h>
30 #if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
39 static struct event
*evs
;
40 static struct event
*tevs
;
41 static struct event
*nextev
;
42 static int calctimeout
;
44 static struct event
*calctimo
__P((void));
45 #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
46 static int sgihack
__P((void));
53 struct event
*evp
, **evpp
;
54 debug3("New event fd %d type %d queued %d\n", ev
->fd
, ev
->type
, ev
->queued
);
58 if (ev
->type
== EV_TIMEOUT
)
63 for (; (evp
= *evpp
); evpp
= &evp
->next
)
64 if (ev
->pri
> evp
->pri
)
75 struct event
*evp
, **evpp
;
76 debug3("Deq event fd %d type %d queued %d\n", ev
->fd
, ev
->type
, ev
->queued
);
80 if (ev
->type
== EV_TIMEOUT
)
85 for (; (evp
= *evpp
); evpp
= &evp
->next
)
92 nextev
= nextev
->next
;
98 struct event
*ev
, *min
;
101 if ((min
= tevs
) == 0)
103 mins
= min
->timeout
.tv_sec
;
104 for (ev
= tevs
->next
; ev
; ev
= ev
->next
)
106 ASSERT(ev
->type
== EV_TIMEOUT
);
107 if (mins
< ev
->timeout
.tv_sec
)
109 if (mins
> ev
->timeout
.tv_sec
|| min
->timeout
.tv_usec
> ev
->timeout
.tv_usec
)
112 mins
= ev
->timeout
.tv_sec
;
123 struct event
*timeoutev
= 0;
124 struct timeval timeout
;
130 timeoutev
= calctimo();
133 gettimeofday(&timeout
, NULL
);
135 timeout
.tv_sec
= timeoutev
->timeout
.tv_sec
- timeout
.tv_sec
;
136 timeout
.tv_usec
= timeoutev
->timeout
.tv_usec
- timeout
.tv_usec
;
137 if (timeout
.tv_usec
< 0)
139 timeout
.tv_usec
+= 1000000;
142 if (timeout
.tv_sec
< 0)
149 debug("waiting for events");
151 debug2(" timeout %d secs %d usecs", timeout
.tv_sec
, timeout
.tv_usec
);
153 for (ev
= evs
; ev
; ev
= ev
->next
)
154 debug3(" - fd %d type %d pri %d\n", ev
->fd
, ev
->type
, ev
->pri
);
156 debug("timed events:\n");
157 for (ev
= tevs
; ev
; ev
= ev
->next
)
158 debug3(" - pri %d sec %d usec %d\n", ev
->pri
, ev
->timeout
.tv_sec
, ev
->timeout
.tv_usec
);
163 for (ev
= evs
; ev
; ev
= ev
->next
)
165 if (ev
->condpos
&& *ev
->condpos
<= (ev
->condneg
? *ev
->condneg
: 0))
167 debug2(" - cond ev fd %d type %d failed\n", ev
->fd
, ev
->type
);
170 if (ev
->type
== EV_READ
)
172 else if (ev
->type
== EV_WRITE
)
178 for (nsel
= 0; nsel
< FD_SETSIZE
; nsel
++)
179 if (FD_ISSET(nsel
, &r
))
183 for (nsel
= 0; nsel
< FD_SETSIZE
; nsel
++)
184 if (FD_ISSET(nsel
, &w
))
189 nsel
= select(FD_SETSIZE
, &r
, &w
, (fd_set
*)0, timeoutev
? &timeout
: (struct timeval
*) 0);
194 #if defined(sgi) && defined(SVR4)
195 if (errno
== EIO
&& sgihack())
198 #if defined(__osf__) || defined(M_UNIX)
199 /* OSF/1 3.x, SCO bug: EBADF */
200 /* OSF/1 4.x bug: EIO */
201 if ((errno
== EIO
|| errno
== EBADF
) && sgihack())
204 Panic(errno
, "select");
208 else if (nsel
== 0) /* timeout */
213 timeoutev
->handler(timeoutev
, timeoutev
->data
);
217 * Sequents select emulation counts a descriptor which is
218 * readable and writeable only as one hit. Waaaaa.
221 nsel
= 2 * FD_SETSIZE
;
224 for (ev
= evs
; ev
; ev
= nextev
)
227 if (ev
->type
!= EV_ALWAYS
)
229 set
= ev
->type
== EV_READ
? &r
: &w
;
230 if (nsel
== 0 || !FD_ISSET(ev
->fd
, set
))
234 if (ev
->condpos
&& *ev
->condpos
<= (ev
->condneg
? *ev
->condneg
: 0))
236 debug2(" + hit ev fd %d type %d!\n", ev
->fd
, ev
->type
);
237 ev
->handler(ev
, ev
->data
);
247 ASSERT(ev
->type
== EV_TIMEOUT
);
248 debug2("event %x new timeout %d ms\n", ev
, timo
);
249 gettimeofday(&ev
->timeout
, NULL
);
250 ev
->timeout
.tv_sec
+= timo
/ 1000;
251 ev
->timeout
.tv_usec
+= (timo
% 1000) * 1000;
252 if (ev
->timeout
.tv_usec
> 1000000)
254 ev
->timeout
.tv_usec
-= 1000000;
255 ev
->timeout
.tv_sec
++;
262 #if (defined(sgi) && defined(SVR4)) || defined(__osf__) || defined(M_UNIX)
264 extern struct display
*display
, *displays
;
270 debug("IRIX5.2 workaround: searching for bad display\n");
271 for (display
= displays
; display
; )
275 FD_SET(D_userfd
, &r
);
276 FD_SET(D_userfd
, &w
);
277 tv
.tv_sec
= tv
.tv_usec
= 0;
278 if (select(FD_SETSIZE
, &r
, &w
, (fd_set
*)0, &tv
) == -1)
282 Hangup(); /* goodbye display */
285 display
= display
->d_next
;