17
17
│ PERFORMANCE OF THIS SOFTWARE. │
18
18
╚─────────────────────────────────────────────────────────────────────────────*/
19
19
#include "libc/calls/internal.h"
20
+ #include "libc/calls/sig.internal.h"
20
21
#include "libc/calls/state.internal.h"
21
22
#include "libc/calls/struct/sigset.h"
22
23
#include "libc/calls/struct/sigset.internal.h"
25
26
#include "libc/calls/syscall_support-nt.internal.h"
26
27
#include "libc/intrin/atomic.h"
27
28
#include "libc/intrin/fds.h"
29
+ #include "libc/intrin/weaken.h"
28
30
#include "libc/macros.h"
29
31
#include "libc/nt/console.h"
30
32
#include "libc/nt/enum/filetype.h"
41
43
#include "libc/sock/internal.h"
42
44
#include "libc/sock/struct/pollfd.h"
43
45
#include "libc/sysv/consts/o.h"
46
+ #include "libc/sysv/consts/sicode.h"
44
47
#include "libc/sysv/errfuns.h"
45
48
#include "libc/thread/posixthread.internal.h"
46
49
#ifdef __x86_64__
@@ -84,7 +87,7 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
84
87
struct PosixThread * pt ;
85
88
int i , rc , ev , kind , gotsocks ;
86
89
struct sys_pollfd_nt sockfds [64 ];
87
- uint32_t cm , fi , wi , sn , pn , avail , waitfor , already_slept ;
90
+ uint32_t cm , fi , sn , pn , avail , waitfor , already_slept ;
88
91
89
92
// ensure revents is cleared
90
93
for (i = 0 ; i < nfds ; ++ i )
@@ -228,22 +231,36 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
228
231
// this ensures low latency for apps like emacs which with no sock
229
232
// here we shall actually report that something can be written too
230
233
if (!already_slept ) {
231
- if (__sigcheck (waitmask , false))
232
- return -1 ;
234
+ intptr_t sigev ;
235
+ if (!(sigev = CreateEvent (0 , 0 , 0 , 0 )))
236
+ return __winerr ();
237
+ filehands [pn ] = sigev ;
233
238
pt = _pthread_self ();
234
- filehands [pn ] = pt -> pt_event = CreateEvent (0 , 0 , 0 , 0 );
239
+ pt -> pt_event = sigev ;
240
+ pt -> pt_blkmask = waitmask ;
235
241
atomic_store_explicit (& pt -> pt_blocker , PT_BLOCKER_EVENT ,
236
242
memory_order_release );
237
- wi = WaitForMultipleObjects (pn + 1 , filehands , 0 , waitfor );
243
+ //!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!//
244
+ int sig = 0 ;
245
+ uint32_t wi = pn ;
246
+ if (!_is_canceled () &&
247
+ !(_weaken (__sig_get ) && (sig = _weaken (__sig_get )(waitmask ))))
248
+ wi = WaitForMultipleObjects (pn + 1 , filehands , 0 , waitfor );
249
+ //!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!/!//
238
250
atomic_store_explicit (& pt -> pt_blocker , 0 , memory_order_release );
239
- CloseHandle (filehands [ pn ] );
240
- if (wi == -1u ) {
251
+ CloseHandle (sigev );
252
+ if (wi == -1u )
241
253
// win32 wait failure
242
254
return __winerr ();
243
- } else if (wi == pn ) {
255
+ if (wi == pn ) {
244
256
// our signal event was signalled
245
- if (__sigcheck (waitmask , false))
257
+ int handler_was_called = 0 ;
258
+ if (sig )
259
+ handler_was_called = _weaken (__sig_relay )(sig , SI_KERNEL , waitmask );
260
+ if (_check_cancel () == -1 )
246
261
return -1 ;
262
+ if (handler_was_called )
263
+ return eintr ();
247
264
} else if ((wi ^ kNtWaitAbandoned ) < pn ) {
248
265
// this is possibly because a process or thread was killed
249
266
fds [fileindices [wi ^ kNtWaitAbandoned ]].revents = POLLERR_ ;
@@ -287,8 +304,6 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
287
304
} else {
288
305
// should only be possible on kNtWaitTimeout or semaphore abandoned
289
306
// keep looping for events and we'll catch timeout when appropriate
290
- if (__sigcheck (waitmask , false))
291
- return -1 ;
292
307
}
293
308
}
294
309
@@ -306,6 +321,13 @@ textwindows static int sys_poll_nt_impl(struct pollfd *fds, uint64_t nfds,
306
321
uint32_t waitms ;
307
322
int i , n , rc , got = 0 ;
308
323
324
+ // we normally don't check for signals until we decide to wait, since
325
+ // it's nice to have functions like write() be unlikely to EINTR, but
326
+ // ppoll is a function where users are surely thinking about signals,
327
+ // since ppoll actually allows them to block signals everywhere else.
328
+ if (__sigcheck (waitmask , false))
329
+ return -1 ;
330
+
309
331
// fast path
310
332
if (nfds <= 63 )
311
333
return sys_poll_nt_actual (fds , nfds , deadline , waitmask );
0 commit comments