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.86 by root, Mon Oct 30 23:30:00 2006 UTC vs.
Revision 1.93 by root, Wed Nov 8 02:01:02 2006 UTC

87 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \ 87 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \
88 UNLOCK (wrklock); \ 88 UNLOCK (wrklock); \
89 if (!aio_buf) \ 89 if (!aio_buf) \
90 return -1; 90 return -1;
91 91
92typedef SV SV8; /* byte-sv, used for argument-checking */
93
92enum { 94enum {
93 REQ_QUIT, 95 REQ_QUIT,
94 REQ_OPEN, REQ_CLOSE, 96 REQ_OPEN, REQ_CLOSE,
95 REQ_READ, REQ_WRITE, REQ_READAHEAD, 97 REQ_READ, REQ_WRITE, REQ_READAHEAD,
96 REQ_SENDFILE, 98 REQ_SENDFILE,
111 struct aio_cb *volatile next; 113 struct aio_cb *volatile next;
112 114
113 SV *callback, *fh; 115 SV *callback, *fh;
114 SV *sv1, *sv2; 116 SV *sv1, *sv2;
115 void *ptr1, *ptr2; 117 void *ptr1, *ptr2;
116 Stat_t *statdata;
117 off_t offs; 118 off_t offs;
118 size_t size; 119 size_t size;
119 ssize_t result; 120 ssize_t result;
120 121
121 STRLEN stroffset; 122 STRLEN stroffset;
130 SV *self; /* the perl counterpart of this request, if any */ 131 SV *self; /* the perl counterpart of this request, if any */
131 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first; 132 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first;
132} aio_cb; 133} aio_cb;
133 134
134enum { 135enum {
135 FLAG_CANCELLED = 0x01, 136 FLAG_CANCELLED = 0x01, /* request was cancelled */
136 FLAG_DATA_RO_OFF = 0x80, /* data was set readonly */ 137 FLAG_SV1_RO_OFF = 0x40, /* data was set readonly */
138 FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */
137}; 139};
138 140
139typedef aio_cb *aio_req; 141typedef aio_cb *aio_req;
140typedef aio_cb *aio_req_ornot; 142typedef aio_cb *aio_req_ornot;
141 143
396 398
397static void req_invoke (aio_req req) 399static void req_invoke (aio_req req)
398{ 400{
399 dSP; 401 dSP;
400 402
401 if (req->flags & FLAG_DATA_RO_OFF) 403 if (req->flags & FLAG_SV1_RO_OFF)
402 SvREADONLY_off (req->sv1); 404 SvREADONLY_off (req->sv1);
403
404 if (req->statdata)
405 {
406 PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT;
407 PL_laststatval = req->result;
408 PL_statcache = *(req->statdata);
409 }
410 405
411 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) 406 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback))
412 { 407 {
413 ENTER; 408 ENTER;
414 SAVETMPS; 409 SAVETMPS;
452 PUSHs (sv_2mortal (newSViv (req->result))); 447 PUSHs (sv_2mortal (newSViv (req->result)));
453 PUTBACK; 448 PUTBACK;
454 call_pv ("IO::AIO::_fd2fh", G_SCALAR | G_EVAL); 449 call_pv ("IO::AIO::_fd2fh", G_SCALAR | G_EVAL);
455 SPAGAIN; 450 SPAGAIN;
456 451
457 fh = SvREFCNT_inc (POPs); 452 fh = POPs;
458
459 PUSHMARK (SP); 453 PUSHMARK (SP);
460 XPUSHs (sv_2mortal (fh)); 454 XPUSHs (fh);
461 } 455 }
462 break; 456 break;
463 457
464 case REQ_GROUP: 458 case REQ_GROUP:
465 req->int1 = 2; /* mark group as finished */ 459 req->int1 = 2; /* mark group as finished */
486 *SvEND (req->sv1) = 0; 480 *SvEND (req->sv1) = 0;
487 PUSHs (req->sv1); 481 PUSHs (req->sv1);
488 } 482 }
489 break; 483 break;
490 484
485 case REQ_STAT:
486 case REQ_LSTAT:
487 case REQ_FSTAT:
488 PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT;
489 PL_laststatval = req->result;
490 PL_statcache = *(Stat_t *)(req->ptr2);
491 PUSHs (sv_2mortal (newSViv (req->result)));
492 break;
493
491 case REQ_READ: 494 case REQ_READ:
492 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); 495 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0));
493 *SvEND (req->sv1) = 0; 496 *SvEND (req->sv1) = 0;
494 /* fall through */ 497 PUSHs (sv_2mortal (newSViv (req->result)));
498 break;
499
495 default: 500 default:
496 PUSHs (sv_2mortal (newSViv (req->result))); 501 PUSHs (sv_2mortal (newSViv (req->result)));
497 break; 502 break;
498 } 503 }
499 504
538 543
539 SvREFCNT_dec (req->fh); 544 SvREFCNT_dec (req->fh);
540 SvREFCNT_dec (req->sv1); 545 SvREFCNT_dec (req->sv1);
541 SvREFCNT_dec (req->sv2); 546 SvREFCNT_dec (req->sv2);
542 SvREFCNT_dec (req->callback); 547 SvREFCNT_dec (req->callback);
543 Safefree (req->statdata);
544 548
545 if (req->type == REQ_READDIR) 549 if (req->flags & FLAG_PTR2_FREE)
546 free (req->ptr2); 550 free (req->ptr2);
547 551
548 Safefree (req); 552 Safefree (req);
549} 553}
550 554
997 int errorno; 1001 int errorno;
998 1002
999 LOCK (wrklock); 1003 LOCK (wrklock);
1000 self->dirp = dirp = opendir (req->ptr1); 1004 self->dirp = dirp = opendir (req->ptr1);
1001 self->dbuf = u = malloc (sizeof (*u)); 1005 self->dbuf = u = malloc (sizeof (*u));
1006 req->flags |= FLAG_PTR2_FREE;
1002 req->ptr2 = names = malloc (memlen); 1007 req->ptr2 = names = malloc (memlen);
1003 UNLOCK (wrklock); 1008 UNLOCK (wrklock);
1004 1009
1005 if (dirp && u && names) 1010 if (dirp && u && names)
1006 for (;;) 1011 for (;;)
1102 case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; 1107 case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break;
1103 1108
1104 case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; 1109 case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break;
1105 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; 1110 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break;
1106 1111
1107 case REQ_STAT: req->result = stat (req->ptr1, req->statdata); break; 1112 case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break;
1108 case REQ_LSTAT: req->result = lstat (req->ptr1, req->statdata); break; 1113 case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break;
1109 case REQ_FSTAT: req->result = fstat (req->int1, req->statdata); break; 1114 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break;
1110 1115
1111 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; 1116 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break;
1112 case REQ_CLOSE: req->result = close (req->int1); break; 1117 case REQ_CLOSE: req->result = close (req->int1); break;
1113 case REQ_UNLINK: req->result = unlink (req->ptr1); break; 1118 case REQ_UNLINK: req->result = unlink (req->ptr1); break;
1114 case REQ_RMDIR: req->result = rmdir (req->ptr1); break; 1119 case REQ_RMDIR: req->result = rmdir (req->ptr1); break;
1305 OUTPUT: 1310 OUTPUT:
1306 RETVAL 1311 RETVAL
1307 1312
1308void 1313void
1309aio_open (pathname,flags,mode,callback=&PL_sv_undef) 1314aio_open (pathname,flags,mode,callback=&PL_sv_undef)
1310 SV * pathname 1315 SV8 * pathname
1311 int flags 1316 int flags
1312 int mode 1317 int mode
1313 SV * callback 1318 SV * callback
1314 PROTOTYPE: $$$;$ 1319 PROTOTYPE: $$$;$
1315 PPCODE: 1320 PPCODE:
1316{ 1321{
1317 dREQ; 1322 dREQ;
1318 1323
1319 req->type = REQ_OPEN; 1324 req->type = REQ_OPEN;
1320 req->sv1 = newSVsv (pathname); 1325 req->sv1 = newSVsv (pathname);
1321 req->ptr1 = SvPVbyte_nolen (pathname); 1326 req->ptr1 = SvPVbyte_nolen (req->sv1);
1322 req->int1 = flags; 1327 req->int1 = flags;
1323 req->mode = mode; 1328 req->mode = mode;
1324 1329
1325 REQ_SEND; 1330 REQ_SEND;
1326} 1331}
1348void 1353void
1349aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef) 1354aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef)
1350 SV * fh 1355 SV * fh
1351 UV offset 1356 UV offset
1352 UV length 1357 UV length
1353 SV * data 1358 SV8 * data
1354 UV dataoffset 1359 UV dataoffset
1355 SV * callback 1360 SV * callback
1356 ALIAS: 1361 ALIAS:
1357 aio_read = REQ_READ 1362 aio_read = REQ_READ
1358 aio_write = REQ_WRITE 1363 aio_write = REQ_WRITE
1400 req->stroffset = dataoffset; 1405 req->stroffset = dataoffset;
1401 1406
1402 if (!SvREADONLY (data)) 1407 if (!SvREADONLY (data))
1403 { 1408 {
1404 SvREADONLY_on (data); 1409 SvREADONLY_on (data);
1405 req->flags |= FLAG_DATA_RO_OFF; 1410 req->flags |= FLAG_SV1_RO_OFF;
1406 } 1411 }
1407 1412
1408 REQ_SEND; 1413 REQ_SEND;
1409 } 1414 }
1410} 1415}
1411 1416
1412void 1417void
1413aio_readlink (path,callback=&PL_sv_undef) 1418aio_readlink (path,callback=&PL_sv_undef)
1414 SV * path 1419 SV8 * path
1415 SV * callback 1420 SV * callback
1416 PROTOTYPE: $$;$ 1421 PROTOTYPE: $$;$
1417 PPCODE: 1422 PPCODE:
1418{ 1423{
1419 SV *data; 1424 SV *data;
1422 data = newSV (NAME_MAX); 1427 data = newSV (NAME_MAX);
1423 SvPOK_on (data); 1428 SvPOK_on (data);
1424 1429
1425 req->type = REQ_READLINK; 1430 req->type = REQ_READLINK;
1426 req->fh = newSVsv (path); 1431 req->fh = newSVsv (path);
1427 req->ptr2 = SvPVbyte_nolen (path); 1432 req->ptr2 = SvPVbyte_nolen (req->fh);
1428 req->sv1 = data; 1433 req->sv1 = data;
1429 req->ptr1 = SvPVbyte_nolen (data); 1434 req->ptr1 = SvPVbyte_nolen (data);
1430 1435
1431 REQ_SEND; 1436 REQ_SEND;
1432} 1437}
1474 REQ_SEND; 1479 REQ_SEND;
1475} 1480}
1476 1481
1477void 1482void
1478aio_stat (fh_or_path,callback=&PL_sv_undef) 1483aio_stat (fh_or_path,callback=&PL_sv_undef)
1479 SV * fh_or_path 1484 SV8 * fh_or_path
1480 SV * callback 1485 SV * callback
1481 ALIAS: 1486 ALIAS:
1482 aio_stat = REQ_STAT 1487 aio_stat = REQ_STAT
1483 aio_lstat = REQ_LSTAT 1488 aio_lstat = REQ_LSTAT
1484 PPCODE: 1489 PPCODE:
1485{ 1490{
1486 dREQ; 1491 dREQ;
1487 1492
1488 New (0, req->statdata, 1, Stat_t); 1493 req->ptr2 = malloc (sizeof (Stat_t));
1489 if (!req->statdata) 1494 if (!req->ptr2)
1490 { 1495 {
1491 req_free (req); 1496 req_free (req);
1492 croak ("out of memory during aio_req->statdata allocation"); 1497 croak ("out of memory during aio_stat statdata allocation");
1493 } 1498 }
1499
1500 req->flags |= FLAG_PTR2_FREE;
1494 1501
1495 if (SvPOK (fh_or_path)) 1502 if (SvPOK (fh_or_path))
1496 { 1503 {
1497 req->type = ix; 1504 req->type = ix;
1498 req->sv1 = newSVsv (fh_or_path); 1505 req->sv1 = newSVsv (fh_or_path);
1499 req->ptr1 = SvPVbyte_nolen (fh_or_path); 1506 req->ptr1 = SvPVbyte_nolen (req->sv1);
1500 } 1507 }
1501 else 1508 else
1502 { 1509 {
1503 req->type = REQ_FSTAT; 1510 req->type = REQ_FSTAT;
1504 req->fh = newSVsv (fh_or_path); 1511 req->fh = newSVsv (fh_or_path);
1508 REQ_SEND; 1515 REQ_SEND;
1509} 1516}
1510 1517
1511void 1518void
1512aio_unlink (pathname,callback=&PL_sv_undef) 1519aio_unlink (pathname,callback=&PL_sv_undef)
1513 SV * pathname 1520 SV8 * pathname
1514 SV * callback 1521 SV * callback
1515 ALIAS: 1522 ALIAS:
1516 aio_unlink = REQ_UNLINK 1523 aio_unlink = REQ_UNLINK
1517 aio_rmdir = REQ_RMDIR 1524 aio_rmdir = REQ_RMDIR
1518 aio_readdir = REQ_READDIR 1525 aio_readdir = REQ_READDIR
1520{ 1527{
1521 dREQ; 1528 dREQ;
1522 1529
1523 req->type = ix; 1530 req->type = ix;
1524 req->sv1 = newSVsv (pathname); 1531 req->sv1 = newSVsv (pathname);
1525 req->ptr1 = SvPVbyte_nolen (pathname); 1532 req->ptr1 = SvPVbyte_nolen (req->sv1);
1526 1533
1527 REQ_SEND; 1534 REQ_SEND;
1528} 1535}
1529 1536
1530void 1537void
1531aio_link (oldpath,newpath,callback=&PL_sv_undef) 1538aio_link (oldpath,newpath,callback=&PL_sv_undef)
1532 SV * oldpath 1539 SV8 * oldpath
1533 SV * newpath 1540 SV8 * newpath
1534 SV * callback 1541 SV * callback
1535 ALIAS: 1542 ALIAS:
1536 aio_link = REQ_LINK 1543 aio_link = REQ_LINK
1537 aio_symlink = REQ_SYMLINK 1544 aio_symlink = REQ_SYMLINK
1538 aio_rename = REQ_RENAME 1545 aio_rename = REQ_RENAME
1542 1549
1543 req->type = ix; 1550 req->type = ix;
1544 req->fh = newSVsv (oldpath); 1551 req->fh = newSVsv (oldpath);
1545 req->ptr2 = SvPVbyte_nolen (req->fh); 1552 req->ptr2 = SvPVbyte_nolen (req->fh);
1546 req->sv1 = newSVsv (newpath); 1553 req->sv1 = newSVsv (newpath);
1547 req->ptr1 = SvPVbyte_nolen (newpath); 1554 req->ptr1 = SvPVbyte_nolen (req->sv1);
1548 1555
1549 REQ_SEND; 1556 REQ_SEND;
1550} 1557}
1551 1558
1552void 1559void
1553aio_mknod (pathname,mode,dev,callback=&PL_sv_undef) 1560aio_mknod (pathname,mode,dev,callback=&PL_sv_undef)
1554 SV * pathname 1561 SV8 * pathname
1555 SV * callback 1562 SV * callback
1556 UV mode 1563 UV mode
1557 UV dev 1564 UV dev
1558 PPCODE: 1565 PPCODE:
1559{ 1566{
1560 dREQ; 1567 dREQ;
1561 1568
1562 req->type = REQ_MKNOD; 1569 req->type = REQ_MKNOD;
1563 req->sv1 = newSVsv (pathname); 1570 req->sv1 = newSVsv (pathname);
1564 req->ptr1 = SvPVbyte_nolen (pathname); 1571 req->ptr1 = SvPVbyte_nolen (req->sv1);
1565 req->mode = (mode_t)mode; 1572 req->mode = (mode_t)mode;
1566 req->offs = dev; 1573 req->offs = dev;
1567 1574
1568 REQ_SEND; 1575 REQ_SEND;
1569} 1576}
1636 PROTOTYPE: 1643 PROTOTYPE:
1637 CODE: 1644 CODE:
1638 while (nreqs) 1645 while (nreqs)
1639 { 1646 {
1640 poll_wait (); 1647 poll_wait ();
1641 poll_cb (0); 1648 poll_cb ();
1642 } 1649 }
1643 1650
1644void 1651int
1645poll() 1652poll()
1646 PROTOTYPE: 1653 PROTOTYPE:
1647 CODE: 1654 CODE:
1648 if (nreqs)
1649 {
1650 poll_wait (); 1655 poll_wait ();
1651 poll_cb (0); 1656 RETVAL = poll_cb ();
1652 } 1657 OUTPUT:
1658 RETVAL
1653 1659
1654int 1660int
1655poll_fileno() 1661poll_fileno()
1656 PROTOTYPE: 1662 PROTOTYPE:
1657 CODE: 1663 CODE:
1669 1675
1670void 1676void
1671poll_wait() 1677poll_wait()
1672 PROTOTYPE: 1678 PROTOTYPE:
1673 CODE: 1679 CODE:
1674 if (nreqs)
1675 poll_wait (); 1680 poll_wait ();
1676 1681
1677int 1682int
1678nreqs() 1683nreqs()
1679 PROTOTYPE: 1684 PROTOTYPE:
1680 CODE: 1685 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines