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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines