14
14
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
15
*/
16
16
17
+ # define _GNU_SOURCE
18
+ # include <poll.h>
17
19
#include "../common/private.h"
18
20
19
21
//XXX-FIXME TEMP
@@ -90,25 +92,37 @@ linux_kevent_wait_hires(
90
92
struct kqueue * kq ,
91
93
const struct timespec * timeout )
92
94
{
93
- fd_set fds ;
94
95
int n ;
96
+ #if HAVE_DECL_PPOLL
97
+ struct pollfd fds ;
98
+
99
+ dbg_printf ("waiting for events (timeout=%ld sec %ld nsec)" ,
100
+ timeout -> tv_sec , timeout -> tv_nsec );
101
+ fds .fd = kqueue_epfd (kq );
102
+ fds .events = POLLIN ;
103
+
104
+ n = ppoll (& fds , 1 , timeout , NULL );
105
+ #else
95
106
int epfd ;
107
+ fd_set fds ;
96
108
97
109
dbg_printf ("waiting for events (timeout=%ld sec %ld nsec)" ,
98
110
timeout -> tv_sec , timeout -> tv_nsec );
111
+
99
112
epfd = kqueue_epfd (kq );
100
113
FD_ZERO (& fds );
101
114
FD_SET (epfd , & fds );
102
115
n = pselect (epfd + 1 , & fds , NULL , NULL , timeout , NULL );
116
+ #endif
117
+
103
118
if (n < 0 ) {
104
119
if (errno == EINTR ) {
105
120
dbg_puts ("signal caught" );
106
121
return (-1 );
107
122
}
108
- dbg_perror ("pselect(2)" );
123
+ dbg_perror ("ppoll(2) or pselect(2)" );
109
124
return (-1 );
110
125
}
111
-
112
126
return (n );
113
127
}
114
128
@@ -120,25 +134,27 @@ linux_kevent_wait(
120
134
{
121
135
int timeout , nret ;
122
136
123
- /* Use pselect() if the timeout value is less than one millisecond. */
124
- if (ts != NULL && ts -> tv_sec == 0 && ts -> tv_nsec < 1000000 ) {
137
+ /* Use a high-resolution syscall if the timeout value is less than one millisecond. */
138
+ if (ts != NULL && ts -> tv_sec == 0 && ts -> tv_nsec > 0 && ts -> tv_nsec < 1000000 ) {
125
139
nret = linux_kevent_wait_hires (kq , ts );
140
+ if (nret <= 0 )
141
+ return (nret );
126
142
127
- /* Otherwise, use epoll_wait() directly */
143
+ /* epoll_wait() should have ready events */
144
+ timeout = 0 ;
128
145
} else {
129
-
130
146
/* Convert timeout to the format used by epoll_wait() */
131
147
if (ts == NULL )
132
148
timeout = -1 ;
133
149
else
134
150
timeout = (1000 * ts -> tv_sec ) + (ts -> tv_nsec / 1000000 );
151
+ }
135
152
136
- dbg_puts ("waiting for events" );
137
- nret = epoll_wait (kqueue_epfd (kq ), & epevt [0 ], nevents , timeout );
138
- if (nret < 0 ) {
139
- dbg_perror ("epoll_wait" );
140
- return (-1 );
141
- }
153
+ dbg_puts ("waiting for events" );
154
+ nret = epoll_wait (kqueue_epfd (kq ), & epevt [0 ], nevents , timeout );
155
+ if (nret < 0 ) {
156
+ dbg_perror ("epoll_wait" );
157
+ return (-1 );
142
158
}
143
159
144
160
return (nret );
@@ -157,7 +173,6 @@ linux_kevent_copyout(struct kqueue *kq, int nready,
157
173
for (i = 0 ; i < nready ; i ++ ) {
158
174
ev = & epevt [i ];
159
175
kn = (struct knote * ) ev -> data .ptr ;
160
- knote_lock (kn );
161
176
filt = & kq -> kq_filt [~(kn -> kev .filter )];
162
177
rv = filt -> kf_copyout (eventlist , kn , ev );
163
178
if (slowpath (rv < 0 )) {
@@ -174,8 +189,6 @@ linux_kevent_copyout(struct kqueue *kq, int nready,
174
189
knote_disable (filt , kn ); //FIXME: Error checking
175
190
if (eventlist -> flags & EV_ONESHOT ) {
176
191
knote_delete (filt , kn ); //FIXME: Error checking
177
- } else {
178
- knote_unlock (kn );
179
192
}
180
193
181
194
/* If an empty kevent structure is returned, the event is discarded. */
@@ -196,7 +209,8 @@ linux_eventfd_init(struct eventfd *e)
196
209
{
197
210
int evfd ;
198
211
199
- if ((evfd = eventfd (0 , 0 )) < 0 ) {
212
+ evfd = eventfd (0 , 0 );
213
+ if (evfd < 0 ) {
200
214
dbg_perror ("eventfd" );
201
215
return (-1 );
202
216
}
@@ -295,8 +309,7 @@ linux_get_descriptor_type(struct knote *kn)
295
309
dbg_perror ("fstat(2)" );
296
310
return (-1 );
297
311
}
298
- if (! S_ISSOCK (sb .st_mode )) {
299
- //FIXME: could be a pipe, device file, or other non-regular file
312
+ if (S_ISREG (sb .st_mode )) {
300
313
kn -> kn_flags |= KNFL_REGULAR_FILE ;
301
314
dbg_printf ("fd %d is a regular file\n" , (int )kn -> kev .ident );
302
315
return (0 );
@@ -305,6 +318,9 @@ linux_get_descriptor_type(struct knote *kn)
305
318
/*
306
319
* Test if the socket is active or passive.
307
320
*/
321
+ if (! S_ISSOCK (sb .st_mode ))
322
+ return (0 );
323
+
308
324
slen = sizeof (lsock );
309
325
lsock = 0 ;
310
326
i = getsockopt (kn -> kev .ident , SOL_SOCKET , SO_ACCEPTCONN , (char * ) & lsock , & slen );
0 commit comments