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