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.16 by root, Tue Nov 19 13:08:54 2019 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>
9#include <errno.h> 10#include <errno.h>
10 11
11#ifndef _WIN32 12#if defined(WIN32 ) || defined(_MINIX)
13# define SCHMORP_H_PREFER_SELECT 1
14#endif
15
16#if !SCHMORP_H_PREFER_SELECT
12# include <poll.h> 17# include <poll.h>
13#endif 18#endif
14 19
15/* useful stuff, used by schmorp mostly */ 20/* useful stuff, used by schmorp mostly */
16 21
20 (PERL_REVISION > (a) \ 25 (PERL_REVISION > (a) \
21 || (PERL_REVISION == (a) \ 26 || (PERL_REVISION == (a) \
22 && (PERL_VERSION > (b) \ 27 && (PERL_VERSION > (b) \
23 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c))))) 28 || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c)))))
24 29
30#ifndef PERL_MAGIC_ext
31# define PERL_MAGIC_ext '~'
32#endif
33
25#if !PERL_VERSION_ATLEAST (5,6,0) 34#if !PERL_VERSION_ATLEAST (5,6,0)
26# ifndef PL_ppaddr 35# ifndef PL_ppaddr
27# define PL_ppaddr ppaddr 36# define PL_ppaddr ppaddr
28# endif 37# endif
29# ifndef call_sv 38# ifndef call_sv
40# endif 49# endif
41# ifndef IS_PADCONST 50# ifndef IS_PADCONST
42# define IS_PADCONST(v) 0 51# define IS_PADCONST(v) 0
43# endif 52# endif
44#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# define sv_setval64(sv,i64) sv_setiv ((sv), (i64))
61#else
62typedef NV VAL64;
63# define SvVAL64(sv) SvNV (sv)
64# define newSVval64(i64) newSVnv (i64)
65# define sv_setval64(sv,i64) sv_setnv ((sv), (i64))
66#endif
67
68/* typemap for the above */
69/*
70VAL64 T_VAL64
71
72INPUT
73
74T_VAL64
75 $var = ($type)SvVAL64 ($arg);
76
77OUTPUT
78
79T_VAL64
80 $arg = newSVval64 ($var);
81*/
45 82
46/* 5.11 */ 83/* 5.11 */
47#ifndef CxHASARGS 84#ifndef CxHASARGS
48# define CxHASARGS(cx) (cx)->blk_sub.hasargs 85# define CxHASARGS(cx) (cx)->blk_sub.hasargs
49#endif 86#endif
153s_get_cv (SV *cb_sv) 190s_get_cv (SV *cb_sv)
154{ 191{
155 dTHX; 192 dTHX;
156 HV *st; 193 HV *st;
157 GV *gvp; 194 GV *gvp;
158 195
159 return (SV *)sv_2cv (cb_sv, &st, &gvp, 0); 196 return (SV *)sv_2cv (cb_sv, &st, &gvp, 0);
160} 197}
161 198
162static SV * 199static SV *
163s_get_cv_croak (SV *cb_sv) 200s_get_cv_croak (SV *cb_sv)
197} 234}
198 235
199/*****************************************************************************/ 236/*****************************************************************************/
200/* portable pipe/socketpair */ 237/* portable pipe/socketpair */
201 238
202#ifdef USE_SOCKETS_AS_HANDLES 239#if defined(USE_SOCKETS_AS_HANDLES) || PERL_VERSION_ATLEAST(5,18,0)
203# define S_TO_HANDLE(x) ((HANDLE)win32_get_osfhandle (x)) 240# define S_TO_HANDLE(x) ((HANDLE)win32_get_osfhandle (x))
204#else 241#else
205# define S_TO_HANDLE(x) ((HANDLE)x) 242# define S_TO_HANDLE(x) ((HANDLE)x)
206#endif 243#endif
207 244
209/* taken almost verbatim from libev's ev_win32.c */ 246/* taken almost verbatim from libev's ev_win32.c */
210/* oh, the humanity! */ 247/* oh, the humanity! */
211static int 248static int
212s_pipe (int filedes [2]) 249s_pipe (int filedes [2])
213{ 250{
251 dTHX;
252
214 struct sockaddr_in addr = { 0 }; 253 struct sockaddr_in addr = { 0 };
215 int addr_size = sizeof (addr); 254 int addr_size = sizeof (addr);
216 struct sockaddr_in adr2; 255 struct sockaddr_in adr2;
217 int adr2_size = sizeof (adr2); 256 int adr2_size = sizeof (adr2);
218 SOCKET listener; 257 SOCKET listener;
219 SOCKET sock [2] = { -1, -1 }; 258 SOCKET sock [2] = { -1, -1 };
220 259
221 if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 260 if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
222 return -1; 261 return -1;
223 262
224 addr.sin_family = AF_INET; 263 addr.sin_family = AF_INET;
225 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); 264 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
226 addr.sin_port = 0; 265 addr.sin_port = 0;
232 goto fail; 271 goto fail;
233 272
234 if (listen (listener, 1)) 273 if (listen (listener, 1))
235 goto fail; 274 goto fail;
236 275
237 if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 276 if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
238 goto fail; 277 goto fail;
239 278
240 if (connect (sock [0], (struct sockaddr *)&addr, addr_size)) 279 if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
241 goto fail; 280 goto fail;
242 281
267 || addr.sin_port != adr2.sin_port) 306 || addr.sin_port != adr2.sin_port)
268 goto fail; 307 goto fail;
269 308
270 closesocket (listener); 309 closesocket (listener);
271 310
272#ifdef USE_SOCKETS_AS_HANDLES 311#if defined(USE_SOCKETS_AS_HANDLES) || PERL_VERSION_ATLEAST(5,18,0)
273 /* when select isn't winsocket, we also expect socket, connect, accept etc. 312 /* when select isn't winsocket, we also expect socket, connect, accept etc.
274 * to work on fds */ 313 * to work on fds */
275 filedes [0] = sock [0]; 314 filedes [0] = sock [0];
276 filedes [1] = sock [1]; 315 filedes [1] = sock [1];
277#else 316#else
320 || fcntl (fd, F_SETFD, FD_CLOEXEC); 359 || fcntl (fd, F_SETFD, FD_CLOEXEC);
321} 360}
322 361
323#endif 362#endif
324 363
364#if HAVE_EVENTFD
365# include <sys/eventfd.h>
366#else
325#if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) 367# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
368# define SCHMORP_H_HAVE_EVENTFD 1
326/* our minimum requirement is glibc 2.7 which has the stub, but not the header */ 369/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
327# include <stdint.h> 370# include <stdint.h>
328# ifdef __cplusplus 371# ifdef __cplusplus
329extern "C" { 372extern "C" {
330# endif 373# endif
331 int eventfd (unsigned int initval, int flags); 374 int eventfd (unsigned int initval, int flags);
332# ifdef __cplusplus 375# ifdef __cplusplus
333} 376}
334# endif 377# endif
335#else 378# else
336# define eventfd(initval,flags) -1 379# define eventfd(initval,flags) -1
380# endif
337#endif 381#endif
338 382
339typedef struct { 383typedef struct {
340 int fd[2]; /* read, write fd, might be equal */ 384 int fd[2]; /* read, write fd, might be equal */
341 int len; /* write length (1 pipe/socket, 8 eventfd) */ 385 int len; /* write length (1 pipe/socket, 8 eventfd) */
342 volatile sig_atomic_t sent;
343} s_epipe; 386} s_epipe;
344 387
345static int 388static int
346s_epipe_new (s_epipe *epp) 389s_epipe_new (s_epipe *epp)
347{ 390{
360 return -1; 403 return -1;
361 404
362 if (s_fd_prepare (ep.fd [0]) 405 if (s_fd_prepare (ep.fd [0])
363 || s_fd_prepare (ep.fd [1])) 406 || s_fd_prepare (ep.fd [1]))
364 { 407 {
408 dTHX;
409
365 close (ep.fd [0]); 410 close (ep.fd [0]);
366 close (ep.fd [1]); 411 close (ep.fd [1]);
367 return -1; 412 return -1;
368 } 413 }
369 414
370 ep.len = 1; 415 ep.len = 1;
371 } 416 }
372 417
373 ep.sent = 0;
374 *epp = ep; 418 *epp = ep;
375 return 0; 419 return 0;
376} 420}
377 421
378static void 422static void
379s_epipe_destroy (s_epipe *epp) 423s_epipe_destroy (s_epipe *epp)
380{ 424{
425 dTHX;
426
381 close (epp->fd [0]); 427 close (epp->fd [0]);
382 428
383 if (epp->fd [1] != epp->fd [0]) 429 if (epp->fd [1] != epp->fd [0])
384 close (epp->fd [1]); 430 close (epp->fd [1]);
385 431
387} 433}
388 434
389static void 435static void
390s_epipe_signal (s_epipe *epp) 436s_epipe_signal (s_epipe *epp)
391{ 437{
392 if (epp->sent)
393 return;
394
395 epp->sent = 1;
396 {
397#ifdef _WIN32 438#ifdef _WIN32
398 /* perl overrides send with a function that crashes in other threads. 439 /* perl overrides send with a function that crashes in other threads.
399 * unfortunately, it overrides it with an argument-less macro, so 440 * unfortunately, it overrides it with an argument-less macro, so
400 * there is no way to force usage of the real send function. 441 * there is no way to force usage of the real send function.
401 * incompetent windows programmers - is this redundant? 442 * incompetent windows programmers - is this redundant?
402 */ 443 */
403 DWORD dummy; 444 DWORD dummy;
404 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0); 445 WriteFile (S_TO_HANDLE (epp->fd [1]), (LPCVOID)&dummy, 1, &dummy, 0);
405#else 446#else
406 static uint64_t counter = 1; 447 static uint64_t counter = 1;
407 /* some modules accept fd's from outside, support eventfd here */ 448 /* some modules accept fd's from outside, support eventfd here */
408 if (write (epp->fd [1], &counter, epp->len) < 0 449 if (write (epp->fd [1], &counter, epp->len) < 0
409 && errno == EINVAL 450 && errno == EINVAL
410 && epp->len != 8) 451 && epp->len != 8)
411 write (epp->fd [1], &counter, (epp->len = 8)); 452 write (epp->fd [1], &counter, (epp->len = 8));
412#endif 453#endif
413 }
414} 454}
415 455
416static void 456static void
417s_epipe_drain (s_epipe *epp) 457s_epipe_drain (s_epipe *epp)
418{ 458{
459 dTHX;
419 char buf [9]; 460 char buf [9];
420 461
421#ifdef _WIN32 462#ifdef _WIN32
422 recv (epp->fd [0], buf, sizeof (buf), 0); 463 recv (epp->fd [0], buf, sizeof (buf), 0);
423#else 464#else
424 read (epp->fd [0], buf, sizeof (buf)); 465 read (epp->fd [0], buf, sizeof (buf));
425#endif 466#endif
426
427 epp->sent = 0;
428} 467}
429 468
430/* like new, but dups over old */ 469/* like new, but dups over old */
431static int 470static int
432s_epipe_renew (s_epipe *epp) 471s_epipe_renew (s_epipe *epp)
433{ 472{
473 dTHX;
434 s_epipe epn; 474 s_epipe epn;
435 475
436 if (epp->fd [1] != epp->fd [0]) 476 if (epp->fd [1] != epp->fd [0])
437 close (epp->fd [1]); 477 close (epp->fd [1]);
438 478
442 if (epp->len) 482 if (epp->len)
443 { 483 {
444 if (dup2 (epn.fd [0], epp->fd [0]) < 0) 484 if (dup2 (epn.fd [0], epp->fd [0]) < 0)
445 croak ("unable to dup over old event pipe"); /* should not croak */ 485 croak ("unable to dup over old event pipe"); /* should not croak */
446 486
447 if (epp->fd [1] != epp->fd [0])
448 close (epn.fd [0]); 487 close (epn.fd [0]);
488
489 if (epn.fd [0] == epn.fd [1])
490 epn.fd [1] = epp->fd [0];
449 491
450 epn.fd [0] = epp->fd [0]; 492 epn.fd [0] = epp->fd [0];
451 } 493 }
452 494
453 *epp = epn; 495 *epp = epn;
458#define s_epipe_fd(epp) ((epp)->fd [0]) 500#define s_epipe_fd(epp) ((epp)->fd [0])
459 501
460static int 502static int
461s_epipe_wait (s_epipe *epp) 503s_epipe_wait (s_epipe *epp)
462{ 504{
463#ifdef _WIN32 505 dTHX;
506#if SCHMORP_H_PREFER_SELECT
464 fd_set rfd; 507 fd_set rfd;
465 int fd = s_epipe_fd (epp); 508 int fd = s_epipe_fd (epp);
466 509
467 FD_ZERO (&rfd); 510 FD_ZERO (&rfd);
468 FD_SET (fd, &rfd); 511 FD_SET (fd, &rfd);
473 struct pollfd pfd; 516 struct pollfd pfd;
474 517
475 pfd.fd = s_epipe_fd (epp); 518 pfd.fd = s_epipe_fd (epp);
476 pfd.events = POLLIN; 519 pfd.events = POLLIN;
477 520
478 return poll (&pfd, 1, 0); 521 return poll (&pfd, 1, -1);
479#endif 522#endif
480} 523}
481 524
482#endif 525#endif
483 526

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines