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

Comparing EV/schmorp.h (file contents):
Revision 1.5 by root, Fri Jul 17 14:49:33 2009 UTC vs.
Revision 1.9 by root, Thu Jul 8 00:45:03 2010 UTC

6 */ 6 */
7 7
8#include <signal.h> 8#include <signal.h>
9#include <errno.h> 9#include <errno.h>
10 10
11#ifndef _WIN32 11#if defined(WIN32 ) || defined(_MINIX)
12# define SCHMORP_H_PREFER_SELECT 1
13#endif
14
15#if !SCHMORP_H_PREFER_SELECT
12# include <poll.h> 16# include <poll.h>
13#endif 17#endif
14 18
15/* useful stuff, used by schmorp mostly */ 19/* useful stuff, used by schmorp mostly */
16 20
20 (PERL_REVISION > (a) \ 24 (PERL_REVISION > (a) \
21 || (PERL_REVISION == (a) \ 25 || (PERL_REVISION == (a) \
22 && (PERL_VERSION > (b) \ 26 && (PERL_VERSION > (b) \
23 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c))))) 27 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c)))))
24 28
29#ifndef PERL_MAGIC_ext
30# define PERL_MAGIC_ext '~'
31#endif
32
25#if !PERL_VERSION_ATLEAST (5,6,0) 33#if !PERL_VERSION_ATLEAST (5,6,0)
26# ifndef PL_ppaddr 34# ifndef PL_ppaddr
27# define PL_ppaddr ppaddr 35# define PL_ppaddr ppaddr
28# endif 36# endif
29# ifndef call_sv 37# ifndef call_sv
209/* taken almost verbatim from libev's ev_win32.c */ 217/* taken almost verbatim from libev's ev_win32.c */
210/* oh, the humanity! */ 218/* oh, the humanity! */
211static int 219static int
212s_pipe (int filedes [2]) 220s_pipe (int filedes [2])
213{ 221{
222 dTHX;
223
214 struct sockaddr_in addr = { 0 }; 224 struct sockaddr_in addr = { 0 };
215 int addr_size = sizeof (addr); 225 int addr_size = sizeof (addr);
216 struct sockaddr_in adr2; 226 struct sockaddr_in adr2;
217 int adr2_size = sizeof (adr2); 227 int adr2_size = sizeof (adr2);
218 SOCKET listener; 228 SOCKET listener;
321} 331}
322 332
323#endif 333#endif
324 334
325#if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) 335#if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
336# define SCHMORP_H_HAVE_EVENTFD 1
326/* our minimum requirement is glibc 2.7 which has the stub, but not the header */ 337/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
327# include <stdint.h> 338# include <stdint.h>
328# ifdef __cplusplus 339# ifdef __cplusplus
329extern "C" { 340extern "C" {
330# endif 341# endif
337#endif 348#endif
338 349
339typedef struct { 350typedef struct {
340 int fd[2]; /* read, write fd, might be equal */ 351 int fd[2]; /* read, write fd, might be equal */
341 int len; /* write length (1 pipe/socket, 8 eventfd) */ 352 int len; /* write length (1 pipe/socket, 8 eventfd) */
342 volatile sig_atomic_t sent;
343} s_epipe; 353} s_epipe;
344 354
345static int 355static int
346s_epipe_new (s_epipe *epp) 356s_epipe_new (s_epipe *epp)
347{ 357{
360 return -1; 370 return -1;
361 371
362 if (s_fd_prepare (ep.fd [0]) 372 if (s_fd_prepare (ep.fd [0])
363 || s_fd_prepare (ep.fd [1])) 373 || s_fd_prepare (ep.fd [1]))
364 { 374 {
375 dTHX;
376
365 close (ep.fd [0]); 377 close (ep.fd [0]);
366 close (ep.fd [1]); 378 close (ep.fd [1]);
367 return -1; 379 return -1;
368 } 380 }
369 381
370 ep.len = 1; 382 ep.len = 1;
371 } 383 }
372 384
373 ep.sent = 0;
374 *epp = ep; 385 *epp = ep;
375 return 0; 386 return 0;
376} 387}
377 388
378static void 389static void
379s_epipe_destroy (s_epipe *epp) 390s_epipe_destroy (s_epipe *epp)
380{ 391{
392 dTHX;
393
381 close (epp->fd [0]); 394 close (epp->fd [0]);
382 395
383 if (epp->fd [1] != epp->fd [0]) 396 if (epp->fd [1] != epp->fd [0])
384 close (epp->fd [1]); 397 close (epp->fd [1]);
385 398
387} 400}
388 401
389static void 402static void
390s_epipe_signal (s_epipe *epp) 403s_epipe_signal (s_epipe *epp)
391{ 404{
392 if (epp->sent)
393 return;
394
395 epp->sent = 1;
396 {
397#ifdef _WIN32 405#ifdef _WIN32
398 /* perl overrides send with a function that crashes in other threads. 406 /* perl overrides send with a function that crashes in other threads.
399 * unfortunately, it overrides it with an argument-less macro, so 407 * unfortunately, it overrides it with an argument-less macro, so
400 * there is no way to force usage of the real send function. 408 * there is no way to force usage of the real send function.
401 * incompetent windows programmers - is this redundant? 409 * incompetent windows programmers - is this redundant?
402 */ 410 */
403 DWORD dummy; 411 DWORD dummy;
404 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0); 412 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0);
405#else 413#else
414# if SCHMORP_H_HAVE_EVENTFD
406 static uint64_t counter = 1; 415 static uint64_t counter = 1;
416# else
417 static char counter [8];
418# endif
407 /* some modules accept fd's from outside, support eventfd here */ 419 /* some modules accept fd's from outside, support eventfd here */
408 if (write (epp->fd [1], &counter, epp->len) < 0 420 if (write (epp->fd [1], &counter, epp->len) < 0
409 && errno == EINVAL 421 && errno == EINVAL
410 && epp->len != 8) 422 && epp->len != 8)
411 write (epp->fd [1], &counter, (epp->len = 8)); 423 write (epp->fd [1], &counter, (epp->len = 8));
412#endif 424#endif
413 }
414} 425}
415 426
416static void 427static void
417s_epipe_drain (s_epipe *epp) 428s_epipe_drain (s_epipe *epp)
418{ 429{
430 dTHX;
419 char buf [9]; 431 char buf [9];
420 432
421#ifdef _WIN32 433#ifdef _WIN32
422 recv (epp->fd [0], buf, sizeof (buf), 0); 434 recv (epp->fd [0], buf, sizeof (buf), 0);
423#else 435#else
424 read (epp->fd [0], buf, sizeof (buf)); 436 read (epp->fd [0], buf, sizeof (buf));
425#endif 437#endif
426
427 epp->sent = 0;
428} 438}
429 439
430/* like new, but dups over old */ 440/* like new, but dups over old */
431static int 441static int
432s_epipe_renew (s_epipe *epp) 442s_epipe_renew (s_epipe *epp)
433{ 443{
444 dTHX;
434 s_epipe epn; 445 s_epipe epn;
435 446
436 if (epp->fd [1] != epp->fd [0]) 447 if (epp->fd [1] != epp->fd [0])
437 close (epp->fd [1]); 448 close (epp->fd [1]);
438 449
442 if (epp->len) 453 if (epp->len)
443 { 454 {
444 if (dup2 (epn.fd [0], epp->fd [0]) < 0) 455 if (dup2 (epn.fd [0], epp->fd [0]) < 0)
445 croak ("unable to dup over old event pipe"); /* should not croak */ 456 croak ("unable to dup over old event pipe"); /* should not croak */
446 457
447 if (epp->fd [1] != epp->fd [0])
448 close (epn.fd [0]); 458 close (epn.fd [0]);
459
460 if (epn.fd [0] == epn.fd [1])
461 epn.fd [1] = epp->fd [0];
449 462
450 epn.fd [0] = epp->fd [0]; 463 epn.fd [0] = epp->fd [0];
451 } 464 }
452 465
453 *epp = epn; 466 *epp = epn;
458#define s_epipe_fd(epp) ((epp)->fd [0]) 471#define s_epipe_fd(epp) ((epp)->fd [0])
459 472
460static int 473static int
461s_epipe_wait (s_epipe *epp) 474s_epipe_wait (s_epipe *epp)
462{ 475{
463#ifdef _WIN32 476 dTHX;
477#if SCHMORP_H_PREFER_SELECT
464 fd_set rfd; 478 fd_set rfd;
465 int fd = s_epipe_fd (epp); 479 int fd = s_epipe_fd (epp);
466 480
467 FD_ZERO (&rfd); 481 FD_ZERO (&rfd);
468 FD_SET (fd, &rfd); 482 FD_SET (fd, &rfd);
473 struct pollfd pfd; 487 struct pollfd pfd;
474 488
475 pfd.fd = s_epipe_fd (epp); 489 pfd.fd = s_epipe_fd (epp);
476 pfd.events = POLLIN; 490 pfd.events = POLLIN;
477 491
478 return poll (&pfd, 1, 0); 492 return poll (&pfd, 1, -1);
479#endif 493#endif
480} 494}
481 495
482#endif 496#endif
483 497

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines