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.97 by root, Sun Jan 7 22:59:57 2007 UTC vs.
Revision 1.100 by root, Fri Jun 1 06:00:40 2007 UTC

1/* solaris */ 1#include "xthread.h"
2#define _POSIX_PTHREAD_SEMANTICS 1
3
4#if __linux && !defined(_GNU_SOURCE)
5# define _GNU_SOURCE
6#endif
7
8/* just in case */
9#define _REENTRANT 1
10 2
11#include <errno.h> 3#include <errno.h>
12 4
13#include "EXTERN.h" 5#include "EXTERN.h"
14#include "perl.h" 6#include "perl.h"
15#include "XSUB.h" 7#include "XSUB.h"
16 8
17#include "autoconf/config.h" 9#include "autoconf/config.h"
18
19#include <pthread.h>
20 10
21#include <stddef.h> 11#include <stddef.h>
22#include <stdlib.h> 12#include <stdlib.h>
23#include <errno.h> 13#include <errno.h>
24#include <sys/time.h> 14#include <sys/time.h>
28#include <limits.h> 18#include <limits.h>
29#include <unistd.h> 19#include <unistd.h>
30#include <fcntl.h> 20#include <fcntl.h>
31#include <signal.h> 21#include <signal.h>
32#include <sched.h> 22#include <sched.h>
23#include <utime.h>
33 24
34#if HAVE_SENDFILE 25#if HAVE_SENDFILE
35# if __linux 26# if __linux
36# include <sys/sendfile.h> 27# include <sys/sendfile.h>
37# elif __freebsd 28# elif __freebsd
52/* used for struct dirent, AIX doesn't provide it */ 43/* used for struct dirent, AIX doesn't provide it */
53#ifndef NAME_MAX 44#ifndef NAME_MAX
54# define NAME_MAX 4096 45# define NAME_MAX 4096
55#endif 46#endif
56 47
57#ifndef PTHREAD_STACK_MIN
58/* care for broken platforms, e.g. windows */
59# define PTHREAD_STACK_MIN 16384
60#endif
61
62#if __ia64
63# define STACKSIZE 65536
64#elif __i386 || __x86_64 /* 16k is unreasonably high :( */
65# define STACKSIZE PTHREAD_STACK_MIN
66#else
67# define STACKSIZE 16384
68#endif
69
70/* wether word reads are potentially non-atomic.
71 * this is conservatice, likely most arches this runs
72 * on have atomic word read/writes.
73 */
74#ifndef WORDACCESS_UNSAFE
75# if __i386 || __x86_64
76# define WORDACCESS_UNSAFE 0
77# else
78# define WORDACCESS_UNSAFE 1
79# endif
80#endif
81
82/* buffer size for various temporary buffers */ 48/* buffer size for various temporary buffers */
83#define AIO_BUFSIZE 65536 49#define AIO_BUFSIZE 65536
84 50
85#define dBUF \ 51#define dBUF \
86 char *aio_buf; \ 52 char *aio_buf; \
96 REQ_QUIT, 62 REQ_QUIT,
97 REQ_OPEN, REQ_CLOSE, 63 REQ_OPEN, REQ_CLOSE,
98 REQ_READ, REQ_WRITE, REQ_READAHEAD, 64 REQ_READ, REQ_WRITE, REQ_READAHEAD,
99 REQ_SENDFILE, 65 REQ_SENDFILE,
100 REQ_STAT, REQ_LSTAT, REQ_FSTAT, 66 REQ_STAT, REQ_LSTAT, REQ_FSTAT,
67 REQ_UTIME, REQ_FUTIME, /* must be consecutive */
68 REQ_CHMOD, REQ_FCHMOD, /* must be consecutive */
69 REQ_CHOWN, REQ_FCHOWN, /* must be consecutive */
101 REQ_FSYNC, REQ_FDATASYNC, 70 REQ_FSYNC, REQ_FDATASYNC,
102 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, 71 REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME,
103 REQ_MKNOD, REQ_READDIR, 72 REQ_MKNOD, REQ_READDIR,
104 REQ_LINK, REQ_SYMLINK, REQ_READLINK, 73 REQ_LINK, REQ_SYMLINK, REQ_READLINK,
105 REQ_GROUP, REQ_NOP, 74 REQ_GROUP, REQ_NOP,
111 80
112typedef struct aio_cb 81typedef struct aio_cb
113{ 82{
114 struct aio_cb *volatile next; 83 struct aio_cb *volatile next;
115 84
116 SV *callback, *fh; 85 SV *callback;
117 SV *sv1, *sv2; 86 SV *sv1, *sv2;
118 void *ptr1, *ptr2; 87 void *ptr1, *ptr2;
119 off_t offs; 88 off_t offs;
120 size_t size; 89 size_t size;
121 ssize_t result; 90 ssize_t result;
91 double nv1, nv2;
122 92
123 STRLEN stroffset; 93 STRLEN stroffset;
124 int type; 94 int type;
125 int int1, int2; 95 int int1, int2, int3;
126 int errorno; 96 int errorno;
127 mode_t mode; /* open */ 97 mode_t mode; /* open */
128 98
129 unsigned char flags; 99 unsigned char flags;
130 unsigned char pri; 100 unsigned char pri;
133 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first; 103 struct aio_cb *grp, *grp_prev, *grp_next, *grp_first;
134} aio_cb; 104} aio_cb;
135 105
136enum { 106enum {
137 FLAG_CANCELLED = 0x01, /* request was cancelled */ 107 FLAG_CANCELLED = 0x01, /* request was cancelled */
138 FLAG_SV1_RO_OFF = 0x40, /* data was set readonly */ 108 FLAG_SV2_RO_OFF = 0x40, /* data was set readonly */
139 FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */ 109 FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */
140}; 110};
141 111
142typedef aio_cb *aio_req; 112typedef aio_cb *aio_req;
143typedef aio_cb *aio_req_ornot; 113typedef aio_cb *aio_req_ornot;
161{ 131{
162 return (tv2->tv_sec - tv1->tv_sec ) * AIO_TICKS 132 return (tv2->tv_sec - tv1->tv_sec ) * AIO_TICKS
163 + ((tv2->tv_usec - tv1->tv_usec) >> 10); 133 + ((tv2->tv_usec - tv1->tv_usec) >> 10);
164} 134}
165 135
166static pthread_t main_tid; 136static thread_t main_tid;
167static int main_sig; 137static int main_sig;
168static int block_sig_level; 138static int block_sig_level;
169 139
170void block_sig () 140void block_sig ()
171{ 141{
199 169
200static int next_pri = DEFAULT_PRI + PRI_BIAS; 170static int next_pri = DEFAULT_PRI + PRI_BIAS;
201 171
202static unsigned int started, idle, wanted; 172static unsigned int started, idle, wanted;
203 173
204#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
205# define AIO_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
206#else
207# define AIO_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
208#endif
209
210#define LOCK(mutex) pthread_mutex_lock (&(mutex))
211#define UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
212
213/* worker threads management */ 174/* worker threads management */
214static pthread_mutex_t wrklock = AIO_MUTEX_INIT; 175static mutex_t wrklock = MUTEX_INIT;
215 176
216typedef struct worker { 177typedef struct worker {
217 /* locked by wrklock */ 178 /* locked by wrklock */
218 struct worker *prev, *next; 179 struct worker *prev, *next;
219 180
220 pthread_t tid; 181 thread_t tid;
221 182
222 /* locked by reslock, reqlock or wrklock */ 183 /* locked by reslock, reqlock or wrklock */
223 aio_req req; /* currently processed request */ 184 aio_req req; /* currently processed request */
224 void *dbuf; 185 void *dbuf;
225 DIR *dirp; 186 DIR *dirp;
253static volatile unsigned int nreqs, nready, npending; 214static volatile unsigned int nreqs, nready, npending;
254static volatile unsigned int max_idle = 4; 215static volatile unsigned int max_idle = 4;
255static volatile unsigned int max_outstanding = 0xffffffff; 216static volatile unsigned int max_outstanding = 0xffffffff;
256static int respipe [2]; 217static int respipe [2];
257 218
258static pthread_mutex_t reslock = AIO_MUTEX_INIT; 219static mutex_t reslock = MUTEX_INIT;
259static pthread_mutex_t reqlock = AIO_MUTEX_INIT; 220static mutex_t reqlock = MUTEX_INIT;
260static pthread_cond_t reqwait = PTHREAD_COND_INITIALIZER; 221static cond_t reqwait = COND_INIT;
261 222
262#if WORDACCESS_UNSAFE 223#if WORDACCESS_UNSAFE
263 224
264static unsigned int get_nready () 225static unsigned int get_nready ()
265{ 226{
446 407
447static int req_invoke (aio_req req) 408static int req_invoke (aio_req req)
448{ 409{
449 dSP; 410 dSP;
450 411
451 if (req->flags & FLAG_SV1_RO_OFF) 412 if (req->flags & FLAG_SV2_RO_OFF)
452 SvREADONLY_off (req->sv1); 413 SvREADONLY_off (req->sv2);
453 414
454 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) 415 if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback))
455 { 416 {
456 ENTER; 417 ENTER;
457 SAVETMPS; 418 SAVETMPS;
522 break; 483 break;
523 484
524 case REQ_READLINK: 485 case REQ_READLINK:
525 if (req->result > 0) 486 if (req->result > 0)
526 { 487 {
527 SvCUR_set (req->sv1, req->result); 488 SvCUR_set (req->sv2, req->result);
528 *SvEND (req->sv1) = 0; 489 *SvEND (req->sv2) = 0;
529 PUSHs (req->sv1); 490 PUSHs (req->sv2);
530 } 491 }
531 break; 492 break;
532 493
533 case REQ_STAT: 494 case REQ_STAT:
534 case REQ_LSTAT: 495 case REQ_LSTAT:
538 PL_statcache = *(Stat_t *)(req->ptr2); 499 PL_statcache = *(Stat_t *)(req->ptr2);
539 PUSHs (sv_2mortal (newSViv (req->result))); 500 PUSHs (sv_2mortal (newSViv (req->result)));
540 break; 501 break;
541 502
542 case REQ_READ: 503 case REQ_READ:
543 SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); 504 SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0));
544 *SvEND (req->sv1) = 0; 505 *SvEND (req->sv2) = 0;
545 PUSHs (sv_2mortal (newSViv (req->result))); 506 PUSHs (sv_2mortal (newSViv (req->result)));
546 break; 507 break;
547 508
548 default: 509 default:
549 PUSHs (sv_2mortal (newSViv (req->result))); 510 PUSHs (sv_2mortal (newSViv (req->result)));
583 { 544 {
584 sv_unmagic (req->self, PERL_MAGIC_ext); 545 sv_unmagic (req->self, PERL_MAGIC_ext);
585 SvREFCNT_dec (req->self); 546 SvREFCNT_dec (req->self);
586 } 547 }
587 548
588 SvREFCNT_dec (req->fh);
589 SvREFCNT_dec (req->sv1); 549 SvREFCNT_dec (req->sv1);
590 SvREFCNT_dec (req->sv2); 550 SvREFCNT_dec (req->sv2);
591 SvREFCNT_dec (req->callback); 551 SvREFCNT_dec (req->callback);
592 552
593 if (req->flags & FLAG_PTR2_FREE) 553 if (req->flags & FLAG_PTR2_FREE)
619 579
620static void *aio_proc(void *arg); 580static void *aio_proc(void *arg);
621 581
622static void start_thread (void) 582static void start_thread (void)
623{ 583{
624 sigset_t fullsigset, oldsigset;
625 pthread_attr_t attr;
626
627 worker *wrk = calloc (1, sizeof (worker)); 584 worker *wrk = calloc (1, sizeof (worker));
628 585
629 if (!wrk) 586 if (!wrk)
630 croak ("unable to allocate worker thread data"); 587 croak ("unable to allocate worker thread data");
631 588
632 pthread_attr_init (&attr);
633 pthread_attr_setstacksize (&attr, STACKSIZE);
634 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
635#ifdef PTHREAD_SCOPE_PROCESS
636 pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
637#endif
638
639 sigfillset (&fullsigset);
640
641 LOCK (wrklock); 589 LOCK (wrklock);
642 pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
643 590
644 if (pthread_create (&wrk->tid, &attr, aio_proc, (void *)wrk) == 0) 591 if (thread_create (&wrk->tid, aio_proc, (void *)wrk))
645 { 592 {
646 wrk->prev = &wrk_first; 593 wrk->prev = &wrk_first;
647 wrk->next = wrk_first.next; 594 wrk->next = wrk_first.next;
648 wrk_first.next->prev = wrk; 595 wrk_first.next->prev = wrk;
649 wrk_first.next = wrk; 596 wrk_first.next = wrk;
650 ++started; 597 ++started;
651 } 598 }
652 else 599 else
653 free (wrk); 600 free (wrk);
654 601
655 pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
656 UNLOCK (wrklock); 602 UNLOCK (wrklock);
657} 603}
658 604
659static void maybe_start_thread () 605static void maybe_start_thread ()
660{ 606{
675 ++nreqs; 621 ++nreqs;
676 622
677 LOCK (reqlock); 623 LOCK (reqlock);
678 ++nready; 624 ++nready;
679 reqq_push (&req_queue, req); 625 reqq_push (&req_queue, req);
680 pthread_cond_signal (&reqwait); 626 COND_SIGNAL (reqwait);
681 UNLOCK (reqlock); 627 UNLOCK (reqlock);
682 628
683 unblock_sig (); 629 unblock_sig ();
684 630
685 maybe_start_thread (); 631 maybe_start_thread ();
694 req->type = REQ_QUIT; 640 req->type = REQ_QUIT;
695 req->pri = PRI_MAX + PRI_BIAS; 641 req->pri = PRI_MAX + PRI_BIAS;
696 642
697 LOCK (reqlock); 643 LOCK (reqlock);
698 reqq_push (&req_queue, req); 644 reqq_push (&req_queue, req);
699 pthread_cond_signal (&reqwait); 645 COND_SIGNAL (reqwait);
700 UNLOCK (reqlock); 646 UNLOCK (reqlock);
701 647
702 LOCK (wrklock); 648 LOCK (wrklock);
703 --started; 649 --started;
704 UNLOCK (wrklock); 650 UNLOCK (wrklock);
857/* 803/*
858 * make our pread/pwrite safe against themselves, but not against 804 * make our pread/pwrite safe against themselves, but not against
859 * normal read/write by using a mutex. slows down execution a lot, 805 * normal read/write by using a mutex. slows down execution a lot,
860 * but that's your problem, not mine. 806 * but that's your problem, not mine.
861 */ 807 */
862static pthread_mutex_t preadwritelock = PTHREAD_MUTEX_INITIALIZER; 808static mutex_t preadwritelock = MUTEX_INIT;
863 809
864static ssize_t pread (int fd, void *buf, size_t count, off_t offset) 810static ssize_t pread (int fd, void *buf, size_t count, off_t offset)
865{ 811{
866 ssize_t res; 812 ssize_t res;
867 off_t ooffset; 813 off_t ooffset;
890 836
891 return res; 837 return res;
892} 838}
893#endif 839#endif
894 840
841#ifndef HAVE_FUTIMES
842
843# define utimes(path,times) aio_utimes (path, times)
844# define futimes(fd,times) aio_futimes (fd, times)
845
846int aio_utimes (const char *filename, const struct timeval times[2])
847{
848 if (times)
849 {
850 struct utimbuf buf;
851
852 buf.actime = times[0].tv_sec;
853 buf.modtime = times[1].tv_sec;
854
855 return utime (filename, &buf);
856 }
857 else
858 return utime (filename, 0);
859}
860
861int aio_futimes (int fd, const struct timeval tv[2])
862{
863 errno = ENOSYS;
864 return -1;
865}
866
867#endif
868
895#if !HAVE_FDATASYNC 869#if !HAVE_FDATASYNC
896# define fdatasync fsync 870# define fdatasync fsync
897#endif 871#endif
898 872
899#if !HAVE_READAHEAD 873#if !HAVE_READAHEAD
918#endif 892#endif
919 893
920#if !HAVE_READDIR_R 894#if !HAVE_READDIR_R
921# define readdir_r aio_readdir_r 895# define readdir_r aio_readdir_r
922 896
923static pthread_mutex_t readdirlock = PTHREAD_MUTEX_INITIALIZER; 897static mutex_t readdirlock = MUTEX_INIT;
924 898
925static int readdir_r (DIR *dirp, struct dirent *ent, struct dirent **res) 899static int readdir_r (DIR *dirp, struct dirent *ent, struct dirent **res)
926{ 900{
927 struct dirent *e; 901 struct dirent *e;
928 int errorno; 902 int errorno;
1127 if (req) 1101 if (req)
1128 break; 1102 break;
1129 1103
1130 ++idle; 1104 ++idle;
1131 1105
1132 if (pthread_cond_timedwait (&reqwait, &reqlock, &ts) 1106 if (COND_TIMEDWAIT (reqwait, reqlock, ts)
1133 == ETIMEDOUT) 1107 == ETIMEDOUT)
1134 { 1108 {
1135 if (idle > max_idle) 1109 if (idle > max_idle)
1136 { 1110 {
1137 --idle; 1111 --idle;
1141 UNLOCK (wrklock); 1115 UNLOCK (wrklock);
1142 goto quit; 1116 goto quit;
1143 } 1117 }
1144 1118
1145 /* we are allowed to idle, so do so without any timeout */ 1119 /* we are allowed to idle, so do so without any timeout */
1146 pthread_cond_wait (&reqwait, &reqlock); 1120 COND_WAIT (reqwait, reqlock);
1147 ts.tv_sec = time (0) + IDLE_TIMEOUT; 1121 ts.tv_sec = time (0) + IDLE_TIMEOUT;
1148 } 1122 }
1149 1123
1150 --idle; 1124 --idle;
1151 } 1125 }
1166 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; 1140 case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break;
1167 1141
1168 case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break; 1142 case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break;
1169 case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break; 1143 case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break;
1170 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break; 1144 case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break;
1145
1146 case REQ_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break;
1147 case REQ_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break;
1148 case REQ_CHMOD: req->result = chmod (req->ptr1, req->mode); break;
1149 case REQ_FCHMOD: req->result = fchmod (req->int1, req->mode); break;
1171 1150
1172 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; 1151 case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break;
1173 case REQ_CLOSE: req->result = close (req->int1); break; 1152 case REQ_CLOSE: req->result = close (req->int1); break;
1174 case REQ_UNLINK: req->result = unlink (req->ptr1); break; 1153 case REQ_UNLINK: req->result = unlink (req->ptr1); break;
1175 case REQ_RMDIR: req->result = rmdir (req->ptr1); break; 1154 case REQ_RMDIR: req->result = rmdir (req->ptr1); break;
1186 1165
1187 case REQ_BUSY: 1166 case REQ_BUSY:
1188 { 1167 {
1189 struct timeval tv; 1168 struct timeval tv;
1190 1169
1191 tv.tv_sec = req->int1; 1170 tv.tv_sec = req->nv1;
1192 tv.tv_usec = req->int2; 1171 tv.tv_usec = (req->nv1 - tv.tv_usec) * 1000000.;
1193 1172
1194 req->result = select (0, 0, 0, 0, &tv); 1173 req->result = select (0, 0, 0, 0, &tv);
1174 }
1175
1176 case REQ_UTIME:
1177 case REQ_FUTIME:
1178 {
1179 struct timeval tv[2];
1180 struct timeval *times;
1181
1182 if (req->nv1 != -1. || req->nv2 != -1.)
1183 {
1184 tv[0].tv_sec = req->nv1;
1185 tv[0].tv_usec = (req->nv1 - tv[0].tv_sec) * 1000000.;
1186 tv[1].tv_sec = req->nv2;
1187 tv[1].tv_usec = (req->nv2 - tv[1].tv_sec) * 1000000.;
1188
1189 times = tv;
1190 }
1191 else
1192 times = 0;
1193
1194
1195 req->result = req->type == REQ_FUTIME
1196 ? futimes (req->int1, times)
1197 : utimes (req->ptr1, times);
1195 } 1198 }
1196 1199
1197 case REQ_GROUP: 1200 case REQ_GROUP:
1198 case REQ_NOP: 1201 case REQ_NOP:
1199 break; 1202 break;
1200 1203
1201 case REQ_QUIT: 1204 case REQ_QUIT:
1202 goto quit; 1205 goto quit;
1203 1206
1204 default: 1207 default:
1205 req->result = ENOSYS; 1208 req->result = -1;
1206 break; 1209 break;
1207 } 1210 }
1208 1211
1209 req->errorno = errno; 1212 req->errorno = errno;
1210 1213
1334 newCONSTSUB (stash, "O_TRUNC", newSViv (O_TRUNC)); 1337 newCONSTSUB (stash, "O_TRUNC", newSViv (O_TRUNC));
1335 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); 1338 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO));
1336 newCONSTSUB (stash, "SIGIO", newSViv (SIGIO)); 1339 newCONSTSUB (stash, "SIGIO", newSViv (SIGIO));
1337 1340
1338 create_pipe (); 1341 create_pipe ();
1339 pthread_atfork (atfork_prepare, atfork_parent, atfork_child); 1342 ATFORK (atfork_prepare, atfork_parent, atfork_child);
1340} 1343}
1341 1344
1342void 1345void
1343max_poll_reqs (int nreqs) 1346max_poll_reqs (int nreqs)
1344 PROTOTYPE: $ 1347 PROTOTYPE: $
1373 max_outstanding = maxreqs; 1376 max_outstanding = maxreqs;
1374 OUTPUT: 1377 OUTPUT:
1375 RETVAL 1378 RETVAL
1376 1379
1377void 1380void
1378aio_open (pathname,flags,mode,callback=&PL_sv_undef) 1381aio_open (SV8 *pathname, int flags, int mode, SV *callback=&PL_sv_undef)
1379 SV8 * pathname
1380 int flags
1381 int mode
1382 SV * callback
1383 PROTOTYPE: $$$;$ 1382 PROTOTYPE: $$$;$
1384 PPCODE: 1383 PPCODE:
1385{ 1384{
1386 dREQ; 1385 dREQ;
1387 1386
1393 1392
1394 REQ_SEND; 1393 REQ_SEND;
1395} 1394}
1396 1395
1397void 1396void
1398aio_close (fh,callback=&PL_sv_undef) 1397aio_close (SV *fh, SV *callback=&PL_sv_undef)
1399 SV * fh
1400 SV * callback
1401 PROTOTYPE: $;$ 1398 PROTOTYPE: $;$
1402 ALIAS: 1399 ALIAS:
1403 aio_close = REQ_CLOSE 1400 aio_close = REQ_CLOSE
1404 aio_fsync = REQ_FSYNC 1401 aio_fsync = REQ_FSYNC
1405 aio_fdatasync = REQ_FDATASYNC 1402 aio_fdatasync = REQ_FDATASYNC
1406 PPCODE: 1403 PPCODE:
1407{ 1404{
1408 dREQ; 1405 dREQ;
1409 1406
1410 req->type = ix; 1407 req->type = ix;
1411 req->fh = newSVsv (fh); 1408 req->sv1 = newSVsv (fh);
1412 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1409 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1413 1410
1414 REQ_SEND (req); 1411 REQ_SEND (req);
1415} 1412}
1416 1413
1417void 1414void
1418aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef) 1415aio_read (SV *fh, UV offset, UV length, SV8 *data, UV dataoffset, SV *callback=&PL_sv_undef)
1419 SV * fh
1420 UV offset
1421 UV length
1422 SV8 * data
1423 UV dataoffset
1424 SV * callback
1425 ALIAS: 1416 ALIAS:
1426 aio_read = REQ_READ 1417 aio_read = REQ_READ
1427 aio_write = REQ_WRITE 1418 aio_write = REQ_WRITE
1428 PROTOTYPE: $$$$$;$ 1419 PROTOTYPE: $$$$$;$
1429 PPCODE: 1420 PPCODE:
1457 1448
1458 { 1449 {
1459 dREQ; 1450 dREQ;
1460 1451
1461 req->type = ix; 1452 req->type = ix;
1462 req->fh = newSVsv (fh); 1453 req->sv1 = newSVsv (fh);
1463 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh)) 1454 req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh))
1464 : IoOFP (sv_2io (fh))); 1455 : IoOFP (sv_2io (fh)));
1465 req->offs = offset; 1456 req->offs = offset;
1466 req->size = length; 1457 req->size = length;
1467 req->sv1 = SvREFCNT_inc (data); 1458 req->sv2 = SvREFCNT_inc (data);
1468 req->ptr1 = (char *)svptr + dataoffset; 1459 req->ptr1 = (char *)svptr + dataoffset;
1469 req->stroffset = dataoffset; 1460 req->stroffset = dataoffset;
1470 1461
1471 if (!SvREADONLY (data)) 1462 if (!SvREADONLY (data))
1472 { 1463 {
1473 SvREADONLY_on (data); 1464 SvREADONLY_on (data);
1474 req->flags |= FLAG_SV1_RO_OFF; 1465 req->flags |= FLAG_SV2_RO_OFF;
1475 } 1466 }
1476 1467
1477 REQ_SEND; 1468 REQ_SEND;
1478 } 1469 }
1479} 1470}
1480 1471
1481void 1472void
1482aio_readlink (path,callback=&PL_sv_undef) 1473aio_readlink (SV8 *path, SV *callback=&PL_sv_undef)
1483 SV8 * path
1484 SV * callback
1485 PROTOTYPE: $$;$ 1474 PROTOTYPE: $$;$
1486 PPCODE: 1475 PPCODE:
1487{ 1476{
1488 SV *data; 1477 SV *data;
1489 dREQ; 1478 dREQ;
1490 1479
1491 data = newSV (NAME_MAX); 1480 data = newSV (NAME_MAX);
1492 SvPOK_on (data); 1481 SvPOK_on (data);
1493 1482
1494 req->type = REQ_READLINK; 1483 req->type = REQ_READLINK;
1495 req->fh = newSVsv (path); 1484 req->sv1 = newSVsv (path);
1496 req->ptr2 = SvPVbyte_nolen (req->fh); 1485 req->ptr2 = SvPVbyte_nolen (req->sv1);
1497 req->sv1 = data; 1486 req->sv2 = data;
1498 req->ptr1 = SvPVbyte_nolen (data); 1487 req->ptr1 = SvPVbyte_nolen (data);
1499 1488
1500 REQ_SEND; 1489 REQ_SEND;
1501} 1490}
1502 1491
1503void 1492void
1504aio_sendfile (out_fh,in_fh,in_offset,length,callback=&PL_sv_undef) 1493aio_sendfile (SV *out_fh, SV *in_fh, UV in_offset, UV length, SV *callback=&PL_sv_undef)
1505 SV * out_fh
1506 SV * in_fh
1507 UV in_offset
1508 UV length
1509 SV * callback
1510 PROTOTYPE: $$$$;$ 1494 PROTOTYPE: $$$$;$
1511 PPCODE: 1495 PPCODE:
1512{ 1496{
1513 dREQ; 1497 dREQ;
1514 1498
1515 req->type = REQ_SENDFILE; 1499 req->type = REQ_SENDFILE;
1516 req->fh = newSVsv (out_fh); 1500 req->sv1 = newSVsv (out_fh);
1517 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); 1501 req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh)));
1518 req->sv2 = newSVsv (in_fh); 1502 req->sv2 = newSVsv (in_fh);
1519 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); 1503 req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh)));
1520 req->offs = in_offset; 1504 req->offs = in_offset;
1521 req->size = length; 1505 req->size = length;
1522 1506
1523 REQ_SEND; 1507 REQ_SEND;
1524} 1508}
1525 1509
1526void 1510void
1527aio_readahead (fh,offset,length,callback=&PL_sv_undef) 1511aio_readahead (SV *fh, UV offset, IV length, SV *callback=&PL_sv_undef)
1528 SV * fh
1529 UV offset
1530 IV length
1531 SV * callback
1532 PROTOTYPE: $$$;$ 1512 PROTOTYPE: $$$;$
1533 PPCODE: 1513 PPCODE:
1534{ 1514{
1535 dREQ; 1515 dREQ;
1536 1516
1537 req->type = REQ_READAHEAD; 1517 req->type = REQ_READAHEAD;
1538 req->fh = newSVsv (fh); 1518 req->sv1 = newSVsv (fh);
1539 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); 1519 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh)));
1540 req->offs = offset; 1520 req->offs = offset;
1541 req->size = length; 1521 req->size = length;
1542 1522
1543 REQ_SEND; 1523 REQ_SEND;
1544} 1524}
1545 1525
1546void 1526void
1547aio_stat (fh_or_path,callback=&PL_sv_undef) 1527aio_stat (SV8 *fh_or_path, SV *callback=&PL_sv_undef)
1548 SV8 * fh_or_path
1549 SV * callback
1550 ALIAS: 1528 ALIAS:
1551 aio_stat = REQ_STAT 1529 aio_stat = REQ_STAT
1552 aio_lstat = REQ_LSTAT 1530 aio_lstat = REQ_LSTAT
1553 PPCODE: 1531 PPCODE:
1554{ 1532{
1560 req_free (req); 1538 req_free (req);
1561 croak ("out of memory during aio_stat statdata allocation"); 1539 croak ("out of memory during aio_stat statdata allocation");
1562 } 1540 }
1563 1541
1564 req->flags |= FLAG_PTR2_FREE; 1542 req->flags |= FLAG_PTR2_FREE;
1543 req->sv1 = newSVsv (fh_or_path);
1565 1544
1566 if (SvPOK (fh_or_path)) 1545 if (SvPOK (fh_or_path))
1567 { 1546 {
1568 req->type = ix; 1547 req->type = ix;
1569 req->sv1 = newSVsv (fh_or_path);
1570 req->ptr1 = SvPVbyte_nolen (req->sv1); 1548 req->ptr1 = SvPVbyte_nolen (req->sv1);
1571 } 1549 }
1572 else 1550 else
1573 { 1551 {
1574 req->type = REQ_FSTAT; 1552 req->type = REQ_FSTAT;
1575 req->fh = newSVsv (fh_or_path);
1576 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path))); 1553 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1577 } 1554 }
1578 1555
1579 REQ_SEND; 1556 REQ_SEND;
1580} 1557}
1581 1558
1582void 1559void
1560aio_utime (SV8 *fh_or_path, SV *atime, SV *mtime, SV *callback=&PL_sv_undef)
1561 PPCODE:
1562{
1563 dREQ;
1564
1565 req->nv1 = SvOK (atime) ? SvNV (atime) : -1.;
1566 req->nv2 = SvOK (mtime) ? SvNV (mtime) : -1.;
1567 req->sv1 = newSVsv (fh_or_path);
1568
1569 if (SvPOK (fh_or_path))
1570 {
1571 req->type = REQ_UTIME;
1572 req->ptr1 = SvPVbyte_nolen (req->sv1);
1573 }
1574 else
1575 {
1576 req->type = REQ_FUTIME;
1577 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1578 }
1579
1580 REQ_SEND;
1581}
1582
1583void
1584aio_chmod (SV8 *fh_or_path, int mode, SV *callback=&PL_sv_undef)
1585 PPCODE:
1586{
1587 dREQ;
1588
1589 req->mode = mode;
1590 req->sv1 = newSVsv (fh_or_path);
1591
1592 if (SvPOK (fh_or_path))
1593 {
1594 req->type = REQ_CHMOD;
1595 req->ptr1 = SvPVbyte_nolen (req->sv1);
1596 }
1597 else
1598 {
1599 req->type = REQ_FCHMOD;
1600 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1601 }
1602
1603 REQ_SEND;
1604}
1605
1606void
1607aio_chown (SV8 *fh_or_path, SV *uid, SV *gid, SV *callback=&PL_sv_undef)
1608 PPCODE:
1609{
1610 dREQ;
1611
1612 req->int2 = SvOK (uid) ? SvIV (uid) : -1;
1613 req->int3 = SvOK (gid) ? SvIV (gid) : -1;
1614 req->sv1 = newSVsv (fh_or_path);
1615
1616 if (SvPOK (fh_or_path))
1617 {
1618 req->type = REQ_CHOWN;
1619 req->ptr1 = SvPVbyte_nolen (req->sv1);
1620 }
1621 else
1622 {
1623 req->type = REQ_FCHOWN;
1624 req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh_or_path)));
1625 }
1626
1627 REQ_SEND;
1628}
1629
1630void
1583aio_unlink (pathname,callback=&PL_sv_undef) 1631aio_unlink (SV8 *pathname, SV *callback=&PL_sv_undef)
1584 SV8 * pathname
1585 SV * callback
1586 ALIAS: 1632 ALIAS:
1587 aio_unlink = REQ_UNLINK 1633 aio_unlink = REQ_UNLINK
1588 aio_rmdir = REQ_RMDIR 1634 aio_rmdir = REQ_RMDIR
1589 aio_readdir = REQ_READDIR 1635 aio_readdir = REQ_READDIR
1590 PPCODE: 1636 PPCODE:
1597 1643
1598 REQ_SEND; 1644 REQ_SEND;
1599} 1645}
1600 1646
1601void 1647void
1602aio_mkdir (pathname,mode,callback=&PL_sv_undef) 1648aio_mkdir (SV8 *pathname, int mode, SV *callback=&PL_sv_undef)
1603 SV8 * pathname
1604 UV mode
1605 SV * callback
1606 PPCODE: 1649 PPCODE:
1607{ 1650{
1608 dREQ; 1651 dREQ;
1609 1652
1610 req->type = REQ_MKDIR; 1653 req->type = REQ_MKDIR;
1614 1657
1615 REQ_SEND; 1658 REQ_SEND;
1616} 1659}
1617 1660
1618void 1661void
1619aio_link (oldpath,newpath,callback=&PL_sv_undef) 1662aio_link (SV8 *oldpath, SV8 *newpath, SV *callback=&PL_sv_undef)
1620 SV8 * oldpath
1621 SV8 * newpath
1622 SV * callback
1623 ALIAS: 1663 ALIAS:
1624 aio_link = REQ_LINK 1664 aio_link = REQ_LINK
1625 aio_symlink = REQ_SYMLINK 1665 aio_symlink = REQ_SYMLINK
1626 aio_rename = REQ_RENAME 1666 aio_rename = REQ_RENAME
1627 PPCODE: 1667 PPCODE:
1628{ 1668{
1629 dREQ; 1669 dREQ;
1630 1670
1631 req->type = ix; 1671 req->type = ix;
1632 req->fh = newSVsv (oldpath); 1672 req->sv2 = newSVsv (oldpath);
1633 req->ptr2 = SvPVbyte_nolen (req->fh); 1673 req->ptr2 = SvPVbyte_nolen (req->sv2);
1634 req->sv1 = newSVsv (newpath); 1674 req->sv1 = newSVsv (newpath);
1635 req->ptr1 = SvPVbyte_nolen (req->sv1); 1675 req->ptr1 = SvPVbyte_nolen (req->sv1);
1636 1676
1637 REQ_SEND; 1677 REQ_SEND;
1638} 1678}
1639 1679
1640void 1680void
1641aio_mknod (pathname,mode,dev,callback=&PL_sv_undef) 1681aio_mknod (SV8 *pathname, int mode, UV dev, SV *callback=&PL_sv_undef)
1642 SV8 * pathname
1643 UV mode
1644 UV dev
1645 SV * callback
1646 PPCODE: 1682 PPCODE:
1647{ 1683{
1648 dREQ; 1684 dREQ;
1649 1685
1650 req->type = REQ_MKNOD; 1686 req->type = REQ_MKNOD;
1655 1691
1656 REQ_SEND; 1692 REQ_SEND;
1657} 1693}
1658 1694
1659void 1695void
1660aio_busy (delay,callback=&PL_sv_undef) 1696aio_busy (double delay, SV *callback=&PL_sv_undef)
1661 double delay
1662 SV * callback
1663 PPCODE: 1697 PPCODE:
1664{ 1698{
1665 dREQ; 1699 dREQ;
1666 1700
1667 req->type = REQ_BUSY; 1701 req->type = REQ_BUSY;
1668 req->int1 = delay < 0. ? 0 : delay; 1702 req->nv1 = delay < 0. ? 0. : delay;
1669 req->int2 = delay < 0. ? 0 : 1000. * (delay - req->int1);
1670 1703
1671 REQ_SEND; 1704 REQ_SEND;
1672} 1705}
1673 1706
1674void 1707void
1675aio_group (callback=&PL_sv_undef) 1708aio_group (SV *callback=&PL_sv_undef)
1676 SV * callback
1677 PROTOTYPE: ;$ 1709 PROTOTYPE: ;$
1678 PPCODE: 1710 PPCODE:
1679{ 1711{
1680 dREQ; 1712 dREQ;
1681 1713
1684 req_send (req); 1716 req_send (req);
1685 XPUSHs (req_sv (req, AIO_GRP_KLASS)); 1717 XPUSHs (req_sv (req, AIO_GRP_KLASS));
1686} 1718}
1687 1719
1688void 1720void
1689aio_nop (callback=&PL_sv_undef) 1721aio_nop (SV *callback=&PL_sv_undef)
1690 SV * callback
1691 PPCODE: 1722 PPCODE:
1692{ 1723{
1693 dREQ; 1724 dREQ;
1694 1725
1695 req->type = REQ_NOP; 1726 req->type = REQ_NOP;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines