|
|
1 | #define PERL_NO_GET_CONTEXT |
|
|
2 | |
1 | #include "EXTERN.h" |
3 | #include "EXTERN.h" |
2 | #include "perl.h" |
4 | #include "perl.h" |
3 | #include "XSUB.h" |
5 | #include "XSUB.h" |
4 | |
6 | |
5 | #include <sys/types.h> |
7 | #include <sys/types.h> |
… | |
… | |
10 | #include <sched.h> |
12 | #include <sched.h> |
11 | |
13 | |
12 | typedef void *InputStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
14 | typedef void *InputStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
13 | typedef void *OutputStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
15 | typedef void *OutputStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
14 | typedef void *InOutStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
16 | typedef void *InOutStream; /* hack, but 5.6.1 is simply toooo old ;) */ |
|
|
17 | |
|
|
18 | #ifndef __NR_pread64 |
|
|
19 | # define __NR_pread64 __NR_pread |
|
|
20 | #endif |
|
|
21 | #ifndef __NR_pwrite64 |
|
|
22 | # define __NR_pwrite64 __NR_pwrite |
|
|
23 | #endif |
15 | |
24 | |
16 | #define STACKSIZE 1024 /* yeah */ |
25 | #define STACKSIZE 1024 /* yeah */ |
17 | |
26 | |
18 | enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, REQ_READ, REQ_WRITE, REQ_STAT, REQ_LSTAT, REQ_FSTAT}; |
27 | enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, REQ_READ, REQ_WRITE, REQ_STAT, REQ_LSTAT, REQ_FSTAT}; |
19 | |
28 | |
… | |
… | |
77 | nreqs++; |
86 | nreqs++; |
78 | write (reqpipe[1], &req, sizeof (aio_req)); |
87 | write (reqpipe[1], &req, sizeof (aio_req)); |
79 | } |
88 | } |
80 | |
89 | |
81 | static void |
90 | static void |
|
|
91 | read_write (pTHX_ |
82 | read_write (pTHX_ int dowrite, int fd, off_t offset, size_t length, |
92 | int dowrite, int fd, off_t offset, size_t length, |
83 | SV *data, STRLEN dataoffset, SV*callback) |
93 | SV *data, STRLEN dataoffset, SV*callback) |
84 | { |
94 | { |
85 | aio_req req; |
95 | aio_req req; |
86 | STRLEN svlen; |
96 | STRLEN svlen; |
87 | char *svptr = SvPV (data, svlen); |
97 | char *svptr = SvPV (data, svlen); |
… | |
… | |
203 | { |
213 | { |
204 | aio_thread *thr = thr_arg; |
214 | aio_thread *thr = thr_arg; |
205 | aio_req req; |
215 | aio_req req; |
206 | int errno; |
216 | int errno; |
207 | |
217 | |
|
|
218 | /* this is very much x86 and kernel-specific :(:(:( */ |
208 | /* we rely on gcc's ability to create closures. */ |
219 | /* we rely on gcc's ability to create closures. */ |
209 | _syscall3(int,read,int,fd,char *,buf,size_t,count) |
220 | _syscall3(int,read,int,fd,char *,buf,size_t,count) |
210 | _syscall3(int,write,int,fd,char *,buf,size_t,count) |
221 | _syscall3(int,write,int,fd,char *,buf,size_t,count) |
211 | |
222 | |
212 | _syscall3(int,open,char *,pathname,int,flags,mode_t,mode) |
223 | _syscall3(int,open,char *,pathname,int,flags,mode_t,mode) |
213 | _syscall1(int,close,int,fd) |
224 | _syscall1(int,close,int,fd) |
214 | |
225 | |
215 | _syscall4(int,pread,int,fd,char *,buf,size_t,count,off_t,offset) |
226 | _syscall5(int,pread64,int,fd,char *,buf,size_t,count,unsigned int,offset_lo,unsigned int,offset_hi) |
216 | _syscall4(int,pwrite,int,fd,char *,buf,size_t,count,off_t,offset) |
227 | _syscall5(int,pwrite64,int,fd,char *,buf,size_t,count,unsigned int,offset_lo,unsigned int,offset_hi) |
217 | |
228 | |
218 | _syscall2(int,stat64, const char *, filename, struct stat64 *, buf) |
229 | _syscall2(int,stat64, const char *, filename, struct stat64 *, buf) |
219 | _syscall2(int,lstat64, const char *, filename, struct stat64 *, buf) |
230 | _syscall2(int,lstat64, const char *, filename, struct stat64 *, buf) |
220 | _syscall2(int,fstat64, int, fd, struct stat64 *, buf) |
231 | _syscall2(int,fstat64, int, fd, struct stat64 *, buf) |
221 | |
232 | |
… | |
… | |
226 | { |
237 | { |
227 | req->thread = thr; |
238 | req->thread = thr; |
228 | errno = 0; /* strictly unnecessary */ |
239 | errno = 0; /* strictly unnecessary */ |
229 | |
240 | |
230 | if (req->type == REQ_READ) |
241 | if (req->type == REQ_READ) |
231 | req->result = pread (req->fd, req->dataptr, req->length, req->offset); |
242 | req->result = pread64 (req->fd, req->dataptr, req->length, req->offset & 0xffffffff, req->offset >> 32); |
232 | else if (req->type == REQ_WRITE) |
243 | else if (req->type == REQ_WRITE) |
233 | req->result = pwrite (req->fd, req->dataptr, req->length, req->offset); |
244 | req->result = pwrite64(req->fd, req->dataptr, req->length, req->offset & 0xffffffff, req->offset >> 32); |
234 | else if (req->type == REQ_OPEN) |
245 | else if (req->type == REQ_OPEN) |
235 | req->result = open (req->dataptr, req->fd, req->mode); |
246 | req->result = open (req->dataptr, req->fd, req->mode); |
236 | else if (req->type == REQ_CLOSE) |
247 | else if (req->type == REQ_CLOSE) |
237 | req->result = close (req->fd); |
248 | req->result = close (req->fd); |
238 | else if (req->type == REQ_STAT) |
249 | else if (req->type == REQ_STAT) |
239 | req->result = stat64 (req->dataptr, req->statdata); |
250 | req->result = stat64 (req->dataptr, req->statdata); |
240 | else if (req->type == REQ_LSTAT) |
251 | else if (req->type == REQ_LSTAT) |
241 | req->result = lstat64 (req->dataptr, req->statdata); |
252 | req->result = lstat64 (req->dataptr, req->statdata); |
242 | else if (req->type == REQ_FSTAT) |
253 | else if (req->type == REQ_FSTAT) |
243 | req->result = fstat64 (req->fd, req->statdata); |
254 | req->result = fstat64 (req->fd, req->statdata); |
244 | else |
255 | else |
245 | { |
256 | { |
246 | write (respipe[1], (void *)&req, sizeof (req)); |
257 | write (respipe[1], (void *)&req, sizeof (req)); |
247 | break; |
258 | break; |
248 | } |
259 | } |
… | |
… | |
296 | fd_set rfd; |
307 | fd_set rfd; |
297 | FD_ZERO(&rfd); |
308 | FD_ZERO(&rfd); |
298 | FD_SET(respipe[0], &rfd); |
309 | FD_SET(respipe[0], &rfd); |
299 | |
310 | |
300 | select (respipe[0] + 1, &rfd, 0, 0, 0); |
311 | select (respipe[0] + 1, &rfd, 0, 0, 0); |
301 | poll_cb (); |
312 | poll_cb (aTHX); |
302 | } |
313 | } |
303 | |
314 | |
304 | void |
315 | void |
305 | aio_open(pathname,flags,mode,callback) |
316 | aio_open(pathname,flags,mode,callback) |
306 | SV * pathname |
317 | SV * pathname |