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.13 by root, Sun Apr 14 09:43:18 2013 UTC

1#ifndef SCHMORP_PERL_H_ 1#ifndef SCHMORP_PERL_H_
2#define SCHMORP_PERL_H_ 2#define SCHMORP_PERL_H_
3 3
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 * perl header files MUST already be included.
6 */ 7 */
7 8
8#include <signal.h> 9#include <signal.h>
10#include <errno.h>
9 11
10#ifndef _WIN32 12#if defined(WIN32 ) || defined(_MINIX)
13# define SCHMORP_H_PREFER_SELECT 1
14#endif
15
16#if !SCHMORP_H_PREFER_SELECT
11# include <poll.h> 17# include <poll.h>
12#endif 18#endif
13 19
14/* useful stuff, used by schmorp mostly */ 20/* useful stuff, used by schmorp mostly */
15 21
19 (PERL_REVISION > (a) \ 25 (PERL_REVISION > (a) \
20 || (PERL_REVISION == (a) \ 26 || (PERL_REVISION == (a) \
21 && (PERL_VERSION > (b) \ 27 && (PERL_VERSION > (b) \
22 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c))))) 28 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c)))))
23 29
30#ifndef PERL_MAGIC_ext
31# define PERL_MAGIC_ext '~'
32#endif
33
24#if !PERL_VERSION_ATLEAST (5,6,0) 34#if !PERL_VERSION_ATLEAST (5,6,0)
25# ifndef PL_ppaddr 35# ifndef PL_ppaddr
26# define PL_ppaddr ppaddr 36# define PL_ppaddr ppaddr
27# endif 37# endif
28# ifndef call_sv 38# ifndef call_sv
39# endif 49# endif
40# ifndef IS_PADCONST 50# ifndef IS_PADCONST
41# define IS_PADCONST(v) 0 51# define IS_PADCONST(v) 0
42# endif 52# endif
43#endif 53#endif
54
55/* use NV for 32 bit perls as it allows larger offsets */
56#if IVSIZE >= 8
57typedef IV VAL64;
58# define SvVAL64(sv) SvIV (sv)
59# define newSVval64(i64) newSViv (i64)
60#else
61typedef NV VAL64;
62# define SvVAL64(sv) SvNV (sv)
63# define newSVval64(i64) newSVnv (i64)
64#endif
65
66/* typemap for the above */
67/*
68VAL64 T_VAL64
69
70INPUT
71
72T_VAL64
73 $var = ($type)SvVAL64 ($arg);
74
75OUTPUT
76
77T_VAL64
78 $arg = newSVval64 ($var);
79*/
44 80
45/* 5.11 */ 81/* 5.11 */
46#ifndef CxHASARGS 82#ifndef CxHASARGS
47# define CxHASARGS(cx) (cx)->blk_sub.hasargs 83# define CxHASARGS(cx) (cx)->blk_sub.hasargs
48#endif 84#endif
152s_get_cv (SV *cb_sv) 188s_get_cv (SV *cb_sv)
153{ 189{
154 dTHX; 190 dTHX;
155 HV *st; 191 HV *st;
156 GV *gvp; 192 GV *gvp;
157 193
158 return (SV *)sv_2cv (cb_sv, &st, &gvp, 0); 194 return (SV *)sv_2cv (cb_sv, &st, &gvp, 0);
159} 195}
160 196
161static SV * 197static SV *
162s_get_cv_croak (SV *cb_sv) 198s_get_cv_croak (SV *cb_sv)
193 S_GENSUB_ARG = arg; 229 S_GENSUB_ARG = arg;
194 230
195 return newRV_noinc ((SV *)cv); 231 return newRV_noinc ((SV *)cv);
196} 232}
197 233
234/*****************************************************************************/
198/** portable pipe/socketpair */ 235/* portable pipe/socketpair */
199 236
200#ifdef USE_SOCKETS_AS_HANDLES 237#ifdef USE_SOCKETS_AS_HANDLES
201# define S_TO_SOCKET(x) (win32_get_osfhandle (x)) 238# define S_TO_HANDLE(x) ((HANDLE)win32_get_osfhandle (x))
202#else 239#else
203# define S_TO_SOCKET(x) (x) 240# define S_TO_HANDLE(x) ((HANDLE)x)
204#endif 241#endif
205 242
206#ifdef _WIN32 243#ifdef _WIN32
207/* taken almost verbatim from libev's ev_win32.c */ 244/* taken almost verbatim from libev's ev_win32.c */
208/* oh, the humanity! */ 245/* oh, the humanity! */
209static int 246static int
210s_pipe (int filedes [2]) 247s_pipe (int filedes [2])
211{ 248{
249 dTHX;
250
212 struct sockaddr_in addr = { 0 }; 251 struct sockaddr_in addr = { 0 };
213 int addr_size = sizeof (addr); 252 int addr_size = sizeof (addr);
214 struct sockaddr_in adr2; 253 struct sockaddr_in adr2;
215 int adr2_size = sizeof (adr2); 254 int adr2_size = sizeof (adr2);
216 SOCKET listener; 255 SOCKET listener;
291#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes) 330#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes)
292 331
293static int 332static int
294s_fd_blocking (int fd, int blocking) 333s_fd_blocking (int fd, int blocking)
295{ 334{
296 blocking = !blocking; 335 u_long nonblocking = !blocking;
297 336
298 return ioctlsocket (S_TO_SOCKET (fd), FIONBIO, &blocking); 337 return ioctlsocket ((SOCKET)S_TO_HANDLE (fd), FIONBIO, &nonblocking);
299} 338}
300 339
301#define s_fd_prepare(fd) s_fd_blocking (fd, 0) 340#define s_fd_prepare(fd) s_fd_blocking (fd, 0)
302 341
303#else 342#else
319} 358}
320 359
321#endif 360#endif
322 361
323#if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) 362#if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
363# define SCHMORP_H_HAVE_EVENTFD 1
324/* our minimum requirement is glibc 2.7 which has the stub, but not the header */ 364/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
325# include <stdint.h> 365# include <stdint.h>
326# ifdef __cplusplus 366# ifdef __cplusplus
327extern "C" { 367extern "C" {
328# endif 368# endif
335#endif 375#endif
336 376
337typedef struct { 377typedef struct {
338 int fd[2]; /* read, write fd, might be equal */ 378 int fd[2]; /* read, write fd, might be equal */
339 int len; /* write length (1 pipe/socket, 8 eventfd) */ 379 int len; /* write length (1 pipe/socket, 8 eventfd) */
340 volatile sig_atomic_t sent;
341} s_epipe; 380} s_epipe;
342 381
343static int 382static int
344s_epipe_new (s_epipe *epp) 383s_epipe_new (s_epipe *epp)
345{ 384{
358 return -1; 397 return -1;
359 398
360 if (s_fd_prepare (ep.fd [0]) 399 if (s_fd_prepare (ep.fd [0])
361 || s_fd_prepare (ep.fd [1])) 400 || s_fd_prepare (ep.fd [1]))
362 { 401 {
402 dTHX;
403
363 close (ep.fd [0]); 404 close (ep.fd [0]);
364 close (ep.fd [1]); 405 close (ep.fd [1]);
365 return -1; 406 return -1;
366 } 407 }
367 408
368 ep.len = 1; 409 ep.len = 1;
369 } 410 }
370 411
371 ep.sent = 0;
372 *epp = ep; 412 *epp = ep;
373 return 0; 413 return 0;
374} 414}
375 415
376static void 416static void
377s_epipe_destroy (s_epipe *epp) 417s_epipe_destroy (s_epipe *epp)
378{ 418{
419 dTHX;
420
379 close (epp->fd [0]); 421 close (epp->fd [0]);
380 422
381 if (epp->fd [1] != epp->fd [0]) 423 if (epp->fd [1] != epp->fd [0])
382 close (epp->fd [1]); 424 close (epp->fd [1]);
383 425
385} 427}
386 428
387static void 429static void
388s_epipe_signal (s_epipe *epp) 430s_epipe_signal (s_epipe *epp)
389{ 431{
390 if (epp->sent)
391 return;
392
393 epp->sent = 1;
394#ifdef _WIN32 432#ifdef _WIN32
395 send (epp->fd [1], epp, 1); 433 /* perl overrides send with a function that crashes in other threads.
434 * unfortunately, it overrides it with an argument-less macro, so
435 * there is no way to force usage of the real send function.
436 * incompetent windows programmers - is this redundant?
437 */
438 DWORD dummy;
439 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0);
396#else 440#else
441# if SCHMORP_H_HAVE_EVENTFD
397 static uint64_t counter = 1; 442 static uint64_t counter = 1;
443# else
444 static char counter [8];
445# endif
446 /* some modules accept fd's from outside, support eventfd here */
447 if (write (epp->fd [1], &counter, epp->len) < 0
448 && errno == EINVAL
449 && epp->len != 8)
398 write (epp->fd [1], &counter, epp->len); 450 write (epp->fd [1], &counter, (epp->len = 8));
399#endif 451#endif
400} 452}
401 453
402static void 454static void
403s_epipe_drain (s_epipe *epp) 455s_epipe_drain (s_epipe *epp)
404{ 456{
457 dTHX;
405 char buf [9]; 458 char buf [9];
406 459
407#ifdef _WIN32 460#ifdef _WIN32
408 PerlSock_recv (epp->fd [0], buf, sizeof (buf), 0); 461 recv (epp->fd [0], buf, sizeof (buf), 0);
409#else 462#else
410 read (epp->fd [0], buf, sizeof (buf)); 463 read (epp->fd [0], buf, sizeof (buf));
411#endif 464#endif
412
413 epp->sent = 0;
414} 465}
415 466
416/* like new, but dups over old */ 467/* like new, but dups over old */
417static int 468static int
418s_epipe_renew (s_epipe *epp) 469s_epipe_renew (s_epipe *epp)
419{ 470{
471 dTHX;
420 s_epipe epn; 472 s_epipe epn;
421 473
422 if (epp->fd [1] != epp->fd [0]) 474 if (epp->fd [1] != epp->fd [0])
423 close (epp->fd [1]); 475 close (epp->fd [1]);
424 476
425 if (s_epipe_new (&epn)) 477 if (s_epipe_new (&epn))
426 return -1; 478 return -1;
427 479
428 if (epp->len) 480 if (epp->len)
429 { 481 {
430 if (dup2 (S_TO_SOCKET (epn.fd [0]), S_TO_SOCKET (epp->fd [0])) < 0) 482 if (dup2 (epn.fd [0], epp->fd [0]) < 0)
431 croak ("unable to dup over old event pipe"); /* should not croak */ 483 croak ("unable to dup over old event pipe"); /* should not croak */
432 484
433 if (epp->fd [1] != epp->fd [0])
434 close (epn.fd [0]); 485 close (epn.fd [0]);
486
487 if (epn.fd [0] == epn.fd [1])
488 epn.fd [1] = epp->fd [0];
435 489
436 epn.fd [0] = epp->fd [0]; 490 epn.fd [0] = epp->fd [0];
437 } 491 }
438 492
439 *epp = epn; 493 *epp = epn;
444#define s_epipe_fd(epp) ((epp)->fd [0]) 498#define s_epipe_fd(epp) ((epp)->fd [0])
445 499
446static int 500static int
447s_epipe_wait (s_epipe *epp) 501s_epipe_wait (s_epipe *epp)
448{ 502{
449#ifdef _WIN32 503 dTHX;
504#if SCHMORP_H_PREFER_SELECT
450 fd_set rfd; 505 fd_set rfd;
506 int fd = s_epipe_fd (epp);
451 507
452 FD_ZERO (&rfd); 508 FD_ZERO (&rfd);
453 FD_SET (s_epipe_fd (epp), &rfd); 509 FD_SET (fd, &rfd);
454 510
455 return PerlSock_select (s_epipe_fd (epp) + 1, &rfd, 0, 0, 0); 511 return PerlSock_select (fd + 1, &rfd, 0, 0, 0);
456#else 512#else
457 /* poll is preferable on posix systems */ 513 /* poll is preferable on posix systems */
458 struct pollfd pfd; 514 struct pollfd pfd;
459 515
460 pfd.fd = s_epipe_fd (epp); 516 pfd.fd = s_epipe_fd (epp);
461 pfd.events = POLLIN; 517 pfd.events = POLLIN;
462 518
463 return poll (&pfd, 1, 0); 519 return poll (&pfd, 1, -1);
464#endif 520#endif
465} 521}
466 522
467#endif 523#endif
468 524

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines