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.202 by root, Thu Sep 29 10:01:35 2011 UTC vs.
Revision 1.209 by root, Sun Apr 1 17:46:02 2012 UTC

62 #undef dup 62 #undef dup
63 #undef dup2 63 #undef dup2
64 #undef abort 64 #undef abort
65 #undef pipe 65 #undef pipe
66 66
67 #define EIO_STRUCT_STAT struct _stati64
68 #define EIO_STRUCT_STATI64
69
67#else 70#else
68 71
69 #include <sys/time.h> 72 #include <sys/time.h>
70 #include <sys/select.h> 73 #include <sys/select.h>
71 #include <unistd.h> 74 #include <unistd.h>
72 #include <utime.h> 75 #include <utime.h>
73 #include <signal.h> 76 #include <signal.h>
74 77
75#endif
76
77#define EIO_STRUCT_STAT Stat_t 78 #define EIO_STRUCT_STAT Stat_t
79
80#endif
78 81
79/* use NV for 32 bit perls as it allows larger offsets */ 82/* use NV for 32 bit perls as it allows larger offsets */
80#if IVSIZE >= 8 83#if IVSIZE >= 8
81# define VAL64 IV 84# define VAL64 IV
82# define SvVAL64 SvIV 85# define SvVAL64 SvIV
371} 374}
372 375
373static SV * 376static SV *
374newSVaio_wd (aio_wd wd) 377newSVaio_wd (aio_wd wd)
375{ 378{
376 return sv_bless (newRV_noinc (newSViv ((long)wd)), aio_wd_stash); 379 return sv_bless (newRV_noinc (newSViv ((IV)wd)), aio_wd_stash);
377} 380}
378 381
379static aio_req 382static aio_req
380SvAIO_REQ (SV *sv) 383SvAIO_REQ (SV *sv)
381{ 384{
382 MAGIC *mg; 385 MAGIC *mg;
383 386
384 if (!SvROK (sv) 387 if (!SvROK (sv)
388 /* for speed reasons, we do not verify that SvROK actually has a stash ptr */
385 || (SvSTASH (SvRV (sv)) != aio_grp_stash 389 || (SvSTASH (SvRV (sv)) != aio_grp_stash
386 && SvSTASH (SvRV (sv)) != aio_req_stash 390 && SvSTASH (SvRV (sv)) != aio_req_stash
387 && !sv_derived_from (sv, "IO::AIO::REQ"))) 391 && !sv_derived_from (sv, "IO::AIO::REQ")))
388 croak ("object of class IO::AIO::REQ expected"); 392 croak ("object of class IO::AIO::REQ expected");
389 393
394 398
395static aio_wd 399static aio_wd
396SvAIO_WD (SV *sv) 400SvAIO_WD (SV *sv)
397{ 401{
398 if (!SvROK (sv) 402 if (!SvROK (sv)
403 || SvTYPE (SvRV (sv)) != SVt_PVMG
399 || SvSTASH (SvRV (sv)) != aio_wd_stash 404 || SvSTASH (SvRV (sv)) != aio_wd_stash)
400 || SvTYPE (SvRV (sv)) != SVt_PVMG)
401 croak ("IO::AIO: expected a working directory object as returned by aio_wd"); 405 croak ("IO::AIO: expected a working directory object as returned by aio_wd");
402 406
403 return (aio_wd)(long)SvIVX (SvRV (sv)); 407 return (aio_wd)(long)SvIVX (SvRV (sv));
404} 408}
405 409
471 } 475 }
472 476
473 switch (req->type) 477 switch (req->type)
474 { 478 {
475 case EIO_WD_OPEN: 479 case EIO_WD_OPEN:
476 PUSHs (sv_2mortal (newSVaio_wd (req->wd))); 480 PUSHs (req->result ? &PL_sv_undef : sv_2mortal (newSVaio_wd (req->wd)));
477 break; 481 break;
478 482
479 case EIO_READDIR: 483 case EIO_READDIR:
480 { 484 {
481 SV *rv = &PL_sv_undef; 485 SV *rv = &PL_sv_undef;
634 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); 638 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2);
635 639
636 PUSHs (sv_result); 640 PUSHs (sv_result);
637 break; 641 break;
638 642
643 case EIO_SEEK:
644 PUSHs (req->result ? sv_result : sv_2mortal (newSVval64 (req->offs)));
645 break;
646
639 case EIO_READ: 647 case EIO_READ:
640 { 648 {
641 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); 649 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0));
642 *SvEND (req->sv2) = 0; 650 *SvEND (req->sv2) = 0;
643 SvPOK_only (req->sv2); 651 SvPOK_only (req->sv2);
689 SvREFCNT_dec (req->sv2); 697 SvREFCNT_dec (req->sv2);
690 SvREFCNT_dec (req->sv3); 698 SvREFCNT_dec (req->sv3);
691 SvREFCNT_dec (req->sv4); 699 SvREFCNT_dec (req->sv4);
692 SvREFCNT_dec (req->callback); 700 SvREFCNT_dec (req->callback);
693 701
694 Safefree (req); 702 free (req);
695} 703}
696 704
697static void 705static void
698req_cancel_subs (aio_req grp) 706req_cancel_subs (aio_req grp)
699{ 707{
809{ 817{
810 SvGETMAGIC (cb_sv); 818 SvGETMAGIC (cb_sv);
811 return SvOK (cb_sv) ? s_get_cv_croak (cb_sv) : 0; 819 return SvOK (cb_sv) ? s_get_cv_croak (cb_sv) : 0;
812} 820}
813 821
822static aio_req ecb_noinline
823dreq (SV *callback)
824{
825 SV *cb_cv;
826 aio_req req;
827 int req_pri = next_pri;
828 next_pri = EIO_PRI_DEFAULT;
829
830 cb_cv = get_cb (callback);
831
832 req = calloc (sizeof (*req), 1);
833 if (!req)
834 croak ("out of memory during eio_req allocation");
835
836 req->callback = SvREFCNT_inc (cb_cv);
837 req->pri = req_pri;
838
839 return req;
840}
841
814#define dREQ \ 842#define dREQ \
815 SV *cb_cv; \ 843 aio_req req = dreq (callback); \
816 aio_req req; \
817 int req_pri = next_pri; \
818 next_pri = EIO_PRI_DEFAULT; \
819 \
820 cb_cv = get_cb (callback); \
821 \
822 Newz (0, req, 1, eio_req); \
823 if (!req) \
824 croak ("out of memory during eio_req allocation"); \
825 \
826 req->callback = SvREFCNT_inc (cb_cv); \
827 req->pri = req_pri
828 844
829#define REQ_SEND \ 845#define REQ_SEND \
830 PUTBACK; \ 846 PUTBACK; \
831 req_submit (req); \ 847 req_submit (req); \
832 SPAGAIN; \ 848 SPAGAIN; \
837ecb_inline void 853ecb_inline void
838req_set_path (aio_req req, SV *path, SV **wdsv, SV **pathsv, eio_wd *wd, void **ptr) 854req_set_path (aio_req req, SV *path, SV **wdsv, SV **pathsv, eio_wd *wd, void **ptr)
839{ 855{
840 if (expect_false (SvROK (path))) 856 if (expect_false (SvROK (path)))
841 { 857 {
842 AV *av = (AV *)SvRV (path); 858 SV *rv = SvRV (path);
843 SV *wdob; 859 SV *wdob;
844 860
845 if (SvTYPE (av) != SVt_PVAV || AvFILLp (av) != 1) 861 if (SvTYPE (rv) == SVt_PVAV && AvFILLp (rv) == 1)
846 croak ("IO::AIO: pathname arguments must be specified as strings or [wd, path] arrayrefs");
847
848 path = AvARRAY (av)[1];
849 wdob = AvARRAY (av)[0];
850
851 if (SvOK (wdob))
852 { 862 {
863 path = AvARRAY (rv)[1];
864 wdob = AvARRAY (rv)[0];
865
866 if (SvOK (wdob))
867 {
853 *wd = SvAIO_WD (wdob); 868 *wd = SvAIO_WD (wdob);
854 *wdsv = SvREFCNT_inc_NN (SvRV (wdob)); 869 *wdsv = SvREFCNT_inc_NN (SvRV (wdob));
870 }
871 else
872 *wd = EIO_INVALID_WD;
873 }
874 else if (SvTYPE (rv) == SVt_PVMG && SvSTASH (rv) == aio_wd_stash)
875 {
876 *wd = (aio_wd)(long)SvIVX (rv);
877 *wdsv = SvREFCNT_inc_NN (rv);
878 *ptr = ".";
879 return; /* path set to "." */
855 } 880 }
856 else 881 else
857 *wd = EIO_INVALID_WD; 882 croak ("IO::AIO: pathname arguments must be specified as a string, an IO::AIO::WD object or a [IO::AIO::WD, path] pair");
858 } 883 }
859 884
860 *pathsv = newSVsv (path); 885 *pathsv = newSVsv (path);
861 *ptr = SvPVbyte_nolen (*pathsv); 886 *ptr = SvPVbyte_nolen (*pathsv);
862} 887}
981 const_iv (MAP_LOCKED) 1006 const_iv (MAP_LOCKED)
982 const_iv (MAP_NORESERVE) 1007 const_iv (MAP_NORESERVE)
983 const_iv (MAP_POPULATE) 1008 const_iv (MAP_POPULATE)
984 const_iv (MAP_NONBLOCK) 1009 const_iv (MAP_NONBLOCK)
985 1010
1011 const_eio (SEEK_SET)
1012 const_eio (SEEK_CUR)
1013 const_eio (SEEK_END)
1014
986 const_eio (MCL_FUTURE) 1015 const_eio (MCL_FUTURE)
987 const_eio (MCL_CURRENT) 1016 const_eio (MCL_CURRENT)
988 1017
989 const_eio (MS_ASYNC) 1018 const_eio (MS_ASYNC)
990 const_eio (MS_INVALIDATE) 1019 const_eio (MS_INVALIDATE)
1112 1141
1113 req->type = ix; 1142 req->type = ix;
1114 req->sv1 = newSVsv (fh); 1143 req->sv1 = newSVsv (fh);
1115 req->int1 = fd; 1144 req->int1 = fd;
1116 1145
1117 REQ_SEND (req); 1146 REQ_SEND;
1118} 1147}
1119 1148
1120void 1149void
1121aio_sync_file_range (SV *fh, off_t offset, size_t nbytes, UV flags, SV *callback=&PL_sv_undef) 1150aio_sync_file_range (SV *fh, off_t offset, size_t nbytes, UV flags, SV *callback=&PL_sv_undef)
1122 PPCODE: 1151 PPCODE:
1129 req->int1 = fd; 1158 req->int1 = fd;
1130 req->offs = offset; 1159 req->offs = offset;
1131 req->size = nbytes; 1160 req->size = nbytes;
1132 req->int2 = flags; 1161 req->int2 = flags;
1133 1162
1134 REQ_SEND (req); 1163 REQ_SEND;
1135} 1164}
1136 1165
1137void 1166void
1138aio_fallocate (SV *fh, int mode, off_t offset, size_t len, SV *callback=&PL_sv_undef) 1167aio_fallocate (SV *fh, int mode, off_t offset, size_t len, SV *callback=&PL_sv_undef)
1139 PPCODE: 1168 PPCODE:
1146 req->int1 = fd; 1175 req->int1 = fd;
1147 req->int2 = mode; 1176 req->int2 = mode;
1148 req->offs = offset; 1177 req->offs = offset;
1149 req->size = len; 1178 req->size = len;
1150 1179
1151 REQ_SEND (req); 1180 REQ_SEND;
1152} 1181}
1153 1182
1154void 1183void
1155aio_close (SV *fh, SV *callback=&PL_sv_undef) 1184aio_close (SV *fh, SV *callback=&PL_sv_undef)
1156 PPCODE: 1185 PPCODE:
1180 req->type = EIO_DUP2; 1209 req->type = EIO_DUP2;
1181 req->int1 = close_fd; 1210 req->int1 = close_fd;
1182 req->sv2 = newSVsv (fh); 1211 req->sv2 = newSVsv (fh);
1183 req->int2 = fd; 1212 req->int2 = fd;
1184 1213
1185 REQ_SEND (req); 1214 REQ_SEND;
1215}
1216
1217void
1218aio_seek (SV *fh, SV *offset, int whence, SV *callback=&PL_sv_undef)
1219 PPCODE:
1220{
1221 STRLEN svlen;
1222 int fd = s_fileno_croak (fh, 0);
1223 dREQ;
1224
1225 req->type = EIO_SEEK;
1226 req->sv1 = newSVsv (fh);
1227 req->int1 = fd;
1228 req->offs = SvVAL64 (offset);
1229 req->int2 = whence;
1230
1231 REQ_SEND;
1186} 1232}
1187 1233
1188void 1234void
1189aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef) 1235aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef)
1190 ALIAS: 1236 ALIAS:
1296 aio_statvfs = EIO_STATVFS 1342 aio_statvfs = EIO_STATVFS
1297 PPCODE: 1343 PPCODE:
1298{ 1344{
1299 dREQ; 1345 dREQ;
1300 1346
1301 req->sv1 = newSVsv (fh_or_path);
1302 req_set_fh_or_path (req, ix, ix == EIO_STATVFS ? EIO_FSTATVFS : EIO_FSTAT, fh_or_path); 1347 req_set_fh_or_path (req, ix, ix == EIO_STATVFS ? EIO_FSTATVFS : EIO_FSTAT, fh_or_path);
1348
1303 REQ_SEND; 1349 REQ_SEND;
1304} 1350}
1305 1351
1306UV 1352UV
1307major (UV dev) 1353major (UV dev)
1421 aio_link = EIO_LINK 1467 aio_link = EIO_LINK
1422 aio_symlink = EIO_SYMLINK 1468 aio_symlink = EIO_SYMLINK
1423 aio_rename = EIO_RENAME 1469 aio_rename = EIO_RENAME
1424 PPCODE: 1470 PPCODE:
1425{ 1471{
1472 eio_wd wd2 = 0;
1426 dREQ; 1473 dREQ;
1427 eio_wd wd2 = 0;
1428 1474
1429 req->type = ix; 1475 req->type = ix;
1430 req_set_path1 (req, oldpath); 1476 req_set_path1 (req, oldpath);
1431 req_set_path (req, newpath, &req->sv2, &req->sv4, &wd2, &req->ptr2); 1477 req_set_path (req, newpath, &req->sv2, &req->sv4, &wd2, &req->ptr2);
1432 req->int3 = (long)wd2; 1478 req->int3 = (long)wd2;
1787DESTROY (SV *self) 1833DESTROY (SV *self)
1788 CODE: 1834 CODE:
1789{ 1835{
1790 aio_wd wd = SvAIO_WD (self); 1836 aio_wd wd = SvAIO_WD (self);
1791#if HAVE_AT 1837#if HAVE_AT
1838 {
1792 SV *callback = &PL_sv_undef; 1839 SV *callback = &PL_sv_undef;
1793 dREQ; /* clobbers next_pri :/ */ 1840 dREQ; /* clobbers next_pri :/ */
1841 next_pri = req->pri; /* restore next_pri */
1842 req->pri = EIO_PRI_MAX; /* better use max. priority to conserve fds */
1794 req->type = EIO_WD_CLOSE; 1843 req->type = EIO_WD_CLOSE;
1795 req->wd = wd; 1844 req->wd = wd;
1796 REQ_SEND; 1845 REQ_SEND;
1846 }
1797#else 1847#else
1798 eio_wd_close_sync (wd); 1848 eio_wd_close_sync (wd);
1799#endif 1849#endif
1800} 1850}
1801 1851

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines