1 /* $OpenBSD: uthread_poll.c,v 1.11 2004/11/30 00:14:51 pat Exp $ */
2 /*
3 * Copyright (c) 1999 Daniel Eischen <eischen@vigrid.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Daniel Eischen.
17 * 4. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: uthread_poll.c,v 1.4 1999/08/30 00:02:08 deischen Exp $
34 */
35 #include <unistd.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <poll.h>
39 #include <sys/types.h>
40 #include <sys/time.h>
41 #include <sys/fcntl.h>
42 #ifdef _THREAD_SAFE
43 #include <pthread.h>
44 #include "pthread_private.h"
45
46
47 int
poll(struct pollfd fds[],nfds_t nfds,int timeout)48 poll(struct pollfd fds[], nfds_t nfds, int timeout)
49 {
50 struct pthread *curthread = _get_curthread();
51 struct timespec ts;
52 nfds_t n, numfds = nfds;
53 int ret = 0;
54 struct pthread_poll_data data;
55
56 /* This is a cancellation point: */
57 _thread_enter_cancellation_point();
58
59 if (numfds > (nfds_t)_thread_dtablesize) {
60 numfds = _thread_dtablesize;
61 }
62 /* Check if a timeout was specified: */
63 if (timeout == INFTIM) {
64 /* Wait for ever: */
65 _thread_kern_set_timeout(NULL);
66 } else if (timeout > 0) {
67 /* Convert the timeout in msec to a timespec: */
68 ts.tv_sec = timeout / 1000;
69 ts.tv_nsec = (timeout % 1000) * 1000000;
70
71 /* Set the wake up time: */
72 _thread_kern_set_timeout(&ts);
73 } else if (timeout < 0) {
74 /* a timeout less than zero but not == INFTIM is invalid */
75 errno = EINVAL;
76 _thread_leave_cancellation_point();
77 return (-1);
78 }
79
80 if (((ret = _thread_sys_poll(fds, numfds, 0)) == 0) && (timeout != 0)) {
81 data.nfds = numfds;
82 data.fds = fds;
83
84 /*
85 * Clear revents in case of a timeout which leaves fds
86 * unchanged:
87 */
88 for (n = 0; n < numfds; n++) {
89 fds[n].revents = 0;
90 }
91
92 curthread->data.poll_data = &data;
93 curthread->interrupted = 0;
94 _thread_kern_sched_state(PS_POLL_WAIT, __FILE__, __LINE__);
95 if (curthread->interrupted) {
96 errno = EINTR;
97 ret = -1;
98 } else {
99 ret = data.nfds;
100 }
101 }
102
103 /* No longer in a cancellation point: */
104 _thread_leave_cancellation_point();
105
106 return (ret);
107 }
108 #endif
109