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.100 by root, Fri Jun 1 06:00:40 2007 UTC vs.
Revision 1.101 by root, Fri Jun 1 13:25:51 2007 UTC

46#endif 46#endif
47 47
48/* buffer size for various temporary buffers */ 48/* buffer size for various temporary buffers */
49#define AIO_BUFSIZE 65536 49#define AIO_BUFSIZE 65536
50 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
51#define dBUF \ 58#define dBUF \
52 char *aio_buf; \ 59 char *aio_buf; \
53 LOCK (wrklock); \ 60 LOCK (wrklock); \
54 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \ 61 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \
55 UNLOCK (wrklock); \ 62 UNLOCK (wrklock); \
59typedef SV SV8; /* byte-sv, used for argument-checking */ 66typedef SV SV8; /* byte-sv, used for argument-checking */
60 67
61enum { 68enum {
62 REQ_QUIT, 69 REQ_QUIT,
63 REQ_OPEN, REQ_CLOSE, 70 REQ_OPEN, REQ_CLOSE,
64 REQ_READ, REQ_WRITE, REQ_READAHEAD, 71 REQ_READ, REQ_WRITE,
65 REQ_SENDFILE, 72 REQ_READAHEAD, REQ_SENDFILE,
66 REQ_STAT, REQ_LSTAT, REQ_FSTAT, 73 REQ_STAT, REQ_LSTAT, REQ_FSTAT,
67 REQ_UTIME, REQ_FUTIME, /* must be consecutive */ 74 REQ_UTIME, REQ_FUTIME,
68 REQ_CHMOD, REQ_FCHMOD, /* must be consecutive */ 75 REQ_CHMOD, REQ_FCHMOD,
69 REQ_CHOWN, REQ_FCHOWN, /* must be consecutive */ 76 REQ_CHOWN, REQ_FCHOWN,
70 REQ_FSYNC, REQ_FDATASYNC, 77 REQ_FSYNC, REQ_FDATASYNC,
71 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, 78 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME,
72 REQ_MKNOD, REQ_READDIR, 79 REQ_MKNOD, REQ_READDIR,
73 REQ_LINK, REQ_SYMLINK, REQ_READLINK, 80 REQ_LINK, REQ_SYMLINK, REQ_READLINK,
74 REQ_GROUP, REQ_NOP, 81 REQ_GROUP, REQ_NOP,
317 abort (); 324 abort ();
318} 325}
319 326
320static int poll_cb (); 327static int poll_cb ();
321static int req_invoke (aio_req req); 328static int req_invoke (aio_req req);
322static void req_free (aio_req req); 329static void req_destroy (aio_req req);
323static void req_cancel (aio_req req); 330static void req_cancel (aio_req req);
324 331
325/* must be called at most once */ 332/* must be called at most once */
326static SV *req_sv (aio_req req, const char *klass) 333static SV *req_sv (aio_req req, const char *klass)
327{ 334{
393 { 400 {
394 block_sig (); 401 block_sig ();
395 402
396 if (!req_invoke (grp)) 403 if (!req_invoke (grp))
397 { 404 {
398 req_free (grp); 405 req_destroy (grp);
399 unblock_sig (); 406 unblock_sig ();
400 croak (0); 407 croak (0);
401 } 408 }
402 409
403 req_free (grp); 410 req_destroy (grp);
404 unblock_sig (); 411 unblock_sig ();
405 } 412 }
406} 413}
407 414
408static int req_invoke (aio_req req) 415static int req_invoke (aio_req req)
536 } 543 }
537 544
538 return !SvTRUE (ERRSV); 545 return !SvTRUE (ERRSV);
539} 546}
540 547
541static void req_free (aio_req req) 548static void req_destroy (aio_req req)
542{ 549{
543 if (req->self) 550 if (req->self)
544 { 551 {
545 sv_unmagic (req->self, PERL_MAGIC_ext); 552 sv_unmagic (req->self, PERL_MAGIC_ext);
546 SvREFCNT_dec (req->self); 553 SvREFCNT_dec (req->self);
575 req->flags |= FLAG_CANCELLED; 582 req->flags |= FLAG_CANCELLED;
576 583
577 req_cancel_subs (req); 584 req_cancel_subs (req);
578} 585}
579 586
580static void *aio_proc(void *arg); 587static void *aio_proc (void *arg);
581 588
582static void start_thread (void) 589static void start_thread (void)
583{ 590{
584 worker *wrk = calloc (1, sizeof (worker)); 591 worker *wrk = calloc (1, sizeof (worker));
585 592
745 } 752 }
746 else 753 else
747 { 754 {
748 if (!req_invoke (req)) 755 if (!req_invoke (req))
749 { 756 {
750 req_free (req); 757 req_destroy (req);
751 unblock_sig (); 758 unblock_sig ();
752 croak (0); 759 croak (0);
753 } 760 }
754 761
755 count++; 762 count++;
756 } 763 }
757 764
758 req_free (req); 765 req_destroy (req);
759 766
760 if (maxreqs && !--maxreqs) 767 if (maxreqs && !--maxreqs)
761 break; 768 break;
762 769
763 if (max_poll_time) 770 if (max_poll_time)
1131 errno = 0; /* strictly unnecessary */ 1138 errno = 0; /* strictly unnecessary */
1132 1139
1133 if (!(req->flags & FLAG_CANCELLED)) 1140 if (!(req->flags & FLAG_CANCELLED))
1134 switch (req->type) 1141 switch (req->type)
1135 { 1142 {
1136 case REQ_READ: req->result = pread (req->int1, req->ptr1, req->size, req->offs); break; 1143 case REQ_READ: req->result = req->offs >= 0
1137 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;
1138 1149
1139 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;
1140 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;
1141 1152
1142 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;
1270static void atfork_child (void) 1281static void atfork_child (void)
1271{ 1282{
1272 aio_req prv; 1283 aio_req prv;
1273 1284
1274 while (prv = reqq_shift (&req_queue)) 1285 while (prv = reqq_shift (&req_queue))
1275 req_free (prv); 1286 req_destroy (prv);
1276 1287
1277 while (prv = reqq_shift (&res_queue)) 1288 while (prv = reqq_shift (&res_queue))
1278 req_free (prv); 1289 req_destroy (prv);
1279 1290
1280 while (wrk_first.next != &wrk_first) 1291 while (wrk_first.next != &wrk_first)
1281 { 1292 {
1282 worker *wrk = wrk_first.next; 1293 worker *wrk = wrk_first.next;
1283 1294
1284 if (wrk->req) 1295 if (wrk->req)
1285 req_free (wrk->req); 1296 req_destroy (wrk->req);
1286 1297
1287 worker_clear (wrk); 1298 worker_clear (wrk);
1288 worker_free (wrk); 1299 worker_free (wrk);
1289 } 1300 }
1290 1301
1410 1421
1411 REQ_SEND (req); 1422 REQ_SEND (req);
1412} 1423}
1413 1424
1414void 1425void
1415aio_read (SV *fh, UV offset, UV length, SV8 *data, UV dataoffset, SV *callback=&PL_sv_undef) 1426aio_read (SV *fh, SV *offset, UV length, SV8 *data, UV dataoffset, SV *callback=&PL_sv_undef)
1416 ALIAS: 1427 ALIAS:
1417 aio_read = REQ_READ 1428 aio_read = REQ_READ
1418 aio_write = REQ_WRITE 1429 aio_write = REQ_WRITE
1419 PROTOTYPE: $$$$$;$ 1430 PROTOTYPE: $$$$$;$
1420 PPCODE: 1431 PPCODE:
1451 1462
1452 req->type = ix; 1463 req->type = ix;
1453 req->sv1 = newSVsv (fh); 1464 req->sv1 = newSVsv (fh);
1454 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh)) 1465 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh))
1455 : IoOFP (sv_2io (fh))); 1466 : IoOFP (sv_2io (fh)));
1456 req->offs = offset; 1467 req->offs = SvOK (offset) ? SvVAL64 (offset) : -1;
1457 req->size = length; 1468 req->size = length;
1458 req->sv2 = SvREFCNT_inc (data); 1469 req->sv2 = SvREFCNT_inc (data);
1459 req->ptr1 = (char *)svptr + dataoffset; 1470 req->ptr1 = (char *)svptr + dataoffset;
1460 req->stroffset = dataoffset; 1471 req->stroffset = dataoffset;
1461 1472
1488 1499
1489 REQ_SEND; 1500 REQ_SEND;
1490} 1501}
1491 1502
1492void 1503void
1493aio_sendfile (SV *out_fh, SV *in_fh, UV in_offset, UV length, SV *callback=&PL_sv_undef) 1504aio_sendfile (SV *out_fh, SV *in_fh, SV *in_offset, UV length, SV *callback=&PL_sv_undef)
1494 PROTOTYPE: $$$$;$ 1505 PROTOTYPE: $$$$;$
1495 PPCODE: 1506 PPCODE:
1496{ 1507{
1497 dREQ; 1508 dREQ;
1498 1509
1499 req->type = REQ_SENDFILE; 1510 req->type = REQ_SENDFILE;
1500 req->sv1 = newSVsv (out_fh); 1511 req->sv1 = newSVsv (out_fh);
1501 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); 1512 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh)));
1502 req->sv2 = newSVsv (in_fh); 1513 req->sv2 = newSVsv (in_fh);
1503 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); 1514 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh)));
1504 req->offs = in_offset; 1515 req->offs = SvVAL64 (in_offset);
1505 req->size = length; 1516 req->size = length;
1506 1517
1507 REQ_SEND; 1518 REQ_SEND;
1508} 1519}
1509 1520
1510void 1521void
1511aio_readahead (SV *fh, UV offset, IV length, SV *callback=&PL_sv_undef) 1522aio_readahead (SV *fh, SV *offset, IV length, SV *callback=&PL_sv_undef)
1512 PROTOTYPE: $$$;$ 1523 PROTOTYPE: $$$;$
1513 PPCODE: 1524 PPCODE:
1514{ 1525{
1515 dREQ; 1526 dREQ;
1516 1527
1517 req->type = REQ_READAHEAD; 1528 req->type = REQ_READAHEAD;
1518 req->sv1 = newSVsv (fh); 1529 req->sv1 = newSVsv (fh);
1519 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1530 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1520 req->offs = offset; 1531 req->offs = SvVAL64 (offset);
1521 req->size = length; 1532 req->size = length;
1522 1533
1523 REQ_SEND; 1534 REQ_SEND;
1524} 1535}
1525 1536
1533 dREQ; 1544 dREQ;
1534 1545
1535 req->ptr2 = malloc (sizeof (Stat_t)); 1546 req->ptr2 = malloc (sizeof (Stat_t));
1536 if (!req->ptr2) 1547 if (!req->ptr2)
1537 { 1548 {
1538 req_free (req); 1549 req_destroy (req);
1539 croak ("out of memory during aio_stat statdata allocation"); 1550 croak ("out of memory during aio_stat statdata allocation");
1540 } 1551 }
1541 1552
1542 req->flags |= FLAG_PTR2_FREE; 1553 req->flags |= FLAG_PTR2_FREE;
1543 req->sv1 = newSVsv (fh_or_path); 1554 req->sv1 = newSVsv (fh_or_path);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines