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

Comparing IO-AIO/AIO.xs (file contents):
Revision 1.138 by root, Tue Apr 21 20:06:05 2009 UTC vs.
Revision 1.155 by root, Fri Jul 17 00:56:54 2009 UTC

3#include <errno.h> 3#include <errno.h>
4 4
5#include "EXTERN.h" 5#include "EXTERN.h"
6#include "perl.h" 6#include "perl.h"
7#include "XSUB.h" 7#include "XSUB.h"
8
9#include "schmorp.h"
8 10
9#include <stddef.h> 11#include <stddef.h>
10#include <stdlib.h> 12#include <stdlib.h>
11#include <errno.h> 13#include <errno.h>
12#include <sys/types.h> 14#include <sys/types.h>
75 77
76#define EIO_STRUCT_STAT Stat_t 78#define EIO_STRUCT_STAT Stat_t
77 79
78/* use NV for 32 bit perls as it allows larger offsets */ 80/* use NV for 32 bit perls as it allows larger offsets */
79#if IVSIZE >= 8 81#if IVSIZE >= 8
82# define VAL64 IV
80# define SvVAL64 SvIV 83# define SvVAL64 SvIV
84# define newSVval64 newSViv
81#else 85#else
86# define VAL64 NV
82# define SvVAL64 SvNV 87# define SvVAL64 SvNV
88# define newSVval64 newSVnv
83#endif 89#endif
84 90
85/*****************************************************************************/ 91/*****************************************************************************/
86 92
87#if __GNUC__ >= 3 93#if __GNUC__ >= 3
95 101
96/*****************************************************************************/ 102/*****************************************************************************/
97 103
98static HV *stash; 104static HV *stash;
99typedef SV SV8; /* byte-sv, used for argument-checking */ 105typedef SV SV8; /* byte-sv, used for argument-checking */
106typedef int aio_rfd; /* read file desriptor */
107typedef int aio_wfd; /* write file descriptor */
100 108
101#define AIO_REQ_KLASS "IO::AIO::REQ" 109#define AIO_REQ_KLASS "IO::AIO::REQ"
102#define AIO_GRP_KLASS "IO::AIO::GRP" 110#define AIO_GRP_KLASS "IO::AIO::GRP"
103 111
104#define EIO_REQ_MEMBERS \ 112#define EIO_REQ_MEMBERS \
109 117
110#define EIO_NO_WRAPPERS 1 118#define EIO_NO_WRAPPERS 1
111 119
112#include "libeio/eio.h" 120#include "libeio/eio.h"
113 121
122#ifndef POSIX_FADV_NORMAL
123# define POSIX_FADV_NORMAL 0
124# define NO_FADVISE 1
125#endif
126
127#ifndef POSIX_FADV_SEQUENTIAL
128# define POSIX_FADV_SEQUENTIAL 0
129#endif
130
131#ifndef POSIX_FADV_RANDOM
132# define POSIX_FADV_RANDOM 0
133#endif
134
135#ifndef POSIX_FADV_NOREUSE
136# define POSIX_FADV_NOREUSE 0
137#endif
138
139#ifndef POSIX_FADV_WILLNEED
140# define POSIX_FADV_WILLNEED 0
141#endif
142
143#ifndef POSIX_FADV_DONTNEED
144# define POSIX_FADV_DONTNEED 0
145#endif
146
114static int req_invoke (eio_req *req); 147static int req_invoke (eio_req *req);
115#define EIO_FINISH(req) req_invoke (req) 148#define EIO_FINISH(req) req_invoke (req)
116static void req_destroy (eio_req *grp); 149static void req_destroy (eio_req *grp);
117#define EIO_DESTROY(req) req_destroy (req) 150#define EIO_DESTROY(req) req_destroy (req)
118 151
127 160
128static SV *on_next_submit; 161static SV *on_next_submit;
129static int next_pri = EIO_PRI_DEFAULT; 162static int next_pri = EIO_PRI_DEFAULT;
130static int max_outstanding; 163static int max_outstanding;
131 164
132static int respipe_osf [2], respipe [2] = { -1, -1 }; 165static s_epipe respipe;
133 166
134static void req_destroy (aio_req req); 167static void req_destroy (aio_req req);
135static void req_cancel (aio_req req); 168static void req_cancel (aio_req req);
136 169
137static void want_poll (void) 170static void want_poll (void)
138{ 171{
139 /* write a dummy byte to the pipe so fh becomes ready */ 172 /* write a dummy byte to the pipe so fh becomes ready */
140 respipe_write (respipe_osf [1], (const void *)&respipe_osf, 1); 173 s_epipe_signal (&respipe);
141} 174}
142 175
143static void done_poll (void) 176static void done_poll (void)
144{ 177{
145 /* read any signals sent by the worker threads */ 178 /* read any signals sent by the worker threads */
146 char buf [4]; 179 s_epipe_drain (&respipe);
147 while (respipe_read (respipe [0], buf, 4) == 4)
148 ;
149} 180}
150 181
151/* must be called at most once */ 182/* must be called at most once */
152static SV *req_sv (aio_req req, const char *klass) 183static SV *req_sv (aio_req req, const char *klass)
153{ 184{
228 SV *rv = &PL_sv_undef; 259 SV *rv = &PL_sv_undef;
229 260
230 if (req->result >= 0) 261 if (req->result >= 0)
231 { 262 {
232 int i; 263 int i;
233 char *buf = req->ptr2; 264 char *names = (char *)req->ptr2;
265 eio_dirent *ent = (eio_dirent *)req->ptr1; /* might be 0 */
234 AV *av = newAV (); 266 AV *av = newAV ();
235 267
236 av_extend (av, req->result - 1); 268 av_extend (av, req->result - 1);
237 269
238 for (i = 0; i < req->result; ++i) 270 for (i = 0; i < req->result; ++i)
239 { 271 {
240 SV *sv = newSVpv (buf, 0); 272 if (req->int1 & EIO_READDIR_DENTS)
273 {
274 SV *namesv = newSVpvn (names + ent->nameofs, ent->namelen);
241 275
276 if (req->int1 & EIO_READDIR_CUSTOM2)
277 {
278 static SV *sv_type [EIO_DT_MAX + 1]; /* type sv cache */
279 AV *avent = newAV ();
280
281 av_extend (avent, 2);
282
283 if (!sv_type [ent->type])
284 {
285 sv_type [ent->type] = newSViv (ent->type);
286 SvREADONLY_on (sv_type [ent->type]);
287 }
288
289 av_store (avent, 0, namesv);
290 av_store (avent, 1, SvREFCNT_inc (sv_type [ent->type]));
291 av_store (avent, 2, IVSIZE >= 8 ? newSVuv (ent->inode) : newSVnv (ent->inode));
292
293 av_store (av, i, newRV_noinc ((SV *)avent));
294 }
295 else
242 av_store (av, i, sv); 296 av_store (av, i, namesv);
297
298 ++ent;
299 }
300 else
301 {
302 SV *name = newSVpv (names, 0);
303 av_store (av, i, name);
243 buf += SvCUR (sv) + 1; 304 names += SvCUR (name) + 1;
305 }
244 } 306 }
245 307
246 rv = sv_2mortal (newRV_noinc ((SV *)av)); 308 rv = sv_2mortal (newRV_noinc ((SV *)av));
247 } 309 }
248 310
249 PUSHs (rv); 311 PUSHs (rv);
312
313 if (req->int1 & EIO_READDIR_CUSTOM1)
314 XPUSHs (sv_2mortal (newSViv (req->int1 & ~(EIO_READDIR_CUSTOM1 | EIO_READDIR_CUSTOM2))));
250 } 315 }
251 break; 316 break;
252 317
253 case EIO_OPEN: 318 case EIO_OPEN:
254 { 319 {
260 GV *gv = (GV *)sv_newmortal (); 325 GV *gv = (GV *)sv_newmortal ();
261 int flags = req->int1 & (O_RDONLY | O_WRONLY | O_RDWR); 326 int flags = req->int1 & (O_RDONLY | O_WRONLY | O_RDWR);
262 char sym [64]; 327 char sym [64];
263 int symlen; 328 int symlen;
264 329
265 symlen = snprintf (sym, sizeof (sym), "fd#%d", req->result); 330 symlen = snprintf (sym, sizeof (sym), "fd#%d", (int)req->result);
266 gv_init (gv, stash, sym, symlen, 0); 331 gv_init (gv, stash, sym, symlen, 0);
267 332
268 symlen = snprintf ( 333 symlen = snprintf (
269 sym, 334 sym,
270 sizeof (sym), 335 sizeof (sym),
271 "%s&=%d", 336 "%s&=%d",
272 flags == O_RDONLY ? "<" : flags == O_WRONLY ? ">" : "+<", 337 flags == O_RDONLY ? "<" : flags == O_WRONLY ? ">" : "+<",
273 req->result 338 (int)req->result
274 ); 339 );
275 340
276 if (do_open (gv, sym, symlen, 0, 0, 0, 0)) 341 if (do_open (gv, sym, symlen, 0, 0, 0, 0))
277 fh = (SV *)gv; 342 fh = (SV *)gv;
278 } 343 }
374 grp->sv2 = 0; 439 grp->sv2 = 0;
375 440
376 eio_grp_cancel (grp); 441 eio_grp_cancel (grp);
377} 442}
378 443
379#ifdef USE_SOCKETS_AS_HANDLES
380# define TO_SOCKET(x) (win32_get_osfhandle (x))
381#else
382# define TO_SOCKET(x) (x)
383#endif
384
385static void 444static void
386create_respipe (void) 445create_respipe (void)
387{ 446{
388 int old_readfd = respipe [0];
389
390 if (respipe [1] >= 0)
391 respipe_close (TO_SOCKET (respipe [1]));
392
393#ifdef _WIN32
394 if (PerlSock_socketpair (AF_UNIX, SOCK_STREAM, 0, respipe))
395#else
396 if (pipe (respipe)) 447 if (s_epipe_renew (&respipe))
397#endif
398 croak ("unable to initialize result pipe"); 448 croak ("IO::AIO: unable to initialize result pipe");
399
400 if (old_readfd >= 0)
401 {
402 if (dup2 (TO_SOCKET (respipe [0]), TO_SOCKET (old_readfd)) < 0)
403 croak ("unable to initialize result pipe(2)");
404
405 respipe_close (respipe [0]);
406 respipe [0] = old_readfd;
407 }
408
409#ifdef _WIN32
410 int arg = 1;
411 if (ioctlsocket (TO_SOCKET (respipe [0]), FIONBIO, &arg)
412 || ioctlsocket (TO_SOCKET (respipe [1]), FIONBIO, &arg))
413#else
414 if (fcntl (respipe [0], F_SETFL, O_NONBLOCK)
415 || fcntl (respipe [1], F_SETFL, O_NONBLOCK))
416#endif
417 croak ("unable to initialize result pipe(3)");
418
419 respipe_osf [0] = TO_SOCKET (respipe [0]);
420 respipe_osf [1] = TO_SOCKET (respipe [1]);
421} 449}
422 450
423static void poll_wait (void) 451static void poll_wait (void)
424{ 452{
425 fd_set rfd;
426
427 while (eio_nreqs ()) 453 while (eio_nreqs ())
428 { 454 {
429 int size; 455 int size;
430 456
431 X_LOCK (reslock); 457 X_LOCK (reslock);
435 if (size) 461 if (size)
436 return; 462 return;
437 463
438 etp_maybe_start_thread (); 464 etp_maybe_start_thread ();
439 465
440 FD_ZERO (&rfd); 466 s_epipe_wait (&respipe);
441 FD_SET (respipe [0], &rfd);
442
443 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0);
444 } 467 }
445} 468}
446 469
447static int poll_cb (void) 470static int poll_cb (void)
448{ 471{
466} 489}
467 490
468static SV * 491static SV *
469get_cb (SV *cb_sv) 492get_cb (SV *cb_sv)
470{ 493{
471 HV *st; 494 SvGETMAGIC (cb_sv);
472 GV *gvp; 495 return SvOK (cb_sv) ? s_get_cv_croak (cb_sv) : 0;
473 CV *cv;
474
475 if (!SvOK (cb_sv))
476 return 0;
477
478 cv = sv_2cv (cb_sv, &st, &gvp, 0);
479
480 if (!cv)
481 croak ("IO::AIO callback must be undef or a CODE reference");
482
483 return (SV *)cv;
484} 496}
485 497
486#define dREQ \ 498#define dREQ \
487 SV *cb_cv; \ 499 SV *cb_cv; \
488 aio_req req; \ 500 aio_req req; \
504 SPAGAIN; \ 516 SPAGAIN; \
505 \ 517 \
506 if (GIMME_V != G_VOID) \ 518 if (GIMME_V != G_VOID) \
507 XPUSHs (req_sv (req, AIO_REQ_KLASS)); 519 XPUSHs (req_sv (req, AIO_REQ_KLASS));
508 520
509static int
510extract_fd (SV *fh, int wr)
511{
512 int fd = PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh)));
513
514 if (fd < 0)
515 croak ("illegal fh argument, either not an OS file or read/write mode mismatch");
516
517 return fd;
518}
519
520MODULE = IO::AIO PACKAGE = IO::AIO 521MODULE = IO::AIO PACKAGE = IO::AIO
521 522
522PROTOTYPES: ENABLE 523PROTOTYPES: ENABLE
523 524
524BOOT: 525BOOT:
525{ 526{
526 stash = gv_stashpv ("IO::AIO", 1); 527 static const struct {
527 528 const char *name;
528 newCONSTSUB (stash, "EXDEV", newSViv (EXDEV)); 529 IV iv;
529 newCONSTSUB (stash, "O_RDONLY", newSViv (O_RDONLY)); 530 } *civ, const_iv[] = {
530 newCONSTSUB (stash, "O_WRONLY", newSViv (O_WRONLY)); 531# define const_iv(name, value) { # name, (IV) value },
531 newCONSTSUB (stash, "O_CREAT", newSViv (O_CREAT)); 532# define const_eio(name) { # name, (IV) EIO_ ## name },
532 newCONSTSUB (stash, "O_TRUNC", newSViv (O_TRUNC)); 533 const_iv (EXDEV , EXDEV)
534 const_iv (ENOSYS , ENOSYS)
535 const_iv (O_RDONLY, O_RDONLY)
536 const_iv (O_WRONLY, O_WRONLY)
537 const_iv (O_CREAT , O_CREAT)
538 const_iv (O_TRUNC , O_TRUNC)
533#ifndef _WIN32 539#ifndef _WIN32
534 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); 540 const_iv (S_IFIFO , S_IFIFO)
535#endif 541#endif
536 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); 542 const_iv (FADV_NORMAL , POSIX_FADV_NORMAL)
537 newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_BEFORE", newSViv (EIO_SYNC_FILE_RANGE_WAIT_BEFORE)); 543 const_iv (FADV_SEQUENTIAL, POSIX_FADV_SEQUENTIAL)
538 newCONSTSUB (stash, "SYNC_FILE_RANGE_WRITE" , newSViv (EIO_SYNC_FILE_RANGE_WRITE)); 544 const_iv (FADV_RANDOM , POSIX_FADV_RANDOM)
539 newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_AFTER" , newSViv (EIO_SYNC_FILE_RANGE_WAIT_AFTER)); 545 const_iv (FADV_NOREUSE , POSIX_FADV_NOREUSE)
546 const_iv (FADV_WILLNEED , POSIX_FADV_WILLNEED)
547 const_iv (FADV_DONTNEED , POSIX_FADV_DONTNEED)
540 548
549 const_eio (SYNC_FILE_RANGE_WAIT_BEFORE)
550 const_eio (SYNC_FILE_RANGE_WRITE)
551 const_eio (SYNC_FILE_RANGE_WAIT_AFTER)
552
553 const_eio (READDIR_DENTS)
554 const_eio (READDIR_DIRS_FIRST)
555 const_eio (READDIR_STAT_ORDER)
556 const_eio (READDIR_FOUND_UNKNOWN)
557
558 const_eio (DT_UNKNOWN)
559 const_eio (DT_FIFO)
560 const_eio (DT_CHR)
561 const_eio (DT_DIR)
562 const_eio (DT_BLK)
563 const_eio (DT_REG)
564 const_eio (DT_LNK)
565 const_eio (DT_SOCK)
566 const_eio (DT_WHT)
567 };
568
569 stash = gv_stashpv ("IO::AIO", 1);
570
571 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
572 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
573
541 create_respipe (); 574 create_respipe ();
542 575
543 if (eio_init (want_poll, done_poll) < 0) 576 if (eio_init (want_poll, done_poll) < 0)
544 croak ("IO::AIO: unable to initialise eio library"); 577 croak ("IO::AIO: unable to initialise eio library");
545 578
546 /* atfork child called in fifo order, so before eio's handler */ 579 /* atfork child called in fifo order, so before eio's handler */
547 X_THREAD_ATFORK (0, 0, atfork_child); 580 X_THREAD_ATFORK (0, 0, atfork_child);
548} 581}
549 582
550void 583void
551max_poll_reqs (int nreqs) 584max_poll_reqs (int nreqs)
552 PROTOTYPE: $ 585 PROTOTYPE: $
605 ALIAS: 638 ALIAS:
606 aio_fsync = EIO_FSYNC 639 aio_fsync = EIO_FSYNC
607 aio_fdatasync = EIO_FDATASYNC 640 aio_fdatasync = EIO_FDATASYNC
608 PPCODE: 641 PPCODE:
609{ 642{
610 int fd = extract_fd (fh, 0); 643 int fd = s_fileno_croak (fh, 0);
611 dREQ; 644 dREQ;
612 645
613 req->type = ix; 646 req->type = ix;
614 req->sv1 = newSVsv (fh); 647 req->sv1 = newSVsv (fh);
615 req->int1 = fd; 648 req->int1 = fd;
616 649
617 REQ_SEND (req); 650 REQ_SEND (req);
618} 651}
619 652
620void 653void
621aio_sync_file_range (SV *fh, SV *offset, SV *nbytes, IV flags, SV *callback=&PL_sv_undef) 654aio_sync_file_range (SV *fh, off_t offset, size_t nbytes, UV flags, SV *callback=&PL_sv_undef)
622 PROTOTYPE: $$$$;$ 655 PROTOTYPE: $$$$;$
623 PPCODE: 656 PPCODE:
624{ 657{
625 int fd = extract_fd (fh, 0); 658 int fd = s_fileno_croak (fh, 0);
626 dREQ; 659 dREQ;
627 660
628 req->type = EIO_SYNC_FILE_RANGE; 661 req->type = EIO_SYNC_FILE_RANGE;
629 req->sv1 = newSVsv (fh); 662 req->sv1 = newSVsv (fh);
630 req->int1 = fd; 663 req->int1 = fd;
631 req->offs = SvVAL64 (offset); 664 req->offs = offset;
632 req->size = SvVAL64 (nbytes); 665 req->size = nbytes;
633 req->int2 = flags; 666 req->int2 = flags;
634 667
635 REQ_SEND (req); 668 REQ_SEND (req);
636} 669}
637 670
639aio_close (SV *fh, SV *callback=&PL_sv_undef) 672aio_close (SV *fh, SV *callback=&PL_sv_undef)
640 PROTOTYPE: $;$ 673 PROTOTYPE: $;$
641 PPCODE: 674 PPCODE:
642{ 675{
643 static int close_pipe = -1; /* dummy fd to close fds via dup2 */ 676 static int close_pipe = -1; /* dummy fd to close fds via dup2 */
644 int fd = extract_fd (fh, 0); 677 int fd = s_fileno_croak (fh, 0);
645 dREQ; 678 dREQ;
646 679
647 if (close_pipe < 0) 680 if (close_pipe < 0)
648 { 681 {
649 int pipefd [2]; 682 int pipefd [2];
671 aio_write = EIO_WRITE 704 aio_write = EIO_WRITE
672 PROTOTYPE: $$$$$;$ 705 PROTOTYPE: $$$$$;$
673 PPCODE: 706 PPCODE:
674{ 707{
675 STRLEN svlen; 708 STRLEN svlen;
676 int fd = extract_fd (fh, ix == EIO_WRITE); 709 int fd = s_fileno_croak (fh, ix == EIO_WRITE);
677 char *svptr = SvPVbyte (data, svlen); 710 char *svptr = SvPVbyte (data, svlen);
678 UV len = SvUV (length); 711 UV len = SvUV (length);
679 712
680 if (dataoffset < 0) 713 if (dataoffset < 0)
681 dataoffset += svlen; 714 dataoffset += svlen;
693 { 726 {
694 /* read: check type and grow scalar as necessary */ 727 /* read: check type and grow scalar as necessary */
695 SvUPGRADE (data, SVt_PV); 728 SvUPGRADE (data, SVt_PV);
696 svptr = SvGROW (data, len + dataoffset + 1); 729 svptr = SvGROW (data, len + dataoffset + 1);
697 } 730 }
698
699 if (len < 0)
700 croak ("length must not be negative");
701 731
702 { 732 {
703 dREQ; 733 dREQ;
704 734
705 req->type = ix; 735 req->type = ix;
735 765
736 REQ_SEND; 766 REQ_SEND;
737} 767}
738 768
739void 769void
740aio_sendfile (SV *out_fh, SV *in_fh, SV *in_offset, UV length, SV *callback=&PL_sv_undef) 770aio_sendfile (SV *out_fh, SV *in_fh, off_t in_offset, size_t length, SV *callback=&PL_sv_undef)
741 PROTOTYPE: $$$$;$ 771 PROTOTYPE: $$$$;$
742 PPCODE: 772 PPCODE:
743{ 773{
744 int ifd = extract_fd (in_fh , 0); 774 int ifd = s_fileno_croak (in_fh , 0);
745 int ofd = extract_fd (out_fh, 0); 775 int ofd = s_fileno_croak (out_fh, 1);
746 dREQ; 776 dREQ;
747 777
748 req->type = EIO_SENDFILE; 778 req->type = EIO_SENDFILE;
749 req->sv1 = newSVsv (out_fh); 779 req->sv1 = newSVsv (out_fh);
750 req->int1 = ofd; 780 req->int1 = ofd;
751 req->sv2 = newSVsv (in_fh); 781 req->sv2 = newSVsv (in_fh);
752 req->int2 = ifd; 782 req->int2 = ifd;
753 req->offs = SvVAL64 (in_offset); 783 req->offs = in_offset;
754 req->size = length; 784 req->size = length;
755 785
756 REQ_SEND; 786 REQ_SEND;
757} 787}
758 788
759void 789void
760aio_readahead (SV *fh, SV *offset, IV length, SV *callback=&PL_sv_undef) 790aio_readahead (SV *fh, off_t offset, size_t length, SV *callback=&PL_sv_undef)
761 PROTOTYPE: $$$;$ 791 PROTOTYPE: $$$;$
762 PPCODE: 792 PPCODE:
763{ 793{
764 int fd = extract_fd (fh, 0); 794 int fd = s_fileno_croak (fh, 0);
765 dREQ; 795 dREQ;
766 796
767 req->type = EIO_READAHEAD; 797 req->type = EIO_READAHEAD;
768 req->sv1 = newSVsv (fh); 798 req->sv1 = newSVsv (fh);
769 req->int1 = fd; 799 req->int1 = fd;
770 req->offs = SvVAL64 (offset); 800 req->offs = offset;
771 req->size = length; 801 req->size = length;
772 802
773 REQ_SEND; 803 REQ_SEND;
774} 804}
775 805
891 req->type = EIO_FCHOWN; 921 req->type = EIO_FCHOWN;
892 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path))); 922 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
893 } 923 }
894 924
895 REQ_SEND; 925 REQ_SEND;
926}
927
928void
929aio_readdirx (SV8 *pathname, IV flags, SV *callback=&PL_sv_undef)
930 PPCODE:
931{
932 dREQ;
933
934 req->type = EIO_READDIR;
935 req->sv1 = newSVsv (pathname);
936 req->ptr1 = SvPVbyte_nolen (req->sv1);
937 req->int1 = flags | EIO_READDIR_DENTS | EIO_READDIR_CUSTOM1;
938
939 if (flags & EIO_READDIR_DENTS)
940 req->int1 |= EIO_READDIR_CUSTOM2;
941
942 REQ_SEND;
896} 943}
897 944
898void 945void
899aio_unlink (SV8 *pathname, SV *callback=&PL_sv_undef) 946aio_unlink (SV8 *pathname, SV *callback=&PL_sv_undef)
900 ALIAS: 947 ALIAS:
1028 1075
1029int 1076int
1030poll_fileno() 1077poll_fileno()
1031 PROTOTYPE: 1078 PROTOTYPE:
1032 CODE: 1079 CODE:
1033 RETVAL = respipe [0]; 1080 RETVAL = s_epipe_fd (&respipe);
1034 OUTPUT: 1081 OUTPUT:
1035 RETVAL 1082 RETVAL
1036 1083
1037int 1084int
1038poll_cb(...) 1085poll_cb(...)
1078 CODE: 1125 CODE:
1079 RETVAL = eio_nthreads (); 1126 RETVAL = eio_nthreads ();
1080 OUTPUT: 1127 OUTPUT:
1081 RETVAL 1128 RETVAL
1082 1129
1130int
1131fadvise (aio_rfd fh, off_t offset, off_t length, IV advice)
1132 PROTOTYPE: $$$$
1133 CODE:
1134#if _XOPEN_SOURCE >= 600 && !NO_FADVISE
1135 RETVAL = posix_fadvise (fh, offset, length, advice);
1136#else
1137 RETVAL = errno = ENOSYS;
1138#endif
1139 OUTPUT:
1140 RETVAL
1141
1142ssize_t
1143sendfile (aio_wfd ofh, aio_rfd ifh, off_t offset, size_t count)
1144 PROTOTYPE: $$$$
1145 CODE:
1146 eio_sendfile_sync (ofh, ifh, offset, count);
1147
1083void _on_next_submit (SV *cb) 1148void _on_next_submit (SV *cb)
1084 CODE: 1149 CODE:
1085 SvREFCNT_dec (on_next_submit); 1150 SvREFCNT_dec (on_next_submit);
1086 on_next_submit = SvOK (cb) ? newSVsv (cb) : 0; 1151 on_next_submit = SvOK (cb) ? newSVsv (cb) : 0;
1087 1152
1101 if (GIMME_V != G_VOID) 1166 if (GIMME_V != G_VOID)
1102 XPUSHs (req->callback ? sv_2mortal (newRV_inc (req->callback)) : &PL_sv_undef); 1167 XPUSHs (req->callback ? sv_2mortal (newRV_inc (req->callback)) : &PL_sv_undef);
1103 1168
1104 if (items > 1) 1169 if (items > 1)
1105 { 1170 {
1106 SV *cb_cv = get_cb (callback); 1171 SV *cb_cv =get_cb (callback);
1107 1172
1108 SvREFCNT_dec (req->callback); 1173 SvREFCNT_dec (req->callback);
1109 req->callback = SvREFCNT_inc (cb_cv); 1174 req->callback = SvREFCNT_inc (cb_cv);
1110 } 1175 }
1111} 1176}
1148 AV *av; 1213 AV *av;
1149 1214
1150 grp->errorno = errno; 1215 grp->errorno = errno;
1151 1216
1152 av = newAV (); 1217 av = newAV ();
1218 av_extend (av, items - 1);
1153 1219
1154 for (i = 1; i < items; ++i ) 1220 for (i = 1; i < items; ++i )
1155 av_push (av, newSVsv (ST (i))); 1221 av_push (av, newSVsv (ST (i)));
1156 1222
1157 SvREFCNT_dec (grp->sv1); 1223 SvREFCNT_dec (grp->sv1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines