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.98 by root, Wed May 9 06:45:12 2007 UTC vs.
Revision 1.102 by root, Sun Jun 3 09:44:17 2007 UTC

18#include <limits.h> 18#include <limits.h>
19#include <unistd.h> 19#include <unistd.h>
20#include <fcntl.h> 20#include <fcntl.h>
21#include <signal.h> 21#include <signal.h>
22#include <sched.h> 22#include <sched.h>
23#include <utime.h>
23 24
24#if HAVE_SENDFILE 25#if HAVE_SENDFILE
25# if __linux 26# if __linux
26# include <sys/sendfile.h> 27# include <sys/sendfile.h>
27# elif __freebsd 28# elif __freebsd
45#endif 46#endif
46 47
47/* buffer size for various temporary buffers */ 48/* buffer size for various temporary buffers */
48#define AIO_BUFSIZE 65536 49#define AIO_BUFSIZE 65536
49 50
51/* use NV for 32 bit perls as it allows larger offsets */
52#if IVSIZE >= 8
53# define SvVAL64 SvIV
54#else
55# define SvVAL64 SvNV
56#endif
57
50#define dBUF \ 58#define dBUF \
51 char *aio_buf; \ 59 char *aio_buf; \
52 LOCK (wrklock); \ 60 LOCK (wrklock); \
53 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \ 61 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \
54 UNLOCK (wrklock); \ 62 UNLOCK (wrklock); \
58typedef SV SV8; /* byte-sv, used for argument-checking */ 66typedef SV SV8; /* byte-sv, used for argument-checking */
59 67
60enum { 68enum {
61 REQ_QUIT, 69 REQ_QUIT,
62 REQ_OPEN, REQ_CLOSE, 70 REQ_OPEN, REQ_CLOSE,
63 REQ_READ, REQ_WRITE, REQ_READAHEAD, 71 REQ_READ, REQ_WRITE,
64 REQ_SENDFILE, 72 REQ_READAHEAD, REQ_SENDFILE,
65 REQ_STAT, REQ_LSTAT, REQ_FSTAT, 73 REQ_STAT, REQ_LSTAT, REQ_FSTAT,
74 REQ_UTIME, REQ_FUTIME,
75 REQ_CHMOD, REQ_FCHMOD,
76 REQ_CHOWN, REQ_FCHOWN,
66 REQ_FSYNC, REQ_FDATASYNC, 77 REQ_FSYNC, REQ_FDATASYNC,
67 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, 78 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME,
68 REQ_MKNOD, REQ_READDIR, 79 REQ_MKNOD, REQ_READDIR,
69 REQ_LINK, REQ_SYMLINK, REQ_READLINK, 80 REQ_LINK, REQ_SYMLINK, REQ_READLINK,
70 REQ_GROUP, REQ_NOP, 81 REQ_GROUP, REQ_NOP,
76 87
77typedef struct aio_cb 88typedef struct aio_cb
78{ 89{
79 struct aio_cb *volatile next; 90 struct aio_cb *volatile next;
80 91
81 SV *callback, *fh; 92 SV *callback;
82 SV *sv1, *sv2; 93 SV *sv1, *sv2;
83 void *ptr1, *ptr2; 94 void *ptr1, *ptr2;
84 off_t offs; 95 off_t offs;
85 size_t size; 96 size_t size;
86 ssize_t result; 97 ssize_t result;
98 double nv1, nv2;
87 99
88 STRLEN stroffset; 100 STRLEN stroffset;
89 int type; 101 int type;
90 int int1, int2; 102 int int1, int2, int3;
91 int errorno; 103 int errorno;
92 mode_t mode; /* open */ 104 mode_t mode; /* open */
93 105
94 unsigned char flags; 106 unsigned char flags;
95 unsigned char pri; 107 unsigned char pri;
98 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first; 110 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first;
99} aio_cb; 111} aio_cb;
100 112
101enum { 113enum {
102 FLAG_CANCELLED = 0x01, /* request was cancelled */ 114 FLAG_CANCELLED = 0x01, /* request was cancelled */
103 FLAG_SV1_RO_OFF = 0x40, /* data was set readonly */ 115 FLAG_SV2_RO_OFF = 0x40, /* data was set readonly */
104 FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */ 116 FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */
105}; 117};
106 118
107typedef aio_cb *aio_req; 119typedef aio_cb *aio_req;
108typedef aio_cb *aio_req_ornot; 120typedef aio_cb *aio_req_ornot;
312 abort (); 324 abort ();
313} 325}
314 326
315static int poll_cb (); 327static int poll_cb ();
316static int req_invoke (aio_req req); 328static int req_invoke (aio_req req);
317static void req_free (aio_req req); 329static void req_destroy (aio_req req);
318static void req_cancel (aio_req req); 330static void req_cancel (aio_req req);
319 331
320/* must be called at most once */ 332/* must be called at most once */
321static SV *req_sv (aio_req req, const char *klass) 333static SV *req_sv (aio_req req, const char *klass)
322{ 334{
388 { 400 {
389 block_sig (); 401 block_sig ();
390 402
391 if (!req_invoke (grp)) 403 if (!req_invoke (grp))
392 { 404 {
393 req_free (grp); 405 req_destroy (grp);
394 unblock_sig (); 406 unblock_sig ();
395 croak (0); 407 croak (0);
396 } 408 }
397 409
398 req_free (grp); 410 req_destroy (grp);
399 unblock_sig (); 411 unblock_sig ();
400 } 412 }
401} 413}
402 414
403static int req_invoke (aio_req req) 415static int req_invoke (aio_req req)
404{ 416{
405 dSP; 417 dSP;
406 418
407 if (req->flags & FLAG_SV1_RO_OFF) 419 if (req->flags & FLAG_SV2_RO_OFF)
408 SvREADONLY_off (req->sv1); 420 SvREADONLY_off (req->sv2);
409 421
410 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) 422 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback))
411 { 423 {
412 ENTER; 424 ENTER;
413 SAVETMPS; 425 SAVETMPS;
478 break; 490 break;
479 491
480 case REQ_READLINK: 492 case REQ_READLINK:
481 if (req->result > 0) 493 if (req->result > 0)
482 { 494 {
483 SvCUR_set (req->sv1, req->result); 495 SvCUR_set (req->sv2, req->result);
484 *SvEND (req->sv1) = 0; 496 *SvEND (req->sv2) = 0;
485 PUSHs (req->sv1); 497 PUSHs (req->sv2);
486 } 498 }
487 break; 499 break;
488 500
489 case REQ_STAT: 501 case REQ_STAT:
490 case REQ_LSTAT: 502 case REQ_LSTAT:
494 PL_statcache = *(Stat_t *)(req->ptr2); 506 PL_statcache = *(Stat_t *)(req->ptr2);
495 PUSHs (sv_2mortal (newSViv (req->result))); 507 PUSHs (sv_2mortal (newSViv (req->result)));
496 break; 508 break;
497 509
498 case REQ_READ: 510 case REQ_READ:
499 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); 511 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0));
500 *SvEND (req->sv1) = 0; 512 *SvEND (req->sv2) = 0;
501 PUSHs (sv_2mortal (newSViv (req->result))); 513 PUSHs (sv_2mortal (newSViv (req->result)));
502 break; 514 break;
503 515
504 default: 516 default:
505 PUSHs (sv_2mortal (newSViv (req->result))); 517 PUSHs (sv_2mortal (newSViv (req->result)));
531 } 543 }
532 544
533 return !SvTRUE (ERRSV); 545 return !SvTRUE (ERRSV);
534} 546}
535 547
536static void req_free (aio_req req) 548static void req_destroy (aio_req req)
537{ 549{
538 if (req->self) 550 if (req->self)
539 { 551 {
540 sv_unmagic (req->self, PERL_MAGIC_ext); 552 sv_unmagic (req->self, PERL_MAGIC_ext);
541 SvREFCNT_dec (req->self); 553 SvREFCNT_dec (req->self);
542 } 554 }
543 555
544 SvREFCNT_dec (req->fh);
545 SvREFCNT_dec (req->sv1); 556 SvREFCNT_dec (req->sv1);
546 SvREFCNT_dec (req->sv2); 557 SvREFCNT_dec (req->sv2);
547 SvREFCNT_dec (req->callback); 558 SvREFCNT_dec (req->callback);
548 559
549 if (req->flags & FLAG_PTR2_FREE) 560 if (req->flags & FLAG_PTR2_FREE)
571 req->flags |= FLAG_CANCELLED; 582 req->flags |= FLAG_CANCELLED;
572 583
573 req_cancel_subs (req); 584 req_cancel_subs (req);
574} 585}
575 586
576static void *aio_proc(void *arg); 587static void *aio_proc (void *arg);
577 588
578static void start_thread (void) 589static void start_thread (void)
579{ 590{
580 worker *wrk = calloc (1, sizeof (worker)); 591 worker *wrk = calloc (1, sizeof (worker));
581 592
741 } 752 }
742 else 753 else
743 { 754 {
744 if (!req_invoke (req)) 755 if (!req_invoke (req))
745 { 756 {
746 req_free (req); 757 req_destroy (req);
747 unblock_sig (); 758 unblock_sig ();
748 croak (0); 759 croak (0);
749 } 760 }
750 761
751 count++; 762 count++;
752 } 763 }
753 764
754 req_free (req); 765 req_destroy (req);
755 766
756 if (maxreqs && !--maxreqs) 767 if (maxreqs && !--maxreqs)
757 break; 768 break;
758 769
759 if (max_poll_time) 770 if (max_poll_time)
830 lseek (fd, offset, SEEK_SET); 841 lseek (fd, offset, SEEK_SET);
831 UNLOCK (preadwritelock); 842 UNLOCK (preadwritelock);
832 843
833 return res; 844 return res;
834} 845}
846#endif
847
848#ifndef HAVE_FUTIMES
849
850# define utimes(path,times) aio_utimes (path, times)
851# define futimes(fd,times) aio_futimes (fd, times)
852
853int aio_utimes (const char *filename, const struct timeval times[2])
854{
855 if (times)
856 {
857 struct utimbuf buf;
858
859 buf.actime = times[0].tv_sec;
860 buf.modtime = times[1].tv_sec;
861
862 return utime (filename, &buf);
863 }
864 else
865 return utime (filename, 0);
866}
867
868int aio_futimes (int fd, const struct timeval tv[2])
869{
870 errno = ENOSYS;
871 return -1;
872}
873
835#endif 874#endif
836 875
837#if !HAVE_FDATASYNC 876#if !HAVE_FDATASYNC
838# define fdatasync fsync 877# define fdatasync fsync
839#endif 878#endif
1099 errno = 0; /* strictly unnecessary */ 1138 errno = 0; /* strictly unnecessary */
1100 1139
1101 if (!(req->flags & FLAG_CANCELLED)) 1140 if (!(req->flags & FLAG_CANCELLED))
1102 switch (req->type) 1141 switch (req->type)
1103 { 1142 {
1104 case REQ_READ: req->result = pread (req->int1, req->ptr1, req->size, req->offs); break; 1143 case REQ_READ: req->result = req->offs >= 0
1105 case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; 1144 ? pread (req->int1, req->ptr1, req->size, req->offs)
1145 : read (req->int1, req->ptr1, req->size); break;
1146 case REQ_WRITE: req->result = req->offs >= 0
1147 ? pwrite (req->int1, req->ptr1, req->size, req->offs)
1148 : write (req->int1, req->ptr1, req->size); break;
1106 1149
1107 case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; 1150 case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break;
1108 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; 1151 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break;
1109 1152
1110 case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break; 1153 case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break;
1111 case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break; 1154 case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break;
1112 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break; 1155 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break;
1156
1157 case REQ_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break;
1158 case REQ_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break;
1159 case REQ_CHMOD: req->result = chmod (req->ptr1, req->mode); break;
1160 case REQ_FCHMOD: req->result = fchmod (req->int1, req->mode); break;
1113 1161
1114 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; 1162 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break;
1115 case REQ_CLOSE: req->result = close (req->int1); break; 1163 case REQ_CLOSE: req->result = close (req->int1); break;
1116 case REQ_UNLINK: req->result = unlink (req->ptr1); break; 1164 case REQ_UNLINK: req->result = unlink (req->ptr1); break;
1117 case REQ_RMDIR: req->result = rmdir (req->ptr1); break; 1165 case REQ_RMDIR: req->result = rmdir (req->ptr1); break;
1128 1176
1129 case REQ_BUSY: 1177 case REQ_BUSY:
1130 { 1178 {
1131 struct timeval tv; 1179 struct timeval tv;
1132 1180
1133 tv.tv_sec = req->int1; 1181 tv.tv_sec = req->nv1;
1134 tv.tv_usec = req->int2; 1182 tv.tv_usec = (req->nv1 - tv.tv_usec) * 1000000.;
1135 1183
1136 req->result = select (0, 0, 0, 0, &tv); 1184 req->result = select (0, 0, 0, 0, &tv);
1185 }
1186
1187 case REQ_UTIME:
1188 case REQ_FUTIME:
1189 {
1190 struct timeval tv[2];
1191 struct timeval *times;
1192
1193 if (req->nv1 != -1. || req->nv2 != -1.)
1194 {
1195 tv[0].tv_sec = req->nv1;
1196 tv[0].tv_usec = (req->nv1 - tv[0].tv_sec) * 1000000.;
1197 tv[1].tv_sec = req->nv2;
1198 tv[1].tv_usec = (req->nv2 - tv[1].tv_sec) * 1000000.;
1199
1200 times = tv;
1201 }
1202 else
1203 times = 0;
1204
1205
1206 req->result = req->type == REQ_FUTIME
1207 ? futimes (req->int1, times)
1208 : utimes (req->ptr1, times);
1137 } 1209 }
1138 1210
1139 case REQ_GROUP: 1211 case REQ_GROUP:
1140 case REQ_NOP: 1212 case REQ_NOP:
1141 break; 1213 break;
1142 1214
1143 case REQ_QUIT: 1215 case REQ_QUIT:
1144 goto quit; 1216 goto quit;
1145 1217
1146 default: 1218 default:
1147 req->result = ENOSYS; 1219 req->result = -1;
1148 break; 1220 break;
1149 } 1221 }
1150 1222
1151 req->errorno = errno; 1223 req->errorno = errno;
1152 1224
1209static void atfork_child (void) 1281static void atfork_child (void)
1210{ 1282{
1211 aio_req prv; 1283 aio_req prv;
1212 1284
1213 while (prv = reqq_shift (&req_queue)) 1285 while (prv = reqq_shift (&req_queue))
1214 req_free (prv); 1286 req_destroy (prv);
1215 1287
1216 while (prv = reqq_shift (&res_queue)) 1288 while (prv = reqq_shift (&res_queue))
1217 req_free (prv); 1289 req_destroy (prv);
1218 1290
1219 while (wrk_first.next != &wrk_first) 1291 while (wrk_first.next != &wrk_first)
1220 { 1292 {
1221 worker *wrk = wrk_first.next; 1293 worker *wrk = wrk_first.next;
1222 1294
1223 if (wrk->req) 1295 if (wrk->req)
1224 req_free (wrk->req); 1296 req_destroy (wrk->req);
1225 1297
1226 worker_clear (wrk); 1298 worker_clear (wrk);
1227 worker_free (wrk); 1299 worker_free (wrk);
1228 } 1300 }
1229 1301
1315 max_outstanding = maxreqs; 1387 max_outstanding = maxreqs;
1316 OUTPUT: 1388 OUTPUT:
1317 RETVAL 1389 RETVAL
1318 1390
1319void 1391void
1320aio_open (pathname,flags,mode,callback=&PL_sv_undef) 1392aio_open (SV8 *pathname, int flags, int mode, SV *callback=&PL_sv_undef)
1321 SV8 * pathname
1322 int flags
1323 int mode
1324 SV * callback
1325 PROTOTYPE: $$$;$ 1393 PROTOTYPE: $$$;$
1326 PPCODE: 1394 PPCODE:
1327{ 1395{
1328 dREQ; 1396 dREQ;
1329 1397
1335 1403
1336 REQ_SEND; 1404 REQ_SEND;
1337} 1405}
1338 1406
1339void 1407void
1340aio_close (fh,callback=&PL_sv_undef) 1408aio_close (SV *fh, SV *callback=&PL_sv_undef)
1341 SV * fh
1342 SV * callback
1343 PROTOTYPE: $;$ 1409 PROTOTYPE: $;$
1344 ALIAS: 1410 ALIAS:
1345 aio_close = REQ_CLOSE 1411 aio_close = REQ_CLOSE
1346 aio_fsync = REQ_FSYNC 1412 aio_fsync = REQ_FSYNC
1347 aio_fdatasync = REQ_FDATASYNC 1413 aio_fdatasync = REQ_FDATASYNC
1348 PPCODE: 1414 PPCODE:
1349{ 1415{
1350 dREQ; 1416 dREQ;
1351 1417
1352 req->type = ix; 1418 req->type = ix;
1353 req->fh = newSVsv (fh); 1419 req->sv1 = newSVsv (fh);
1354 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1420 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1355 1421
1356 REQ_SEND (req); 1422 REQ_SEND (req);
1357} 1423}
1358 1424
1359void 1425void
1360aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef) 1426aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef)
1361 SV * fh
1362 UV offset
1363 UV length
1364 SV8 * data
1365 UV dataoffset
1366 SV * callback
1367 ALIAS: 1427 ALIAS:
1368 aio_read = REQ_READ 1428 aio_read = REQ_READ
1369 aio_write = REQ_WRITE 1429 aio_write = REQ_WRITE
1370 PROTOTYPE: $$$$$;$ 1430 PROTOTYPE: $$$$$;$
1371 PPCODE: 1431 PPCODE:
1372{ 1432{
1373 STRLEN svlen; 1433 STRLEN svlen;
1374 char *svptr = SvPVbyte (data, svlen); 1434 char *svptr = SvPVbyte (data, svlen);
1435 UV len = SvUV (length);
1375 1436
1376 SvUPGRADE (data, SVt_PV); 1437 SvUPGRADE (data, SVt_PV);
1377 SvPOK_on (data); 1438 SvPOK_on (data);
1378 1439
1379 if (dataoffset < 0) 1440 if (dataoffset < 0)
1380 dataoffset += svlen; 1441 dataoffset += svlen;
1381 1442
1382 if (dataoffset < 0 || dataoffset > svlen) 1443 if (dataoffset < 0 || dataoffset > svlen)
1383 croak ("data offset outside of string"); 1444 croak ("dataoffset outside of data scalar");
1384 1445
1385 if (ix == REQ_WRITE) 1446 if (ix == REQ_WRITE)
1386 { 1447 {
1387 /* write: check length and adjust. */ 1448 /* write: check length and adjust. */
1388 if (length < 0 || length + dataoffset > svlen) 1449 if (!SvOK (length) || len + dataoffset > svlen)
1389 length = svlen - dataoffset; 1450 len = svlen - dataoffset;
1390 } 1451 }
1391 else 1452 else
1392 { 1453 {
1393 /* read: grow scalar as necessary */ 1454 /* read: grow scalar as necessary */
1394 svptr = SvGROW (data, length + dataoffset + 1); 1455 svptr = SvGROW (data, len + dataoffset + 1);
1395 } 1456 }
1396 1457
1397 if (length < 0) 1458 if (len < 0)
1398 croak ("length must not be negative"); 1459 croak ("length must not be negative");
1399 1460
1400 { 1461 {
1401 dREQ; 1462 dREQ;
1402 1463
1403 req->type = ix; 1464 req->type = ix;
1404 req->fh = newSVsv (fh); 1465 req->sv1 = newSVsv (fh);
1405 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh)) 1466 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh))
1406 : IoOFP (sv_2io (fh))); 1467 : IoOFP (sv_2io (fh)));
1407 req->offs = offset; 1468 req->offs = SvOK (offset) ? SvVAL64 (offset) : -1;
1408 req->size = length; 1469 req->size = len;
1409 req->sv1 = SvREFCNT_inc (data); 1470 req->sv2 = SvREFCNT_inc (data);
1410 req->ptr1 = (char *)svptr + dataoffset; 1471 req->ptr1 = (char *)svptr + dataoffset;
1411 req->stroffset = dataoffset; 1472 req->stroffset = dataoffset;
1412 1473
1413 if (!SvREADONLY (data)) 1474 if (!SvREADONLY (data))
1414 { 1475 {
1415 SvREADONLY_on (data); 1476 SvREADONLY_on (data);
1416 req->flags |= FLAG_SV1_RO_OFF; 1477 req->flags |= FLAG_SV2_RO_OFF;
1417 } 1478 }
1418 1479
1419 REQ_SEND; 1480 REQ_SEND;
1420 } 1481 }
1421} 1482}
1422 1483
1423void 1484void
1424aio_readlink (path,callback=&PL_sv_undef) 1485aio_readlink (SV8 *path, SV *callback=&PL_sv_undef)
1425 SV8 * path
1426 SV * callback
1427 PROTOTYPE: $$;$ 1486 PROTOTYPE: $$;$
1428 PPCODE: 1487 PPCODE:
1429{ 1488{
1430 SV *data; 1489 SV *data;
1431 dREQ; 1490 dREQ;
1432 1491
1433 data = newSV (NAME_MAX); 1492 data = newSV (NAME_MAX);
1434 SvPOK_on (data); 1493 SvPOK_on (data);
1435 1494
1436 req->type = REQ_READLINK; 1495 req->type = REQ_READLINK;
1437 req->fh = newSVsv (path); 1496 req->sv1 = newSVsv (path);
1438 req->ptr2 = SvPVbyte_nolen (req->fh); 1497 req->ptr2 = SvPVbyte_nolen (req->sv1);
1439 req->sv1 = data; 1498 req->sv2 = data;
1440 req->ptr1 = SvPVbyte_nolen (data); 1499 req->ptr1 = SvPVbyte_nolen (data);
1441 1500
1442 REQ_SEND; 1501 REQ_SEND;
1443} 1502}
1444 1503
1445void 1504void
1446aio_sendfile (out_fh,in_fh,in_offset,length,callback=&PL_sv_undef) 1505aio_sendfile (SV *out_fh, SV *in_fh, SV *in_offset, UV length, SV *callback=&PL_sv_undef)
1447 SV * out_fh
1448 SV * in_fh
1449 UV in_offset
1450 UV length
1451 SV * callback
1452 PROTOTYPE: $$$$;$ 1506 PROTOTYPE: $$$$;$
1453 PPCODE: 1507 PPCODE:
1454{ 1508{
1455 dREQ; 1509 dREQ;
1456 1510
1457 req->type = REQ_SENDFILE; 1511 req->type = REQ_SENDFILE;
1458 req->fh = newSVsv (out_fh); 1512 req->sv1 = newSVsv (out_fh);
1459 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); 1513 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh)));
1460 req->sv2 = newSVsv (in_fh); 1514 req->sv2 = newSVsv (in_fh);
1461 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); 1515 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh)));
1462 req->offs = in_offset; 1516 req->offs = SvVAL64 (in_offset);
1463 req->size = length; 1517 req->size = length;
1464 1518
1465 REQ_SEND; 1519 REQ_SEND;
1466} 1520}
1467 1521
1468void 1522void
1469aio_readahead (fh,offset,length,callback=&PL_sv_undef) 1523aio_readahead (SV *fh, SV *offset, IV length, SV *callback=&PL_sv_undef)
1470 SV * fh
1471 UV offset
1472 IV length
1473 SV * callback
1474 PROTOTYPE: $$$;$ 1524 PROTOTYPE: $$$;$
1475 PPCODE: 1525 PPCODE:
1476{ 1526{
1477 dREQ; 1527 dREQ;
1478 1528
1479 req->type = REQ_READAHEAD; 1529 req->type = REQ_READAHEAD;
1480 req->fh = newSVsv (fh); 1530 req->sv1 = newSVsv (fh);
1481 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1531 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1482 req->offs = offset; 1532 req->offs = SvVAL64 (offset);
1483 req->size = length; 1533 req->size = length;
1484 1534
1485 REQ_SEND; 1535 REQ_SEND;
1486} 1536}
1487 1537
1488void 1538void
1489aio_stat (fh_or_path,callback=&PL_sv_undef) 1539aio_stat (SV8 *fh_or_path, SV *callback=&PL_sv_undef)
1490 SV8 * fh_or_path
1491 SV * callback
1492 ALIAS: 1540 ALIAS:
1493 aio_stat = REQ_STAT 1541 aio_stat = REQ_STAT
1494 aio_lstat = REQ_LSTAT 1542 aio_lstat = REQ_LSTAT
1495 PPCODE: 1543 PPCODE:
1496{ 1544{
1497 dREQ; 1545 dREQ;
1498 1546
1499 req->ptr2 = malloc (sizeof (Stat_t)); 1547 req->ptr2 = malloc (sizeof (Stat_t));
1500 if (!req->ptr2) 1548 if (!req->ptr2)
1501 { 1549 {
1502 req_free (req); 1550 req_destroy (req);
1503 croak ("out of memory during aio_stat statdata allocation"); 1551 croak ("out of memory during aio_stat statdata allocation");
1504 } 1552 }
1505 1553
1506 req->flags |= FLAG_PTR2_FREE; 1554 req->flags |= FLAG_PTR2_FREE;
1555 req->sv1 = newSVsv (fh_or_path);
1507 1556
1508 if (SvPOK (fh_or_path)) 1557 if (SvPOK (fh_or_path))
1509 { 1558 {
1510 req->type = ix; 1559 req->type = ix;
1511 req->sv1 = newSVsv (fh_or_path);
1512 req->ptr1 = SvPVbyte_nolen (req->sv1); 1560 req->ptr1 = SvPVbyte_nolen (req->sv1);
1513 } 1561 }
1514 else 1562 else
1515 { 1563 {
1516 req->type = REQ_FSTAT; 1564 req->type = REQ_FSTAT;
1517 req->fh = newSVsv (fh_or_path);
1518 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path))); 1565 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1519 } 1566 }
1520 1567
1521 REQ_SEND; 1568 REQ_SEND;
1522} 1569}
1523 1570
1524void 1571void
1572aio_utime (SV8 *fh_or_path, SV *atime, SV *mtime, SV *callback=&PL_sv_undef)
1573 PPCODE:
1574{
1575 dREQ;
1576
1577 req->nv1 = SvOK (atime) ? SvNV (atime) : -1.;
1578 req->nv2 = SvOK (mtime) ? SvNV (mtime) : -1.;
1579 req->sv1 = newSVsv (fh_or_path);
1580
1581 if (SvPOK (fh_or_path))
1582 {
1583 req->type = REQ_UTIME;
1584 req->ptr1 = SvPVbyte_nolen (req->sv1);
1585 }
1586 else
1587 {
1588 req->type = REQ_FUTIME;
1589 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1590 }
1591
1592 REQ_SEND;
1593}
1594
1595void
1596aio_chmod (SV8 *fh_or_path, int mode, SV *callback=&PL_sv_undef)
1597 PPCODE:
1598{
1599 dREQ;
1600
1601 req->mode = mode;
1602 req->sv1 = newSVsv (fh_or_path);
1603
1604 if (SvPOK (fh_or_path))
1605 {
1606 req->type = REQ_CHMOD;
1607 req->ptr1 = SvPVbyte_nolen (req->sv1);
1608 }
1609 else
1610 {
1611 req->type = REQ_FCHMOD;
1612 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1613 }
1614
1615 REQ_SEND;
1616}
1617
1618void
1619aio_chown (SV8 *fh_or_path, SV *uid, SV *gid, SV *callback=&PL_sv_undef)
1620 PPCODE:
1621{
1622 dREQ;
1623
1624 req->int2 = SvOK (uid) ? SvIV (uid) : -1;
1625 req->int3 = SvOK (gid) ? SvIV (gid) : -1;
1626 req->sv1 = newSVsv (fh_or_path);
1627
1628 if (SvPOK (fh_or_path))
1629 {
1630 req->type = REQ_CHOWN;
1631 req->ptr1 = SvPVbyte_nolen (req->sv1);
1632 }
1633 else
1634 {
1635 req->type = REQ_FCHOWN;
1636 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1637 }
1638
1639 REQ_SEND;
1640}
1641
1642void
1525aio_unlink (pathname,callback=&PL_sv_undef) 1643aio_unlink (SV8 *pathname, SV *callback=&PL_sv_undef)
1526 SV8 * pathname
1527 SV * callback
1528 ALIAS: 1644 ALIAS:
1529 aio_unlink = REQ_UNLINK 1645 aio_unlink = REQ_UNLINK
1530 aio_rmdir = REQ_RMDIR 1646 aio_rmdir = REQ_RMDIR
1531 aio_readdir = REQ_READDIR 1647 aio_readdir = REQ_READDIR
1532 PPCODE: 1648 PPCODE:
1539 1655
1540 REQ_SEND; 1656 REQ_SEND;
1541} 1657}
1542 1658
1543void 1659void
1544aio_mkdir (pathname,mode,callback=&PL_sv_undef) 1660aio_mkdir (SV8 *pathname, int mode, SV *callback=&PL_sv_undef)
1545 SV8 * pathname
1546 UV mode
1547 SV * callback
1548 PPCODE: 1661 PPCODE:
1549{ 1662{
1550 dREQ; 1663 dREQ;
1551 1664
1552 req->type = REQ_MKDIR; 1665 req->type = REQ_MKDIR;
1556 1669
1557 REQ_SEND; 1670 REQ_SEND;
1558} 1671}
1559 1672
1560void 1673void
1561aio_link (oldpath,newpath,callback=&PL_sv_undef) 1674aio_link (SV8 *oldpath, SV8 *newpath, SV *callback=&PL_sv_undef)
1562 SV8 * oldpath
1563 SV8 * newpath
1564 SV * callback
1565 ALIAS: 1675 ALIAS:
1566 aio_link = REQ_LINK 1676 aio_link = REQ_LINK
1567 aio_symlink = REQ_SYMLINK 1677 aio_symlink = REQ_SYMLINK
1568 aio_rename = REQ_RENAME 1678 aio_rename = REQ_RENAME
1569 PPCODE: 1679 PPCODE:
1570{ 1680{
1571 dREQ; 1681 dREQ;
1572 1682
1573 req->type = ix; 1683 req->type = ix;
1574 req->fh = newSVsv (oldpath); 1684 req->sv2 = newSVsv (oldpath);
1575 req->ptr2 = SvPVbyte_nolen (req->fh); 1685 req->ptr2 = SvPVbyte_nolen (req->sv2);
1576 req->sv1 = newSVsv (newpath); 1686 req->sv1 = newSVsv (newpath);
1577 req->ptr1 = SvPVbyte_nolen (req->sv1); 1687 req->ptr1 = SvPVbyte_nolen (req->sv1);
1578 1688
1579 REQ_SEND; 1689 REQ_SEND;
1580} 1690}
1581 1691
1582void 1692void
1583aio_mknod (pathname,mode,dev,callback=&PL_sv_undef) 1693aio_mknod (SV8 *pathname, int mode, UV dev, SV *callback=&PL_sv_undef)
1584 SV8 * pathname
1585 UV mode
1586 UV dev
1587 SV * callback
1588 PPCODE: 1694 PPCODE:
1589{ 1695{
1590 dREQ; 1696 dREQ;
1591 1697
1592 req->type = REQ_MKNOD; 1698 req->type = REQ_MKNOD;
1597 1703
1598 REQ_SEND; 1704 REQ_SEND;
1599} 1705}
1600 1706
1601void 1707void
1602aio_busy (delay,callback=&PL_sv_undef) 1708aio_busy (double delay, SV *callback=&PL_sv_undef)
1603 double delay
1604 SV * callback
1605 PPCODE: 1709 PPCODE:
1606{ 1710{
1607 dREQ; 1711 dREQ;
1608 1712
1609 req->type = REQ_BUSY; 1713 req->type = REQ_BUSY;
1610 req->int1 = delay < 0. ? 0 : delay; 1714 req->nv1 = delay < 0. ? 0. : delay;
1611 req->int2 = delay < 0. ? 0 : 1000. * (delay - req->int1);
1612 1715
1613 REQ_SEND; 1716 REQ_SEND;
1614} 1717}
1615 1718
1616void 1719void
1617aio_group (callback=&PL_sv_undef) 1720aio_group (SV *callback=&PL_sv_undef)
1618 SV * callback
1619 PROTOTYPE: ;$ 1721 PROTOTYPE: ;$
1620 PPCODE: 1722 PPCODE:
1621{ 1723{
1622 dREQ; 1724 dREQ;
1623 1725
1626 req_send (req); 1728 req_send (req);
1627 XPUSHs (req_sv (req, AIO_GRP_KLASS)); 1729 XPUSHs (req_sv (req, AIO_GRP_KLASS));
1628} 1730}
1629 1731
1630void 1732void
1631aio_nop (callback=&PL_sv_undef) 1733aio_nop (SV *callback=&PL_sv_undef)
1632 SV * callback
1633 PPCODE: 1734 PPCODE:
1634{ 1735{
1635 dREQ; 1736 dREQ;
1636 1737
1637 req->type = REQ_NOP; 1738 req->type = REQ_NOP;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines