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.108 by root, Thu Oct 4 12:50:35 2007 UTC vs.
Revision 1.112 by root, Tue Apr 1 19:40:47 2008 UTC

119 REQ_STAT, REQ_LSTAT, REQ_FSTAT, 119 REQ_STAT, REQ_LSTAT, REQ_FSTAT,
120 REQ_TRUNCATE, REQ_FTRUNCATE, 120 REQ_TRUNCATE, REQ_FTRUNCATE,
121 REQ_UTIME, REQ_FUTIME, 121 REQ_UTIME, REQ_FUTIME,
122 REQ_CHMOD, REQ_FCHMOD, 122 REQ_CHMOD, REQ_FCHMOD,
123 REQ_CHOWN, REQ_FCHOWN, 123 REQ_CHOWN, REQ_FCHOWN,
124 REQ_FSYNC, REQ_FDATASYNC, 124 REQ_SYNC, REQ_FSYNC, REQ_FDATASYNC,
125 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, 125 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME,
126 REQ_MKNOD, REQ_READDIR, 126 REQ_MKNOD, REQ_READDIR,
127 REQ_LINK, REQ_SYMLINK, REQ_READLINK, 127 REQ_LINK, REQ_SYMLINK, REQ_READLINK,
128 REQ_GROUP, REQ_NOP, 128 REQ_GROUP, REQ_NOP,
129 REQ_BUSY, 129 REQ_BUSY,
189 189
190static thread_t main_tid; 190static thread_t main_tid;
191static int main_sig; 191static int main_sig;
192static int block_sig_level; 192static int block_sig_level;
193 193
194void block_sig () 194void block_sig (void)
195{ 195{
196 sigset_t ss; 196 sigset_t ss;
197 197
198 if (block_sig_level++) 198 if (block_sig_level++)
199 return; 199 return;
204 sigemptyset (&ss); 204 sigemptyset (&ss);
205 sigaddset (&ss, main_sig); 205 sigaddset (&ss, main_sig);
206 pthread_sigmask (SIG_BLOCK, &ss, 0); 206 pthread_sigmask (SIG_BLOCK, &ss, 0);
207} 207}
208 208
209void unblock_sig () 209void unblock_sig (void)
210{ 210{
211 sigset_t ss; 211 sigset_t ss;
212 212
213 if (--block_sig_level) 213 if (--block_sig_level)
214 return; 214 return;
274static mutex_t reqlock = X_MUTEX_INIT; 274static mutex_t reqlock = X_MUTEX_INIT;
275static cond_t reqwait = X_COND_INIT; 275static cond_t reqwait = X_COND_INIT;
276 276
277#if WORDACCESS_UNSAFE 277#if WORDACCESS_UNSAFE
278 278
279static unsigned int get_nready () 279static unsigned int get_nready (void)
280{ 280{
281 unsigned int retval; 281 unsigned int retval;
282 282
283 X_LOCK (reqlock); 283 X_LOCK (reqlock);
284 retval = nready; 284 retval = nready;
285 X_UNLOCK (reqlock); 285 X_UNLOCK (reqlock);
286 286
287 return retval; 287 return retval;
288} 288}
289 289
290static unsigned int get_npending () 290static unsigned int get_npending (void)
291{ 291{
292 unsigned int retval; 292 unsigned int retval;
293 293
294 X_LOCK (reslock); 294 X_LOCK (reslock);
295 retval = npending; 295 retval = npending;
296 X_UNLOCK (reslock); 296 X_UNLOCK (reslock);
297 297
298 return retval; 298 return retval;
299} 299}
300 300
301static unsigned int get_nthreads () 301static unsigned int get_nthreads (void)
302{ 302{
303 unsigned int retval; 303 unsigned int retval;
304 304
305 X_LOCK (wrklock); 305 X_LOCK (wrklock);
306 retval = started; 306 retval = started;
369 } 369 }
370 370
371 abort (); 371 abort ();
372} 372}
373 373
374static int poll_cb (); 374static int poll_cb (void);
375static int req_invoke (aio_req req); 375static int req_invoke (aio_req req);
376static void req_destroy (aio_req req); 376static void req_destroy (aio_req req);
377static void req_cancel (aio_req req); 377static void req_cancel (aio_req req);
378 378
379/* must be called at most once */ 379/* must be called at most once */
527 527
528 if (do_open (gv, sym, symlen, 0, 0, 0, 0)) 528 if (do_open (gv, sym, symlen, 0, 0, 0, 0))
529 fh = (SV *)gv; 529 fh = (SV *)gv;
530 } 530 }
531 531
532 XPUSHs (fh); 532 PUSHs (fh);
533 } 533 }
534 break; 534 break;
535 535
536 case REQ_GROUP: 536 case REQ_GROUP:
537 req->int1 = 2; /* mark group as finished */ 537 req->int1 = 2; /* mark group as finished */
581 } 581 }
582 582
583 errno = req->errorno; 583 errno = req->errorno;
584 584
585 PUTBACK; 585 PUTBACK;
586 call_sv (req->callback, G_VOID | G_EVAL); 586 call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD);
587 SPAGAIN; 587 SPAGAIN;
588 588
589 FREETMPS; 589 FREETMPS;
590 LEAVE; 590 LEAVE;
591
592 PUTBACK;
591 } 593 }
592 594
593 if (req->grp) 595 if (req->grp)
594 { 596 {
595 aio_req grp = req->grp; 597 aio_req grp = req->grp;
651#else 653#else
652# define TO_SOCKET(x) (x) 654# define TO_SOCKET(x) (x)
653#endif 655#endif
654 656
655static void 657static void
656create_respipe () 658create_respipe (void)
657{ 659{
658 int old_readfd = respipe [0]; 660 int old_readfd = respipe [0];
659 661
660 if (respipe [1] >= 0) 662 if (respipe [1] >= 0)
661 respipe_close (TO_SOCKET (respipe [1])); 663 respipe_close (TO_SOCKET (respipe [1]));
713 free (wrk); 715 free (wrk);
714 716
715 X_UNLOCK (wrklock); 717 X_UNLOCK (wrklock);
716} 718}
717 719
718static void maybe_start_thread () 720static void maybe_start_thread (void)
719{ 721{
720 if (get_nthreads () >= wanted) 722 if (get_nthreads () >= wanted)
721 return; 723 return;
722 724
723 /* todo: maybe use idle here, but might be less exact */ 725 /* todo: maybe use idle here, but might be less exact */
783 785
784 while (started > wanted) 786 while (started > wanted)
785 end_thread (); 787 end_thread ();
786} 788}
787 789
788static void poll_wait () 790static void poll_wait (void)
789{ 791{
790 fd_set rfd; 792 fd_set rfd;
791 793
792 while (nreqs) 794 while (nreqs)
793 { 795 {
806 808
807 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0); 809 PerlSock_select (respipe [0] + 1, &rfd, 0, 0, 0);
808 } 810 }
809} 811}
810 812
811static int poll_cb () 813static int poll_cb (void)
812{ 814{
813 dSP; 815 dSP;
814 int count = 0; 816 int count = 0;
815 int maxreqs = max_poll_reqs; 817 int maxreqs = max_poll_reqs;
816 int do_croak = 0; 818 int do_croak = 0;
1180 1182
1181/*****************************************************************************/ 1183/*****************************************************************************/
1182 1184
1183X_THREAD_PROC (aio_proc) 1185X_THREAD_PROC (aio_proc)
1184{ 1186{
1185 {//D
1186 aio_req req; 1187 aio_req req;
1187 struct timespec ts; 1188 struct timespec ts;
1188 worker *self = (worker *)thr_arg; 1189 worker *self = (worker *)thr_arg;
1189 1190
1190 /* try to distribute timeouts somewhat randomly */ 1191 /* try to distribute timeouts somewhat randomly */
1255 case REQ_FCHMOD: req->result = fchmod (req->int1, req->mode); break; 1256 case REQ_FCHMOD: req->result = fchmod (req->int1, req->mode); break;
1256 case REQ_TRUNCATE: req->result = truncate (req->ptr1, req->offs); break; 1257 case REQ_TRUNCATE: req->result = truncate (req->ptr1, req->offs); break;
1257 case REQ_FTRUNCATE: req->result = ftruncate (req->int1, req->offs); break; 1258 case REQ_FTRUNCATE: req->result = ftruncate (req->int1, req->offs); break;
1258 1259
1259 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; 1260 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break;
1260 case REQ_CLOSE: req->result = PerlIO_close ((PerlIO *)req->ptr1); break; 1261 case REQ_CLOSE: req->result = close (req->int1); break;
1261 case REQ_UNLINK: req->result = unlink (req->ptr1); break; 1262 case REQ_UNLINK: req->result = unlink (req->ptr1); break;
1262 case REQ_RMDIR: req->result = rmdir (req->ptr1); break; 1263 case REQ_RMDIR: req->result = rmdir (req->ptr1); break;
1263 case REQ_MKDIR: req->result = mkdir (req->ptr1, req->mode); break; 1264 case REQ_MKDIR: req->result = mkdir (req->ptr1, req->mode); break;
1264 case REQ_RENAME: req->result = rename (req->ptr2, req->ptr1); break; 1265 case REQ_RENAME: req->result = rename (req->ptr2, req->ptr1); break;
1265 case REQ_LINK: req->result = link (req->ptr2, req->ptr1); break; 1266 case REQ_LINK: req->result = link (req->ptr2, req->ptr1); break;
1266 case REQ_SYMLINK: req->result = symlink (req->ptr2, req->ptr1); break; 1267 case REQ_SYMLINK: req->result = symlink (req->ptr2, req->ptr1); break;
1267 case REQ_MKNOD: req->result = mknod (req->ptr2, req->mode, (dev_t)req->offs); break; 1268 case REQ_MKNOD: req->result = mknod (req->ptr2, req->mode, (dev_t)req->offs); break;
1268 case REQ_READLINK: req->result = readlink (req->ptr2, req->ptr1, NAME_MAX); break; 1269 case REQ_READLINK: req->result = readlink (req->ptr2, req->ptr1, NAME_MAX); break;
1269 1270
1271 case REQ_SYNC: req->result = 0; sync (); break;
1272 case REQ_FSYNC: req->result = fsync (req->int1); break;
1270 case REQ_FDATASYNC: req->result = fdatasync (req->int1); break; 1273 case REQ_FDATASYNC: req->result = fdatasync (req->int1); break;
1271 case REQ_FSYNC: req->result = fsync (req->int1); break; 1274
1272 case REQ_READDIR: scandir_ (req, self); break; 1275 case REQ_READDIR: scandir_ (req, self); break;
1273 1276
1274 case REQ_BUSY: 1277 case REQ_BUSY:
1275#ifdef _WIN32 1278#ifdef _WIN32
1276 Sleep (req->nv1 * 1000.); 1279 Sleep (req->nv1 * 1000.);
1348 X_LOCK (wrklock); 1351 X_LOCK (wrklock);
1349 worker_free (self); 1352 worker_free (self);
1350 X_UNLOCK (wrklock); 1353 X_UNLOCK (wrklock);
1351 1354
1352 return 0; 1355 return 0;
1353 }//D
1354} 1356}
1355 1357
1356/*****************************************************************************/ 1358/*****************************************************************************/
1357 1359
1358static void atfork_prepare (void) 1360static void atfork_prepare (void)
1532 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1534 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1533 1535
1534 REQ_SEND (req); 1536 REQ_SEND (req);
1535} 1537}
1536 1538
1539int
1540_dup (int fd)
1541 PROTOTYPE: $
1542 CODE:
1543 RETVAL = dup (fd);
1544 OUTPUT:
1545 RETVAL
1546
1537void 1547void
1538aio_close (SV *fh, SV *callback=&PL_sv_undef) 1548_aio_close (int fd, SV *callback=&PL_sv_undef)
1539 PROTOTYPE: $;$ 1549 PROTOTYPE: $;$
1540 PPCODE: 1550 PPCODE:
1541{ 1551{
1542 PerlIO *io = IoIFP (sv_2io (fh));
1543 int fd = PerlIO_fileno (io);
1544
1545 if (fd < 0)
1546 croak ("aio_close called with fd-less filehandle");
1547
1548 PerlIO_binmode (aTHX_ io, 0, 0, 0);
1549
1550 {
1551 dREQ; 1552 dREQ;
1552 1553
1553 req->type = REQ_CLOSE; 1554 req->type = REQ_CLOSE;
1554 req->sv1 = newSVsv (fh); 1555 req->int1 = fd;
1555 req->ptr1 = (void *)io;
1556 1556
1557 REQ_SEND (req); 1557 REQ_SEND (req);
1558 }
1559} 1558}
1560 1559
1561void 1560void
1562aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef) 1561aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef)
1563 ALIAS: 1562 ALIAS:
1888 XPUSHs (req_sv (req, AIO_GRP_KLASS)); 1887 XPUSHs (req_sv (req, AIO_GRP_KLASS));
1889} 1888}
1890 1889
1891void 1890void
1892aio_nop (SV *callback=&PL_sv_undef) 1891aio_nop (SV *callback=&PL_sv_undef)
1892 ALIAS:
1893 aio_nop = REQ_NOP
1894 aio_sync = REQ_SYNC
1893 PPCODE: 1895 PPCODE:
1894{ 1896{
1895 dREQ; 1897 dREQ;
1896 1898
1897 req->type = REQ_NOP; 1899 req->type = ix;
1898 1900
1899 REQ_SEND; 1901 REQ_SEND;
1900} 1902}
1901 1903
1902int 1904int
1988 1990
1989 block_sig (); 1991 block_sig ();
1990 PUSHMARK (SP); 1992 PUSHMARK (SP);
1991 PUTBACK; 1993 PUTBACK;
1992 count = call_sv (cb, GIMME_V | G_NOARGS | G_EVAL); 1994 count = call_sv (cb, GIMME_V | G_NOARGS | G_EVAL);
1993 SPAGAIN;
1994 unblock_sig (); 1995 unblock_sig ();
1995 1996
1996 if (SvTRUE (ERRSV)) 1997 if (SvTRUE (ERRSV))
1997 croak (0); 1998 croak (0);
1998 1999

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines