ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-AIO/schmorp.h
(Generate patch)

Comparing IO-AIO/schmorp.h (file contents):
Revision 1.5 by root, Wed Jul 15 01:36:04 2009 UTC vs.
Revision 1.9 by root, Wed Aug 5 11:47:56 2009 UTC

4/* WARNING 4/* WARNING
5 * This header file is a shared resource between many modules. 5 * This header file is a shared resource between many modules.
6 */ 6 */
7 7
8#include <signal.h> 8#include <signal.h>
9#include <errno.h>
9 10
10#ifndef _WIN32 11#ifndef _WIN32
11# include <poll.h> 12# include <poll.h>
12#endif 13#endif
13 14
19 (PERL_REVISION > (a) \ 20 (PERL_REVISION > (a) \
20 || (PERL_REVISION == (a) \ 21 || (PERL_REVISION == (a) \
21 && (PERL_VERSION > (b) \ 22 && (PERL_VERSION > (b) \
22 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c))))) 23 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c)))))
23 24
25#ifndef PERL_MAGIC_ext
26# define PERL_MAGIC_ext '~'
27#endif
28
24#if !PERL_VERSION_ATLEAST (5,6,0) 29#if !PERL_VERSION_ATLEAST (5,6,0)
25# ifndef PL_ppaddr 30# ifndef PL_ppaddr
26# define PL_ppaddr ppaddr 31# define PL_ppaddr ppaddr
27# endif 32# endif
28# ifndef call_sv 33# ifndef call_sv
193 S_GENSUB_ARG = arg; 198 S_GENSUB_ARG = arg;
194 199
195 return newRV_noinc ((SV *)cv); 200 return newRV_noinc ((SV *)cv);
196} 201}
197 202
203/*****************************************************************************/
198/** portable pipe/socketpair */ 204/* portable pipe/socketpair */
199 205
200#ifdef USE_SOCKETS_AS_HANDLES 206#ifdef USE_SOCKETS_AS_HANDLES
201# define S_TO_SOCKET(x) (win32_get_osfhandle (x)) 207# define S_TO_HANDLE(x) ((HANDLE)win32_get_osfhandle (x))
202#else 208#else
203# define S_TO_SOCKET(x) (x) 209# define S_TO_HANDLE(x) ((HANDLE)x)
204#endif 210#endif
205 211
206#ifdef _WIN32 212#ifdef _WIN32
207/* taken almost verbatim from libev's ev_win32.c */ 213/* taken almost verbatim from libev's ev_win32.c */
208/* oh, the humanity! */ 214/* oh, the humanity! */
209static int 215static int
210s_pipe (int filedes [2]) 216s_pipe (int filedes [2])
211{ 217{
218 dTHX;
219
212 struct sockaddr_in addr = { 0 }; 220 struct sockaddr_in addr = { 0 };
213 int addr_size = sizeof (addr); 221 int addr_size = sizeof (addr);
214 struct sockaddr_in adr2; 222 struct sockaddr_in adr2;
215 int adr2_size = sizeof (adr2); 223 int adr2_size = sizeof (adr2);
216 SOCKET listener; 224 SOCKET listener;
291#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes) 299#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes)
292 300
293static int 301static int
294s_fd_blocking (int fd, int blocking) 302s_fd_blocking (int fd, int blocking)
295{ 303{
296 blocking = !blocking; 304 u_long nonblocking = !blocking;
297 305
298 return ioctlsocket (S_TO_SOCKET (fd), FIONBIO, &blocking); 306 return ioctlsocket ((SOCKET)S_TO_HANDLE (fd), FIONBIO, &nonblocking);
299} 307}
300 308
301#define s_fd_prepare(fd) s_fd_blocking (fd, 0) 309#define s_fd_prepare(fd) s_fd_blocking (fd, 0)
302 310
303#else 311#else
335#endif 343#endif
336 344
337typedef struct { 345typedef struct {
338 int fd[2]; /* read, write fd, might be equal */ 346 int fd[2]; /* read, write fd, might be equal */
339 int len; /* write length (1 pipe/socket, 8 eventfd) */ 347 int len; /* write length (1 pipe/socket, 8 eventfd) */
340 volatile sig_atomic_t sent;
341} s_epipe; 348} s_epipe;
342 349
343static int 350static int
344s_epipe_new (s_epipe *epp) 351s_epipe_new (s_epipe *epp)
345{ 352{
358 return -1; 365 return -1;
359 366
360 if (s_fd_prepare (ep.fd [0]) 367 if (s_fd_prepare (ep.fd [0])
361 || s_fd_prepare (ep.fd [1])) 368 || s_fd_prepare (ep.fd [1]))
362 { 369 {
370 dTHX;
371
363 close (ep.fd [0]); 372 close (ep.fd [0]);
364 close (ep.fd [1]); 373 close (ep.fd [1]);
365 return -1; 374 return -1;
366 } 375 }
367 376
368 ep.len = 1; 377 ep.len = 1;
369 } 378 }
370 379
371 ep.sent = 0;
372 *epp = ep; 380 *epp = ep;
373 return 0; 381 return 0;
374} 382}
375 383
376static void 384static void
377s_epipe_destroy (s_epipe *epp) 385s_epipe_destroy (s_epipe *epp)
378{ 386{
387 dTHX;
388
379 close (epp->fd [0]); 389 close (epp->fd [0]);
380 390
381 if (epp->fd [1] != epp->fd [0]) 391 if (epp->fd [1] != epp->fd [0])
382 close (epp->fd [1]); 392 close (epp->fd [1]);
383 393
385} 395}
386 396
387static void 397static void
388s_epipe_signal (s_epipe *epp) 398s_epipe_signal (s_epipe *epp)
389{ 399{
390 if (epp->sent)
391 return;
392
393 epp->sent = 1;
394#ifdef _WIN32 400#ifdef _WIN32
395 send (epp->fd [1], epp, 1); 401 /* perl overrides send with a function that crashes in other threads.
402 * unfortunately, it overrides it with an argument-less macro, so
403 * there is no way to force usage of the real send function.
404 * incompetent windows programmers - is this redundant?
405 */
406 DWORD dummy;
407 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0);
396#else 408#else
397 static uint64_t counter = 1; 409 static uint64_t counter = 1;
410 /* some modules accept fd's from outside, support eventfd here */
411 if (write (epp->fd [1], &counter, epp->len) < 0
412 && errno == EINVAL
413 && epp->len != 8)
398 write (epp->fd [1], &counter, epp->len); 414 write (epp->fd [1], &counter, (epp->len = 8));
399#endif 415#endif
400} 416}
401 417
402static void 418static void
403s_epipe_drain (s_epipe *epp) 419s_epipe_drain (s_epipe *epp)
404{ 420{
421 dTHX;
405 char buf [9]; 422 char buf [9];
406 423
407#ifdef _WIN32 424#ifdef _WIN32
408 PerlSock_recv (epp->fd [0], buf, sizeof (buf), 0); 425 recv (epp->fd [0], buf, sizeof (buf), 0);
409#else 426#else
410 read (epp->fd [0], buf, sizeof (buf)); 427 read (epp->fd [0], buf, sizeof (buf));
411#endif 428#endif
412
413 epp->sent = 0;
414} 429}
415 430
416/* like new, but dups over old */ 431/* like new, but dups over old */
417static int 432static int
418s_epipe_renew (s_epipe *epp) 433s_epipe_renew (s_epipe *epp)
419{ 434{
435 dTHX;
420 s_epipe epn; 436 s_epipe epn;
421 437
422 if (epp->fd [1] != epp->fd [0]) 438 if (epp->fd [1] != epp->fd [0])
423 close (epp->fd [1]); 439 close (epp->fd [1]);
424 440
425 if (s_epipe_new (&epn)) 441 if (s_epipe_new (&epn))
426 return -1; 442 return -1;
427 443
428 if (epp->len) 444 if (epp->len)
429 { 445 {
430 if (dup2 (S_TO_SOCKET (epn.fd [0]), S_TO_SOCKET (epp->fd [0])) < 0) 446 if (dup2 (epn.fd [0], epp->fd [0]) < 0)
431 croak ("unable to dup over old event pipe"); /* should not croak */ 447 croak ("unable to dup over old event pipe"); /* should not croak */
432 448
433 if (epp->fd [1] != epp->fd [0]) 449 if (epp->fd [1] != epp->fd [0])
434 close (epn.fd [0]); 450 close (epn.fd [0]);
435 451
444#define s_epipe_fd(epp) ((epp)->fd [0]) 460#define s_epipe_fd(epp) ((epp)->fd [0])
445 461
446static int 462static int
447s_epipe_wait (s_epipe *epp) 463s_epipe_wait (s_epipe *epp)
448{ 464{
465 dTHX;
449#ifdef _WIN32 466#ifdef _WIN32
450 fd_set rfd; 467 fd_set rfd;
468 int fd = s_epipe_fd (epp);
451 469
452 FD_ZERO (&rfd); 470 FD_ZERO (&rfd);
453 FD_SET (s_epipe_fd (epp), &rfd); 471 FD_SET (fd, &rfd);
454 472
455 return PerlSock_select (s_epipe_fd (epp) + 1, &rfd, 0, 0, 0); 473 return PerlSock_select (fd + 1, &rfd, 0, 0, 0);
456#else 474#else
457 /* poll is preferable on posix systems */ 475 /* poll is preferable on posix systems */
458 struct pollfd pfd; 476 struct pollfd pfd;
459 477
460 pfd.fd = s_epipe_fd (epp); 478 pfd.fd = s_epipe_fd (epp);
461 pfd.events = POLLIN; 479 pfd.events = POLLIN;
462 480
463 return poll (&pfd, 1, 0); 481 return poll (&pfd, 1, -1);
464#endif 482#endif
465} 483}
466 484
467#endif 485#endif
468 486

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines