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.90 by root, Tue Oct 31 00:32:19 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;
486 *SvEND (req->sv1) = 0; 481 *SvEND (req->sv1) = 0;
487 PUSHs (req->sv1); 482 PUSHs (req->sv1);
488 } 483 }
489 break; 484 break;
490 485
486 case REQ_STAT:
487 case REQ_LSTAT:
488 case REQ_FSTAT:
489 PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT;
490 PL_laststatval = req->result;
491 PL_statcache = *(Stat_t *)(req->ptr2);
492 PUSHs (sv_2mortal (newSViv (req->result)));
493 break;
494
491 case REQ_READ: 495 case REQ_READ:
492 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); 496 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0));
493 *SvEND (req->sv1) = 0; 497 *SvEND (req->sv1) = 0;
494 /* fall through */ 498 PUSHs (sv_2mortal (newSViv (req->result)));
499 break;
500
495 default: 501 default:
496 PUSHs (sv_2mortal (newSViv (req->result))); 502 PUSHs (sv_2mortal (newSViv (req->result)));
497 break; 503 break;
498 } 504 }
499 505
538 544
539 SvREFCNT_dec (req->fh); 545 SvREFCNT_dec (req->fh);
540 SvREFCNT_dec (req->sv1); 546 SvREFCNT_dec (req->sv1);
541 SvREFCNT_dec (req->sv2); 547 SvREFCNT_dec (req->sv2);
542 SvREFCNT_dec (req->callback); 548 SvREFCNT_dec (req->callback);
543 Safefree (req->statdata);
544 549
545 if (req->type == REQ_READDIR) 550 if (req->flags & FLAG_PTR2_FREE)
546 free (req->ptr2); 551 free (req->ptr2);
547 552
548 Safefree (req); 553 Safefree (req);
549} 554}
550 555
997 int errorno; 1002 int errorno;
998 1003
999 LOCK (wrklock); 1004 LOCK (wrklock);
1000 self->dirp = dirp = opendir (req->ptr1); 1005 self->dirp = dirp = opendir (req->ptr1);
1001 self->dbuf = u = malloc (sizeof (*u)); 1006 self->dbuf = u = malloc (sizeof (*u));
1007 req->flags |= FLAG_PTR2_FREE;
1002 req->ptr2 = names = malloc (memlen); 1008 req->ptr2 = names = malloc (memlen);
1003 UNLOCK (wrklock); 1009 UNLOCK (wrklock);
1004 1010
1005 if (dirp && u && names) 1011 if (dirp && u && names)
1006 for (;;) 1012 for (;;)
1102 case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; 1108 case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break;
1103 1109
1104 case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; 1110 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; 1111 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break;
1106 1112
1107 case REQ_STAT: req->result = stat (req->ptr1, req->statdata); break; 1113 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; 1114 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; 1115 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break;
1110 1116
1111 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; 1117 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break;
1112 case REQ_CLOSE: req->result = close (req->int1); break; 1118 case REQ_CLOSE: req->result = close (req->int1); break;
1113 case REQ_UNLINK: req->result = unlink (req->ptr1); break; 1119 case REQ_UNLINK: req->result = unlink (req->ptr1); break;
1114 case REQ_RMDIR: req->result = rmdir (req->ptr1); break; 1120 case REQ_RMDIR: req->result = rmdir (req->ptr1); break;
1305 OUTPUT: 1311 OUTPUT:
1306 RETVAL 1312 RETVAL
1307 1313
1308void 1314void
1309aio_open (pathname,flags,mode,callback=&PL_sv_undef) 1315aio_open (pathname,flags,mode,callback=&PL_sv_undef)
1310 SV * pathname 1316 SV8 * pathname
1311 int flags 1317 int flags
1312 int mode 1318 int mode
1313 SV * callback 1319 SV * callback
1314 PROTOTYPE: $$$;$ 1320 PROTOTYPE: $$$;$
1315 PPCODE: 1321 PPCODE:
1316{ 1322{
1317 dREQ; 1323 dREQ;
1318 1324
1319 req->type = REQ_OPEN; 1325 req->type = REQ_OPEN;
1320 req->sv1 = newSVsv (pathname); 1326 req->sv1 = newSVsv (pathname);
1321 req->ptr1 = SvPVbyte_nolen (pathname); 1327 req->ptr1 = SvPVbyte_nolen (req->sv1);
1322 req->int1 = flags; 1328 req->int1 = flags;
1323 req->mode = mode; 1329 req->mode = mode;
1324 1330
1325 REQ_SEND; 1331 REQ_SEND;
1326} 1332}
1348void 1354void
1349aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef) 1355aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef)
1350 SV * fh 1356 SV * fh
1351 UV offset 1357 UV offset
1352 UV length 1358 UV length
1353 SV * data 1359 SV8 * data
1354 UV dataoffset 1360 UV dataoffset
1355 SV * callback 1361 SV * callback
1356 ALIAS: 1362 ALIAS:
1357 aio_read = REQ_READ 1363 aio_read = REQ_READ
1358 aio_write = REQ_WRITE 1364 aio_write = REQ_WRITE
1400 req->stroffset = dataoffset; 1406 req->stroffset = dataoffset;
1401 1407
1402 if (!SvREADONLY (data)) 1408 if (!SvREADONLY (data))
1403 { 1409 {
1404 SvREADONLY_on (data); 1410 SvREADONLY_on (data);
1405 req->flags |= FLAG_DATA_RO_OFF; 1411 req->flags |= FLAG_SV1_RO_OFF;
1406 } 1412 }
1407 1413
1408 REQ_SEND; 1414 REQ_SEND;
1409 } 1415 }
1410} 1416}
1411 1417
1412void 1418void
1413aio_readlink (path,callback=&PL_sv_undef) 1419aio_readlink (path,callback=&PL_sv_undef)
1414 SV * path 1420 SV8 * path
1415 SV * callback 1421 SV * callback
1416 PROTOTYPE: $$;$ 1422 PROTOTYPE: $$;$
1417 PPCODE: 1423 PPCODE:
1418{ 1424{
1419 SV *data; 1425 SV *data;
1422 data = newSV (NAME_MAX); 1428 data = newSV (NAME_MAX);
1423 SvPOK_on (data); 1429 SvPOK_on (data);
1424 1430
1425 req->type = REQ_READLINK; 1431 req->type = REQ_READLINK;
1426 req->fh = newSVsv (path); 1432 req->fh = newSVsv (path);
1427 req->ptr2 = SvPVbyte_nolen (path); 1433 req->ptr2 = SvPVbyte_nolen (req->fh);
1428 req->sv1 = data; 1434 req->sv1 = data;
1429 req->ptr1 = SvPVbyte_nolen (data); 1435 req->ptr1 = SvPVbyte_nolen (data);
1430 1436
1431 REQ_SEND; 1437 REQ_SEND;
1432} 1438}
1474 REQ_SEND; 1480 REQ_SEND;
1475} 1481}
1476 1482
1477void 1483void
1478aio_stat (fh_or_path,callback=&PL_sv_undef) 1484aio_stat (fh_or_path,callback=&PL_sv_undef)
1479 SV * fh_or_path 1485 SV8 * fh_or_path
1480 SV * callback 1486 SV * callback
1481 ALIAS: 1487 ALIAS:
1482 aio_stat = REQ_STAT 1488 aio_stat = REQ_STAT
1483 aio_lstat = REQ_LSTAT 1489 aio_lstat = REQ_LSTAT
1484 PPCODE: 1490 PPCODE:
1485{ 1491{
1486 dREQ; 1492 dREQ;
1487 1493
1488 New (0, req->statdata, 1, Stat_t); 1494 req->ptr2 = malloc (sizeof (Stat_t));
1489 if (!req->statdata) 1495 if (!req->ptr2)
1490 { 1496 {
1491 req_free (req); 1497 req_free (req);
1492 croak ("out of memory during aio_req->statdata allocation"); 1498 croak ("out of memory during aio_stat statdata allocation");
1493 } 1499 }
1500
1501 req->flags |= FLAG_PTR2_FREE;
1494 1502
1495 if (SvPOK (fh_or_path)) 1503 if (SvPOK (fh_or_path))
1496 { 1504 {
1497 req->type = ix; 1505 req->type = ix;
1498 req->sv1 = newSVsv (fh_or_path); 1506 req->sv1 = newSVsv (fh_or_path);
1499 req->ptr1 = SvPVbyte_nolen (fh_or_path); 1507 req->ptr1 = SvPVbyte_nolen (req->sv1);
1500 } 1508 }
1501 else 1509 else
1502 { 1510 {
1503 req->type = REQ_FSTAT; 1511 req->type = REQ_FSTAT;
1504 req->fh = newSVsv (fh_or_path); 1512 req->fh = newSVsv (fh_or_path);
1508 REQ_SEND; 1516 REQ_SEND;
1509} 1517}
1510 1518
1511void 1519void
1512aio_unlink (pathname,callback=&PL_sv_undef) 1520aio_unlink (pathname,callback=&PL_sv_undef)
1513 SV * pathname 1521 SV8 * pathname
1514 SV * callback 1522 SV * callback
1515 ALIAS: 1523 ALIAS:
1516 aio_unlink = REQ_UNLINK 1524 aio_unlink = REQ_UNLINK
1517 aio_rmdir = REQ_RMDIR 1525 aio_rmdir = REQ_RMDIR
1518 aio_readdir = REQ_READDIR 1526 aio_readdir = REQ_READDIR
1520{ 1528{
1521 dREQ; 1529 dREQ;
1522 1530
1523 req->type = ix; 1531 req->type = ix;
1524 req->sv1 = newSVsv (pathname); 1532 req->sv1 = newSVsv (pathname);
1525 req->ptr1 = SvPVbyte_nolen (pathname); 1533 req->ptr1 = SvPVbyte_nolen (req->sv1);
1526 1534
1527 REQ_SEND; 1535 REQ_SEND;
1528} 1536}
1529 1537
1530void 1538void
1531aio_link (oldpath,newpath,callback=&PL_sv_undef) 1539aio_link (oldpath,newpath,callback=&PL_sv_undef)
1532 SV * oldpath 1540 SV8 * oldpath
1533 SV * newpath 1541 SV8 * newpath
1534 SV * callback 1542 SV * callback
1535 ALIAS: 1543 ALIAS:
1536 aio_link = REQ_LINK 1544 aio_link = REQ_LINK
1537 aio_symlink = REQ_SYMLINK 1545 aio_symlink = REQ_SYMLINK
1538 aio_rename = REQ_RENAME 1546 aio_rename = REQ_RENAME
1542 1550
1543 req->type = ix; 1551 req->type = ix;
1544 req->fh = newSVsv (oldpath); 1552 req->fh = newSVsv (oldpath);
1545 req->ptr2 = SvPVbyte_nolen (req->fh); 1553 req->ptr2 = SvPVbyte_nolen (req->fh);
1546 req->sv1 = newSVsv (newpath); 1554 req->sv1 = newSVsv (newpath);
1547 req->ptr1 = SvPVbyte_nolen (newpath); 1555 req->ptr1 = SvPVbyte_nolen (req->sv1);
1548 1556
1549 REQ_SEND; 1557 REQ_SEND;
1550} 1558}
1551 1559
1552void 1560void
1553aio_mknod (pathname,mode,dev,callback=&PL_sv_undef) 1561aio_mknod (pathname,mode,dev,callback=&PL_sv_undef)
1554 SV * pathname 1562 SV8 * pathname
1555 SV * callback 1563 SV * callback
1556 UV mode 1564 UV mode
1557 UV dev 1565 UV dev
1558 PPCODE: 1566 PPCODE:
1559{ 1567{
1560 dREQ; 1568 dREQ;
1561 1569
1562 req->type = REQ_MKNOD; 1570 req->type = REQ_MKNOD;
1563 req->sv1 = newSVsv (pathname); 1571 req->sv1 = newSVsv (pathname);
1564 req->ptr1 = SvPVbyte_nolen (pathname); 1572 req->ptr1 = SvPVbyte_nolen (req->sv1);
1565 req->mode = (mode_t)mode; 1573 req->mode = (mode_t)mode;
1566 req->offs = dev; 1574 req->offs = dev;
1567 1575
1568 REQ_SEND; 1576 REQ_SEND;
1569} 1577}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines