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.162 by root, Sun Jan 10 23:05:12 2010 UTC vs.
Revision 1.170 by root, Wed Aug 4 16:09:36 2010 UTC

18#include <fcntl.h> 18#include <fcntl.h>
19#include <sched.h> 19#include <sched.h>
20 20
21#if _POSIX_MEMLOCK || _POSIX_MAPPED_FILES 21#if _POSIX_MEMLOCK || _POSIX_MAPPED_FILES
22# include <sys/mman.h> 22# include <sys/mman.h>
23#endif
24
25#if !_POSIX_MAPPED_FILES
26# define mmap(addr,length,prot,flags,fd,offs) (errno = ENOSYS, -1)
27# define munmap(addr,length) (errno = ENOSYS, -1)
28#endif 23#endif
29 24
30/* perl namespace pollution */ 25/* perl namespace pollution */
31#undef VERSION 26#undef VERSION
32 27
145#endif 140#endif
146#ifndef POSIX_FADV_DONTNEED 141#ifndef POSIX_FADV_DONTNEED
147# define POSIX_FADV_DONTNEED 0 142# define POSIX_FADV_DONTNEED 0
148#endif 143#endif
149 144
145#if _XOPEN_SOURCE < 600 || NO_FADVISE
146# define posix_fadvise(a,b,c,d) errno = ENOSYS /* also return ENOSYS */
147#endif
148
149#ifndef POSIX_MADV_NORMAL
150# define POSIX_MADV_NORMAL 0
151# define NO_MADVISE 1
152#endif
153#ifndef POSIX_MADV_SEQUENTIAL
154# define POSIX_MADV_SEQUENTIAL 0
155#endif
156#ifndef POSIX_MADV_RANDOM
157# define POSIX_MADV_RANDOM 0
158#endif
159#ifndef POSIX_MADV_WILLNEED
160# define POSIX_MADV_WILLNEED 0
161#endif
162#ifndef POSIX_MADV_DONTNEED
163# define POSIX_MADV_DONTNEED 0
164#endif
165
166#if _XOPEN_SOURCE < 600 || NO_MADVISE
167# define posix_madvise(a,b,c) errno = ENOSYS /* also return ENOSYS */
168#endif
169
150#ifndef ST_NODEV 170#ifndef ST_NODEV
151# define ST_NODEV 0 171# define ST_NODEV 0
152#endif 172#endif
153#ifndef ST_NOEXEC 173#ifndef ST_NOEXEC
154# define ST_NOEXEC 0 174# define ST_NOEXEC 0
309 } 329 }
310} 330}
311 331
312static int req_invoke (eio_req *req) 332static int req_invoke (eio_req *req)
313{ 333{
314 dSP;
315
316 if (req->flags & FLAG_SV2_RO_OFF) 334 if (req->flags & FLAG_SV2_RO_OFF)
317 SvREADONLY_off (req->sv2); 335 SvREADONLY_off (req->sv2);
318 336
319 if (!EIO_CANCELLED (req) && req->callback) 337 if (!EIO_CANCELLED (req) && req->callback)
320 { 338 {
339 dSP;
340 static SV *sv_result_cache; /* caches the result integer SV */
341 SV *sv_result;
342
321 ENTER; 343 ENTER;
322 SAVETMPS; 344 SAVETMPS;
323 PUSHMARK (SP); 345 PUSHMARK (SP);
324 EXTEND (SP, 1); 346 EXTEND (SP, 1);
347
348 /* do not recreate the result IV from scratch each time */
349 if (expect_true (sv_result_cache))
350 {
351 sv_result = sv_result_cache; sv_result_cache = 0;
352 SvIV_set (sv_result, req->result);
353 }
354 else
355 {
356 sv_result = newSViv (req->result);
357 SvREADONLY_on (sv_result);
358 }
325 359
326 switch (req->type) 360 switch (req->type)
327 { 361 {
328 case EIO_READDIR: 362 case EIO_READDIR:
329 { 363 {
474 case EIO_LSTAT: 508 case EIO_LSTAT:
475 case EIO_FSTAT: 509 case EIO_FSTAT:
476 PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; 510 PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT;
477 PL_laststatval = req->result; 511 PL_laststatval = req->result;
478 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); 512 PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2);
479 PUSHs (sv_2mortal (newSViv (req->result))); 513 PUSHs (sv_result);
480 break; 514 break;
481 515
482 case EIO_READ: 516 case EIO_READ:
483 { 517 {
484 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); 518 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0));
485 *SvEND (req->sv2) = 0; 519 *SvEND (req->sv2) = 0;
486 SvPOK_only (req->sv2); 520 SvPOK_only (req->sv2);
487 SvSETMAGIC (req->sv2); 521 SvSETMAGIC (req->sv2);
488 PUSHs (sv_2mortal (newSViv (req->result))); 522 PUSHs (sv_result);
489 } 523 }
490 break; 524 break;
491 525
492 case EIO_DUP2: 526 case EIO_DUP2: /* EIO_DUP2 actually means aio_close(), su fudge result value */
493 if (req->result > 0) 527 if (req->result > 0)
494 req->result = 0; 528 SvIV_set (sv_result, 0);
495 /* FALLTHROUGH */ 529 /* FALLTHROUGH */
496 530
497 default: 531 default:
498 PUSHs (sv_2mortal (newSViv (req->result))); 532 PUSHs (sv_result);
499 break; 533 break;
500 } 534 }
501 535
502 errno = req->errorno; 536 errno = req->errorno;
503 537
504 PUTBACK; 538 PUTBACK;
505 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD); 539 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD);
506 SPAGAIN; 540 SPAGAIN;
541
542 if (expect_false (SvREFCNT (sv_result) != 1 || sv_result_cache))
543 SvREFCNT_dec (sv_result);
544 else
545 sv_result_cache = sv_result;
507 546
508 FREETMPS; 547 FREETMPS;
509 LEAVE; 548 LEAVE;
510 549
511 PUTBACK; 550 PUTBACK;
589 create_respipe (); 628 create_respipe ();
590} 629}
591 630
592/*****************************************************************************/ 631/*****************************************************************************/
593 632
633#if !_POSIX_MAPPED_FILES
634# define mmap(addr,length,prot,flags,fd,offs) (errno = ENOSYS, -1)
635# define munmap(addr,length) (errno = ENOSYS, -1)
636#endif
637
594#define MMAP_MAGIC PERL_MAGIC_ext 638#define MMAP_MAGIC PERL_MAGIC_ext
595 639
596static int 640static int
597mmap_free (pTHX_ SV *sv, MAGIC *mg) 641mmap_free (pTHX_ SV *sv, MAGIC *mg)
598{ 642{
601 errno = old_errno; 645 errno = old_errno;
602 646
603 mg->mg_obj = 0; /* just in case */ 647 mg->mg_obj = 0; /* just in case */
604 648
605 SvREADONLY_off (sv); 649 SvREADONLY_off (sv);
650
651 if (SvPVX (sv) != mg->mg_ptr)
652 croak ("ERROR: IO::AIO::mmap-mapped scalar changed location, detected");
653
606 SvCUR_set (sv, 0); 654 SvCUR_set (sv, 0);
607 SvLEN_set (sv, 0);
608 SvPVX (sv) = 0; 655 SvPVX (sv) = 0;
609 SvOK_off (sv); 656 SvOK_off (sv);
610 657
611 return 0; 658 return 0;
612} 659}
662# define const_eio(name) { # name, (IV) EIO_ ## name }, 709# define const_eio(name) { # name, (IV) EIO_ ## name },
663 const_iv (EXDEV) 710 const_iv (EXDEV)
664 const_iv (ENOSYS) 711 const_iv (ENOSYS)
665 const_iv (O_RDONLY) 712 const_iv (O_RDONLY)
666 const_iv (O_WRONLY) 713 const_iv (O_WRONLY)
714 const_iv (O_RDWR)
667 const_iv (O_CREAT) 715 const_iv (O_CREAT)
668 const_iv (O_TRUNC) 716 const_iv (O_TRUNC)
717 const_iv (O_EXCL)
718 const_iv (O_APPEND)
669#ifndef _WIN32 719#ifndef _WIN32
670 const_iv (S_IFIFO) 720 const_iv (S_IFIFO)
671#endif 721#endif
672 const_niv (FADV_NORMAL , POSIX_FADV_NORMAL) 722 const_niv (FADV_NORMAL , POSIX_FADV_NORMAL)
673 const_niv (FADV_SEQUENTIAL, POSIX_FADV_SEQUENTIAL) 723 const_niv (FADV_SEQUENTIAL, POSIX_FADV_SEQUENTIAL)
674 const_niv (FADV_RANDOM , POSIX_FADV_RANDOM) 724 const_niv (FADV_RANDOM , POSIX_FADV_RANDOM)
675 const_niv (FADV_NOREUSE , POSIX_FADV_NOREUSE) 725 const_niv (FADV_NOREUSE , POSIX_FADV_NOREUSE)
676 const_niv (FADV_WILLNEED , POSIX_FADV_WILLNEED) 726 const_niv (FADV_WILLNEED , POSIX_FADV_WILLNEED)
677 const_niv (FADV_DONTNEED , POSIX_FADV_DONTNEED) 727 const_niv (FADV_DONTNEED , POSIX_FADV_DONTNEED)
728
729 const_niv (MADV_NORMAL , POSIX_MADV_NORMAL)
730 const_niv (MADV_SEQUENTIAL, POSIX_MADV_SEQUENTIAL)
731 const_niv (MADV_RANDOM , POSIX_MADV_RANDOM)
732 const_niv (MADV_WILLNEED , POSIX_MADV_WILLNEED)
733 const_niv (MADV_DONTNEED , POSIX_MADV_DONTNEED)
678 734
679 const_iv (ST_RDONLY) 735 const_iv (ST_RDONLY)
680 const_iv (ST_NOSUID) 736 const_iv (ST_NOSUID)
681 const_iv (ST_NODEV) 737 const_iv (ST_NODEV)
682 const_iv (ST_NOEXEC) 738 const_iv (ST_NOEXEC)
1337 1393
1338int 1394int
1339fadvise (aio_rfd fh, off_t offset, off_t length, IV advice) 1395fadvise (aio_rfd fh, off_t offset, off_t length, IV advice)
1340 PROTOTYPE: $$$$ 1396 PROTOTYPE: $$$$
1341 CODE: 1397 CODE:
1342#if _XOPEN_SOURCE >= 600 && !NO_FADVISE
1343 RETVAL = posix_fadvise (fh, offset, length, advice); 1398 RETVAL = posix_fadvise (fh, offset, length, advice);
1344#else
1345 RETVAL = errno = ENOSYS; /* yes, this is actually correct */
1346#endif
1347 OUTPUT: 1399 OUTPUT:
1348 RETVAL 1400 RETVAL
1349 1401
1350ssize_t 1402ssize_t
1351sendfile (aio_wfd ofh, aio_rfd ifh, off_t offset, size_t count) 1403sendfile (aio_wfd ofh, aio_rfd ifh, off_t offset, size_t count)
1364 int fd = SvOK (fh) ? s_fileno_croak (fh, flags & PROT_WRITE) : -1; 1416 int fd = SvOK (fh) ? s_fileno_croak (fh, flags & PROT_WRITE) : -1;
1365 void *addr = (void *)mmap (0, length, prot, flags, fd, offset); 1417 void *addr = (void *)mmap (0, length, prot, flags, fd, offset);
1366 if (addr == (void *)-1) 1418 if (addr == (void *)-1)
1367 XSRETURN_NO; 1419 XSRETURN_NO;
1368 1420
1421 sv_force_normal (scalar);
1422
1369 /* we store the length in mg_obj, as namlen is I32 :/ */ 1423 /* we store the length in mg_obj, as namlen is I32 :/ */
1370 sv_magicext (scalar, 0, MMAP_MAGIC, &mmap_vtbl, (char *)addr, 0) 1424 sv_magicext (scalar, 0, MMAP_MAGIC, &mmap_vtbl, (char *)addr, 0)
1371 ->mg_obj = (SV *)length; 1425 ->mg_obj = (SV *)length;
1372 1426
1373 SvUPGRADE (scalar, SVt_PV); /* nop... */ 1427 SvUPGRADE (scalar, SVt_PV); /* nop... */
1428
1374 if (!(prot & PROT_WRITE)) 1429 if (!(prot & PROT_WRITE))
1375 SvREADONLY_on (scalar); 1430 SvREADONLY_on (scalar);
1431
1432 if (SvLEN (scalar))
1433 Safefree (SvPVX (scalar));
1376 1434
1377 SvPVX (scalar) = (char *)addr; 1435 SvPVX (scalar) = (char *)addr;
1378 SvCUR_set (scalar, length); 1436 SvCUR_set (scalar, length);
1379 SvLEN_set (scalar, 0); 1437 SvLEN_set (scalar, 0);
1380 SvPOK_only (scalar); 1438 SvPOK_only (scalar);
1385void 1443void
1386munmap (SV *scalar) 1444munmap (SV *scalar)
1387 PROTOTYPE: $ 1445 PROTOTYPE: $
1388 CODE: 1446 CODE:
1389 sv_unmagic (scalar, MMAP_MAGIC); 1447 sv_unmagic (scalar, MMAP_MAGIC);
1448
1449int
1450madvise (SV *scalar, off_t offset, off_t length, IV advice)
1451 PROTOTYPE: $$$$
1452 CODE:
1453{
1454 char *addr = SvPV_nolen (scalar) + offset;
1455
1456 if (!SvOK (ST (2)))
1457 length = SvCUR (scalar) - offset;
1458
1459 if (addr >= SvEND (scalar) || length <= 0)
1460 XSRETURN_EMPTY;
1461
1462 RETVAL = posix_madvise (addr, length, advice);
1463}
1464 OUTPUT:
1465 RETVAL
1390 1466
1391int 1467int
1392mlockall (int flags) 1468mlockall (int flags)
1393 PROTOTYPE: $ 1469 PROTOTYPE: $
1394 CODE: 1470 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines