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.164 by root, Tue May 4 21:14:01 2010 UTC vs.
Revision 1.166 by root, Sun May 9 20:43:28 2010 UTC

304 } 304 }
305} 305}
306 306
307static int req_invoke (eio_req *req) 307static int req_invoke (eio_req *req)
308{ 308{
309 dSP;
310
311 if (req->flags & FLAG_SV2_RO_OFF) 309 if (req->flags & FLAG_SV2_RO_OFF)
312 SvREADONLY_off (req->sv2); 310 SvREADONLY_off (req->sv2);
313 311
314 if (!EIO_CANCELLED (req) && req->callback) 312 if (!EIO_CANCELLED (req) && req->callback)
315 { 313 {
314 dSP;
315 static SV *sv_result_cache; /* caches the result integer SV */
316 SV *sv_result;
317
316 ENTER; 318 ENTER;
317 SAVETMPS; 319 SAVETMPS;
318 PUSHMARK (SP); 320 PUSHMARK (SP);
319 EXTEND (SP, 1); 321 EXTEND (SP, 1);
322
323 /* do not recreate the result IV from scratch each time */
324 if (expect_true (sv_result_cache))
325 {
326 sv_result = sv_result_cache; sv_result_cache = 0;
327 SvIV_set (sv_result, req->result);
328 }
329 else
330 {
331 sv_result = newSViv (req->result);
332 SvREADONLY_on (sv_result);
333 }
320 334
321 switch (req->type) 335 switch (req->type)
322 { 336 {
323 case EIO_READDIR: 337 case EIO_READDIR:
324 { 338 {
469 case EIO_LSTAT: 483 case EIO_LSTAT:
470 case EIO_FSTAT: 484 case EIO_FSTAT:
471 PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; 485 PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT;
472 PL_laststatval = req->result; 486 PL_laststatval = req->result;
473 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); 487 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2);
474 PUSHs (sv_2mortal (newSViv (req->result))); 488 PUSHs (sv_result);
475 break; 489 break;
476 490
477 case EIO_READ: 491 case EIO_READ:
478 { 492 {
479 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); 493 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0));
480 *SvEND (req->sv2) = 0; 494 *SvEND (req->sv2) = 0;
481 SvPOK_only (req->sv2); 495 SvPOK_only (req->sv2);
482 SvSETMAGIC (req->sv2); 496 SvSETMAGIC (req->sv2);
483 PUSHs (sv_2mortal (newSViv (req->result))); 497 PUSHs (sv_result);
484 } 498 }
485 break; 499 break;
486 500
487 case EIO_DUP2: 501 case EIO_DUP2:
488 if (req->result > 0) 502 if (req->result > 0)
489 req->result = 0; 503 SvIV_set (sv_result, 0);
490 /* FALLTHROUGH */ 504 /* FALLTHROUGH */
491 505
492 default: 506 default:
493 PUSHs (sv_2mortal (newSViv (req->result))); 507 PUSHs (sv_result);
494 break; 508 break;
495 } 509 }
496 510
497 errno = req->errorno; 511 errno = req->errorno;
498 512
499 PUTBACK; 513 PUTBACK;
500 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD); 514 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD);
501 SPAGAIN; 515 SPAGAIN;
516
517 if (expect_false (SvREFCNT (sv_result) != 1 || sv_result_cache))
518 SvREFCNT_dec (sv_result);
519 else
520 sv_result_cache = sv_result;
502 521
503 FREETMPS; 522 FREETMPS;
504 LEAVE; 523 LEAVE;
505 524
506 PUTBACK; 525 PUTBACK;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines