… | |
… | |
111 | struct aio_cb *volatile next; |
111 | struct aio_cb *volatile next; |
112 | |
112 | |
113 | SV *callback, *fh; |
113 | SV *callback, *fh; |
114 | SV *sv1, *sv2; |
114 | SV *sv1, *sv2; |
115 | void *ptr1, *ptr2; |
115 | void *ptr1, *ptr2; |
116 | Stat_t *statdata; |
|
|
117 | off_t offs; |
116 | off_t offs; |
118 | size_t size; |
117 | size_t size; |
119 | ssize_t result; |
118 | ssize_t result; |
120 | |
119 | |
121 | STRLEN stroffset; |
120 | STRLEN stroffset; |
… | |
… | |
130 | SV *self; /* the perl counterpart of this request, if any */ |
129 | SV *self; /* the perl counterpart of this request, if any */ |
131 | struct aio_cb *grp, *grp_prev, *grp_next, *grp_first; |
130 | struct aio_cb *grp, *grp_prev, *grp_next, *grp_first; |
132 | } aio_cb; |
131 | } aio_cb; |
133 | |
132 | |
134 | enum { |
133 | enum { |
135 | FLAG_CANCELLED = 0x01, |
134 | FLAG_CANCELLED = 0x01, |
136 | FLAG_DATA_RO_OFF = 0x80, /* data was set readonly */ |
135 | FLAG_SV1_RO_OFF = 0x40, /* data was set readonly */ |
|
|
136 | FLAG_PTR2_FREE = 0x80, /* need free(ptr2) */ |
137 | }; |
137 | }; |
138 | |
138 | |
139 | typedef aio_cb *aio_req; |
139 | typedef aio_cb *aio_req; |
140 | typedef aio_cb *aio_req_ornot; |
140 | typedef aio_cb *aio_req_ornot; |
141 | |
141 | |
… | |
… | |
396 | |
396 | |
397 | static void req_invoke (aio_req req) |
397 | static void req_invoke (aio_req req) |
398 | { |
398 | { |
399 | dSP; |
399 | dSP; |
400 | |
400 | |
401 | if (req->flags & FLAG_DATA_RO_OFF) |
401 | if (req->flags & FLAG_SV1_RO_OFF) |
402 | SvREADONLY_off (req->sv1); |
402 | 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 | |
403 | |
411 | if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) |
404 | if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) |
412 | { |
405 | { |
413 | ENTER; |
406 | ENTER; |
414 | SAVETMPS; |
407 | SAVETMPS; |
… | |
… | |
486 | *SvEND (req->sv1) = 0; |
479 | *SvEND (req->sv1) = 0; |
487 | PUSHs (req->sv1); |
480 | PUSHs (req->sv1); |
488 | } |
481 | } |
489 | break; |
482 | break; |
490 | |
483 | |
|
|
484 | case REQ_STAT: |
|
|
485 | case REQ_LSTAT: |
|
|
486 | case REQ_FSTAT: |
|
|
487 | PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT; |
|
|
488 | PL_laststatval = req->result; |
|
|
489 | PL_statcache = *(Stat_t *)(req->ptr2); |
|
|
490 | PUSHs (sv_2mortal (newSViv (req->result))); |
|
|
491 | break; |
|
|
492 | |
491 | case REQ_READ: |
493 | case REQ_READ: |
492 | SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); |
494 | SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); |
493 | *SvEND (req->sv1) = 0; |
495 | *SvEND (req->sv1) = 0; |
494 | /* fall through */ |
496 | PUSHs (sv_2mortal (newSViv (req->result))); |
|
|
497 | break; |
|
|
498 | |
495 | default: |
499 | default: |
496 | PUSHs (sv_2mortal (newSViv (req->result))); |
500 | PUSHs (sv_2mortal (newSViv (req->result))); |
497 | break; |
501 | break; |
498 | } |
502 | } |
499 | |
503 | |
… | |
… | |
538 | |
542 | |
539 | SvREFCNT_dec (req->fh); |
543 | SvREFCNT_dec (req->fh); |
540 | SvREFCNT_dec (req->sv1); |
544 | SvREFCNT_dec (req->sv1); |
541 | SvREFCNT_dec (req->sv2); |
545 | SvREFCNT_dec (req->sv2); |
542 | SvREFCNT_dec (req->callback); |
546 | SvREFCNT_dec (req->callback); |
543 | Safefree (req->statdata); |
|
|
544 | |
547 | |
545 | if (req->type == REQ_READDIR) |
548 | if (req->flags & FLAG_PTR2_FREE) |
546 | free (req->ptr2); |
549 | free (req->ptr2); |
547 | |
550 | |
548 | Safefree (req); |
551 | Safefree (req); |
549 | } |
552 | } |
550 | |
553 | |
… | |
… | |
997 | int errorno; |
1000 | int errorno; |
998 | |
1001 | |
999 | LOCK (wrklock); |
1002 | LOCK (wrklock); |
1000 | self->dirp = dirp = opendir (req->ptr1); |
1003 | self->dirp = dirp = opendir (req->ptr1); |
1001 | self->dbuf = u = malloc (sizeof (*u)); |
1004 | self->dbuf = u = malloc (sizeof (*u)); |
|
|
1005 | req->flags |= FLAG_PTR2_FREE; |
1002 | req->ptr2 = names = malloc (memlen); |
1006 | req->ptr2 = names = malloc (memlen); |
1003 | UNLOCK (wrklock); |
1007 | UNLOCK (wrklock); |
1004 | |
1008 | |
1005 | if (dirp && u && names) |
1009 | if (dirp && u && names) |
1006 | for (;;) |
1010 | for (;;) |
… | |
… | |
1102 | case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; |
1106 | case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; |
1103 | |
1107 | |
1104 | case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; |
1108 | 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; |
1109 | case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; |
1106 | |
1110 | |
1107 | case REQ_STAT: req->result = stat (req->ptr1, req->statdata); break; |
1111 | 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; |
1112 | 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; |
1113 | case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break; |
1110 | |
1114 | |
1111 | case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; |
1115 | case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; |
1112 | case REQ_CLOSE: req->result = close (req->int1); break; |
1116 | case REQ_CLOSE: req->result = close (req->int1); break; |
1113 | case REQ_UNLINK: req->result = unlink (req->ptr1); break; |
1117 | case REQ_UNLINK: req->result = unlink (req->ptr1); break; |
1114 | case REQ_RMDIR: req->result = rmdir (req->ptr1); break; |
1118 | case REQ_RMDIR: req->result = rmdir (req->ptr1); break; |
… | |
… | |
1400 | req->stroffset = dataoffset; |
1404 | req->stroffset = dataoffset; |
1401 | |
1405 | |
1402 | if (!SvREADONLY (data)) |
1406 | if (!SvREADONLY (data)) |
1403 | { |
1407 | { |
1404 | SvREADONLY_on (data); |
1408 | SvREADONLY_on (data); |
1405 | req->flags |= FLAG_DATA_RO_OFF; |
1409 | req->flags |= FLAG_SV1_RO_OFF; |
1406 | } |
1410 | } |
1407 | |
1411 | |
1408 | REQ_SEND; |
1412 | REQ_SEND; |
1409 | } |
1413 | } |
1410 | } |
1414 | } |
… | |
… | |
1483 | aio_lstat = REQ_LSTAT |
1487 | aio_lstat = REQ_LSTAT |
1484 | PPCODE: |
1488 | PPCODE: |
1485 | { |
1489 | { |
1486 | dREQ; |
1490 | dREQ; |
1487 | |
1491 | |
1488 | New (0, req->statdata, 1, Stat_t); |
1492 | req->ptr2 = malloc (sizeof (Stat_t)); |
1489 | if (!req->statdata) |
1493 | if (!req->ptr2) |
1490 | { |
1494 | { |
1491 | req_free (req); |
1495 | req_free (req); |
1492 | croak ("out of memory during aio_req->statdata allocation"); |
1496 | croak ("out of memory during aio_stat statdata allocation"); |
1493 | } |
1497 | } |
|
|
1498 | |
|
|
1499 | req->flags |= FLAG_PTR2_FREE; |
1494 | |
1500 | |
1495 | if (SvPOK (fh_or_path)) |
1501 | if (SvPOK (fh_or_path)) |
1496 | { |
1502 | { |
1497 | req->type = ix; |
1503 | req->type = ix; |
1498 | req->sv1 = newSVsv (fh_or_path); |
1504 | req->sv1 = newSVsv (fh_or_path); |
… | |
… | |
1521 | dREQ; |
1527 | dREQ; |
1522 | |
1528 | |
1523 | req->type = ix; |
1529 | req->type = ix; |
1524 | req->sv1 = newSVsv (pathname); |
1530 | req->sv1 = newSVsv (pathname); |
1525 | req->ptr1 = SvPVbyte_nolen (pathname); |
1531 | req->ptr1 = SvPVbyte_nolen (pathname); |
1526 | |
1532 | |
1527 | REQ_SEND; |
1533 | REQ_SEND; |
1528 | } |
1534 | } |
1529 | |
1535 | |
1530 | void |
1536 | void |
1531 | aio_link (oldpath,newpath,callback=&PL_sv_undef) |
1537 | aio_link (oldpath,newpath,callback=&PL_sv_undef) |