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.106 by root, Mon Sep 24 18:14:00 2007 UTC vs.
Revision 1.111 by root, Sun Mar 30 06:31:49 2008 UTC

97# define SvVAL64 SvIV 97# define SvVAL64 SvIV
98#else 98#else
99# define SvVAL64 SvNV 99# define SvVAL64 SvNV
100#endif 100#endif
101 101
102static HV *stash;
103
102#define dBUF \ 104#define dBUF \
103 char *aio_buf; \ 105 char *aio_buf; \
104 X_LOCK (wrklock); \ 106 X_LOCK (wrklock); \
105 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \ 107 self->dbuf = aio_buf = malloc (AIO_BUFSIZE); \
106 X_UNLOCK (wrklock); \ 108 X_UNLOCK (wrklock); \
117 REQ_STAT, REQ_LSTAT, REQ_FSTAT, 119 REQ_STAT, REQ_LSTAT, REQ_FSTAT,
118 REQ_TRUNCATE, REQ_FTRUNCATE, 120 REQ_TRUNCATE, REQ_FTRUNCATE,
119 REQ_UTIME, REQ_FUTIME, 121 REQ_UTIME, REQ_FUTIME,
120 REQ_CHMOD, REQ_FCHMOD, 122 REQ_CHMOD, REQ_FCHMOD,
121 REQ_CHOWN, REQ_FCHOWN, 123 REQ_CHOWN, REQ_FCHOWN,
122 REQ_FSYNC, REQ_FDATASYNC, 124 REQ_SYNC, REQ_FSYNC, REQ_FDATASYNC,
123 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, 125 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME,
124 REQ_MKNOD, REQ_READDIR, 126 REQ_MKNOD, REQ_READDIR,
125 REQ_LINK, REQ_SYMLINK, REQ_READLINK, 127 REQ_LINK, REQ_SYMLINK, REQ_READLINK,
126 REQ_GROUP, REQ_NOP, 128 REQ_GROUP, REQ_NOP,
127 REQ_BUSY, 129 REQ_BUSY,
187 189
188static thread_t main_tid; 190static thread_t main_tid;
189static int main_sig; 191static int main_sig;
190static int block_sig_level; 192static int block_sig_level;
191 193
192void block_sig () 194void block_sig (void)
193{ 195{
194 sigset_t ss; 196 sigset_t ss;
195 197
196 if (block_sig_level++) 198 if (block_sig_level++)
197 return; 199 return;
202 sigemptyset (&ss); 204 sigemptyset (&ss);
203 sigaddset (&ss, main_sig); 205 sigaddset (&ss, main_sig);
204 pthread_sigmask (SIG_BLOCK, &ss, 0); 206 pthread_sigmask (SIG_BLOCK, &ss, 0);
205} 207}
206 208
207void unblock_sig () 209void unblock_sig (void)
208{ 210{
209 sigset_t ss; 211 sigset_t ss;
210 212
211 if (--block_sig_level) 213 if (--block_sig_level)
212 return; 214 return;
272static mutex_t reqlock = X_MUTEX_INIT; 274static mutex_t reqlock = X_MUTEX_INIT;
273static cond_t reqwait = X_COND_INIT; 275static cond_t reqwait = X_COND_INIT;
274 276
275#if WORDACCESS_UNSAFE 277#if WORDACCESS_UNSAFE
276 278
277static unsigned int get_nready () 279static unsigned int get_nready (void)
278{ 280{
279 unsigned int retval; 281 unsigned int retval;
280 282
281 X_LOCK (reqlock); 283 X_LOCK (reqlock);
282 retval = nready; 284 retval = nready;
283 X_UNLOCK (reqlock); 285 X_UNLOCK (reqlock);
284 286
285 return retval; 287 return retval;
286} 288}
287 289
288static unsigned int get_npending () 290static unsigned int get_npending (void)
289{ 291{
290 unsigned int retval; 292 unsigned int retval;
291 293
292 X_LOCK (reslock); 294 X_LOCK (reslock);
293 retval = npending; 295 retval = npending;
294 X_UNLOCK (reslock); 296 X_UNLOCK (reslock);
295 297
296 return retval; 298 return retval;
297} 299}
298 300
299static unsigned int get_nthreads () 301static unsigned int get_nthreads (void)
300{ 302{
301 unsigned int retval; 303 unsigned int retval;
302 304
303 X_LOCK (wrklock); 305 X_LOCK (wrklock);
304 retval = started; 306 retval = started;
367 } 369 }
368 370
369 abort (); 371 abort ();
370} 372}
371 373
372static int poll_cb (); 374static int poll_cb (void);
373static int req_invoke (aio_req req); 375static int req_invoke (aio_req req);
374static void req_destroy (aio_req req); 376static void req_destroy (aio_req req);
375static void req_cancel (aio_req req); 377static void req_cancel (aio_req req);
376 378
377/* must be called at most once */ 379/* must be called at most once */
501 break; 503 break;
502 504
503 case REQ_OPEN: 505 case REQ_OPEN:
504 { 506 {
505 /* convert fd to fh */ 507 /* convert fd to fh */
506 SV *fh; 508 SV *fh = &PL_sv_undef;
507 509
508 PUSHs (sv_2mortal (newSViv (req->result))); 510 if (req->result >= 0)
509 PUTBACK; 511 {
510 call_pv ("IO::AIO::_fd2fh", G_SCALAR | G_EVAL); 512 GV *gv = (GV *)sv_newmortal ();
511 SPAGAIN; 513 int flags = req->int1 & (O_RDONLY | O_WRONLY | O_RDWR);
514 char sym [64];
515 int symlen;
516
517 symlen = snprintf (sym, sizeof (sym), "fd#%d", req->result);
518 gv_init (gv, stash, sym, symlen, 0);
512 519
513 fh = POPs; 520 symlen = snprintf (
514 PUSHMARK (SP); 521 sym,
522 sizeof (sym),
523 "%s&=%d",
524 flags == O_RDONLY ? "<" : flags == O_WRONLY ? ">" : "+<",
525 req->result
526 );
527
528 if (do_open (gv, sym, symlen, 0, 0, 0, 0))
529 fh = (SV *)gv;
530 }
531
515 XPUSHs (fh); 532 PUSHs (fh);
516 } 533 }
517 break; 534 break;
518 535
519 case REQ_GROUP: 536 case REQ_GROUP:
520 req->int1 = 2; /* mark group as finished */ 537 req->int1 = 2; /* mark group as finished */
564 } 581 }
565 582
566 errno = req->errorno; 583 errno = req->errorno;
567 584
568 PUTBACK; 585 PUTBACK;
569 call_sv (req->callback, G_VOID | G_EVAL); 586 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD);
570 SPAGAIN; 587 SPAGAIN;
571 588
572 FREETMPS; 589 FREETMPS;
573 LEAVE; 590 LEAVE;
591
592 PUTBACK;
574 } 593 }
575 594
576 if (req->grp) 595 if (req->grp)
577 { 596 {
578 aio_req grp = req->grp; 597 aio_req grp = req->grp;
634#else 653#else
635# define TO_SOCKET(x) (x) 654# define TO_SOCKET(x) (x)
636#endif 655#endif
637 656
638static void 657static void
639create_respipe () 658create_respipe (void)
640{ 659{
641 int old_readfd = respipe [0]; 660 int old_readfd = respipe [0];
642 661
643 if (respipe [1] >= 0) 662 if (respipe [1] >= 0)
644 respipe_close (TO_SOCKET (respipe [1])); 663 respipe_close (TO_SOCKET (respipe [1]));
696 free (wrk); 715 free (wrk);
697 716
698 X_UNLOCK (wrklock); 717 X_UNLOCK (wrklock);
699} 718}
700 719
701static void maybe_start_thread () 720static void maybe_start_thread (void)
702{ 721{
703 if (get_nthreads () >= wanted) 722 if (get_nthreads () >= wanted)
704 return; 723 return;
705 724
706 /* todo: maybe use idle here, but might be less exact */ 725 /* todo: maybe use idle here, but might be less exact */
766 785
767 while (started > wanted) 786 while (started > wanted)
768 end_thread (); 787 end_thread ();
769} 788}
770 789
771static void poll_wait () 790static void poll_wait (void)
772{ 791{
773 fd_set rfd; 792 fd_set rfd;
774 793
775 while (nreqs) 794 while (nreqs)
776 { 795 {
789 808
790 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0); 809 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0);
791 } 810 }
792} 811}
793 812
794static int poll_cb () 813static int poll_cb (void)
795{ 814{
796 dSP; 815 dSP;
797 int count = 0; 816 int count = 0;
798 int maxreqs = max_poll_reqs; 817 int maxreqs = max_poll_reqs;
799 int do_croak = 0; 818 int do_croak = 0;
1248 case REQ_LINK: req->result = link (req->ptr2, req->ptr1); break; 1267 case REQ_LINK: req->result = link (req->ptr2, req->ptr1); break;
1249 case REQ_SYMLINK: req->result = symlink (req->ptr2, req->ptr1); break; 1268 case REQ_SYMLINK: req->result = symlink (req->ptr2, req->ptr1); break;
1250 case REQ_MKNOD: req->result = mknod (req->ptr2, req->mode, (dev_t)req->offs); break; 1269 case REQ_MKNOD: req->result = mknod (req->ptr2, req->mode, (dev_t)req->offs); break;
1251 case REQ_READLINK: req->result = readlink (req->ptr2, req->ptr1, NAME_MAX); break; 1270 case REQ_READLINK: req->result = readlink (req->ptr2, req->ptr1, NAME_MAX); break;
1252 1271
1272 case REQ_SYNC: req->result = 0; sync (); break;
1273 case REQ_FSYNC: req->result = fsync (req->int1); break;
1253 case REQ_FDATASYNC: req->result = fdatasync (req->int1); break; 1274 case REQ_FDATASYNC: req->result = fdatasync (req->int1); break;
1254 case REQ_FSYNC: req->result = fsync (req->int1); break; 1275
1255 case REQ_READDIR: scandir_ (req, self); break; 1276 case REQ_READDIR: scandir_ (req, self); break;
1256 1277
1257 case REQ_BUSY: 1278 case REQ_BUSY:
1258#ifdef _WIN32 1279#ifdef _WIN32
1259 Sleep (req->nv1 * 1000.); 1280 Sleep (req->nv1 * 1000.);
1421 1442
1422PROTOTYPES: ENABLE 1443PROTOTYPES: ENABLE
1423 1444
1424BOOT: 1445BOOT:
1425{ 1446{
1426 HV *stash = gv_stashpv ("IO::AIO", 1); 1447 stash = gv_stashpv ("IO::AIO", 1);
1427 1448
1428 newCONSTSUB (stash, "EXDEV", newSViv (EXDEV)); 1449 newCONSTSUB (stash, "EXDEV", newSViv (EXDEV));
1429 newCONSTSUB (stash, "O_RDONLY", newSViv (O_RDONLY)); 1450 newCONSTSUB (stash, "O_RDONLY", newSViv (O_RDONLY));
1430 newCONSTSUB (stash, "O_WRONLY", newSViv (O_WRONLY)); 1451 newCONSTSUB (stash, "O_WRONLY", newSViv (O_WRONLY));
1431 newCONSTSUB (stash, "O_CREAT", newSViv (O_CREAT)); 1452 newCONSTSUB (stash, "O_CREAT", newSViv (O_CREAT));
1499 1520
1500 REQ_SEND; 1521 REQ_SEND;
1501} 1522}
1502 1523
1503void 1524void
1504aio_close (SV *fh, SV *callback=&PL_sv_undef) 1525aio_fsync (SV *fh, SV *callback=&PL_sv_undef)
1505 PROTOTYPE: $;$ 1526 PROTOTYPE: $;$
1506 ALIAS: 1527 ALIAS:
1507 aio_close = REQ_CLOSE
1508 aio_fsync = REQ_FSYNC 1528 aio_fsync = REQ_FSYNC
1509 aio_fdatasync = REQ_FDATASYNC 1529 aio_fdatasync = REQ_FDATASYNC
1510 PPCODE: 1530 PPCODE:
1511{ 1531{
1512 dREQ; 1532 dREQ;
1513 1533
1514 req->type = ix; 1534 req->type = ix;
1515 req->sv1 = newSVsv (fh); 1535 req->sv1 = newSVsv (fh);
1516 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1536 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1537
1538 REQ_SEND (req);
1539}
1540
1541int
1542_dup (int fd)
1543 PROTOTYPE: $
1544 CODE:
1545 RETVAL = dup (fd);
1546 OUTPUT:
1547 RETVAL
1548
1549void
1550_aio_close (int fd, SV *callback=&PL_sv_undef)
1551 PROTOTYPE: $;$
1552 PPCODE:
1553{
1554 dREQ;
1555
1556 req->type = REQ_CLOSE;
1557 req->int1 = fd;
1517 1558
1518 REQ_SEND (req); 1559 REQ_SEND (req);
1519} 1560}
1520 1561
1521void 1562void
1848 XPUSHs (req_sv (req, AIO_GRP_KLASS)); 1889 XPUSHs (req_sv (req, AIO_GRP_KLASS));
1849} 1890}
1850 1891
1851void 1892void
1852aio_nop (SV *callback=&PL_sv_undef) 1893aio_nop (SV *callback=&PL_sv_undef)
1894 ALIAS:
1895 aio_nop = REQ_NOP
1896 aio_sync = REQ_SYNC
1853 PPCODE: 1897 PPCODE:
1854{ 1898{
1855 dREQ; 1899 dREQ;
1856 1900
1857 req->type = REQ_NOP; 1901 req->type = ix;
1858 1902
1859 REQ_SEND; 1903 REQ_SEND;
1860} 1904}
1861 1905
1862int 1906int
1948 1992
1949 block_sig (); 1993 block_sig ();
1950 PUSHMARK (SP); 1994 PUSHMARK (SP);
1951 PUTBACK; 1995 PUTBACK;
1952 count = call_sv (cb, GIMME_V | G_NOARGS | G_EVAL); 1996 count = call_sv (cb, GIMME_V | G_NOARGS | G_EVAL);
1953 SPAGAIN;
1954 unblock_sig (); 1997 unblock_sig ();
1955 1998
1956 if (SvTRUE (ERRSV)) 1999 if (SvTRUE (ERRSV))
1957 croak (0); 2000 croak (0);
1958 2001

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines