1 /*	$OpenBSD: uthread_kevent.c,v 1.4 2003/10/19 05:27:03 brad Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 Jonathan Lemon <jlemon@flugsvamp.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: uthread_kevent.c,v 1.6 2001/12/08 00:53:37 sobomax Exp $
29  */
30 
31 #include <unistd.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/time.h>
35 #include <sys/event.h>
36 #ifdef _THREAD_SAFE
37 #include <pthread.h>
38 #include "pthread_private.h"
39 
40 int
kevent(int kq,const struct kevent * changelist,int nchanges,struct kevent * eventlist,int nevents,const struct timespec * timeout)41 kevent(int kq, const struct kevent *changelist, int nchanges,
42     struct kevent *eventlist, int nevents, const struct timespec *timeout)
43 {
44 	struct pthread	*curthread = _get_curthread();
45 	struct timespec nullts = { 0, 0 };
46 	int rc;
47 
48 	/* Set the wake up time */
49 	_thread_kern_set_timeout(timeout);
50 
51 	rc = _thread_sys_kevent(kq, changelist, nchanges,
52 	    eventlist, nevents, &nullts);
53 	if (rc == 0 && eventlist != NULL && nevents > 0 && (timeout == NULL ||
54 	    timeout->tv_sec != 0 || timeout->tv_nsec != 0)) {
55 		/* Save the socket file descriptor: */
56 		curthread->data.fd.fd = kq;
57 		curthread->data.fd.fname = __FILE__;
58 		curthread->data.fd.branch = __LINE__;
59 
60 		do {
61 			/* Reset the interrupted and timeout flags: */
62 			curthread->interrupted = 0;
63 			curthread->timeout = 0;
64 
65 			_thread_kern_sched_state(PS_FDR_WAIT,
66 			    __FILE__, __LINE__);
67 
68 			if (curthread->interrupted) {
69 				errno = EINTR;
70 				rc = -1;
71 				break;
72 			}
73 			rc = _thread_sys_kevent(kq, NULL, 0,
74 			    eventlist, nevents, &nullts);
75 		} while (rc == 0 && curthread->timeout == 0);
76 	}
77 	return (rc);
78 }
79 #endif
80