eio 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +8 -0
  2. data/COPYING +502 -0
  3. data/LICENSE +16 -0
  4. data/README.rdoc +201 -0
  5. data/Rakefile +48 -0
  6. data/bench/eventmachine.rb +134 -0
  7. data/eio.gemspec +17 -0
  8. data/ext/eio/eio_ext.c +1447 -0
  9. data/ext/eio/extconf.rb +11 -0
  10. data/ext/libeio/CVS/Entries +13 -0
  11. data/ext/libeio/CVS/Repository +1 -0
  12. data/ext/libeio/CVS/Root +1 -0
  13. data/ext/libeio/Changes +40 -0
  14. data/ext/libeio/LICENSE +36 -0
  15. data/ext/libeio/Makefile +692 -0
  16. data/ext/libeio/Makefile.am +15 -0
  17. data/ext/libeio/Makefile.in +692 -0
  18. data/ext/libeio/aclocal.m4 +8937 -0
  19. data/ext/libeio/autogen.sh +3 -0
  20. data/ext/libeio/autom4te.cache/output.0 +13871 -0
  21. data/ext/libeio/autom4te.cache/output.1 +13867 -0
  22. data/ext/libeio/autom4te.cache/requests +275 -0
  23. data/ext/libeio/autom4te.cache/traces.0 +2384 -0
  24. data/ext/libeio/autom4te.cache/traces.1 +621 -0
  25. data/ext/libeio/config.guess +1501 -0
  26. data/ext/libeio/config.h +122 -0
  27. data/ext/libeio/config.h.in +121 -0
  28. data/ext/libeio/config.status +2035 -0
  29. data/ext/libeio/config.sub +1705 -0
  30. data/ext/libeio/configure +13867 -0
  31. data/ext/libeio/configure.ac +22 -0
  32. data/ext/libeio/demo.c +194 -0
  33. data/ext/libeio/eio.3 +3428 -0
  34. data/ext/libeio/eio.c +2075 -0
  35. data/ext/libeio/eio.h +336 -0
  36. data/ext/libeio/eio.pod +303 -0
  37. data/ext/libeio/install-sh +520 -0
  38. data/ext/libeio/libeio.m4 +156 -0
  39. data/ext/libeio/libtool +8890 -0
  40. data/ext/libeio/ltmain.sh +8406 -0
  41. data/ext/libeio/missing +376 -0
  42. data/ext/libeio/stamp-h1 +1 -0
  43. data/ext/libeio/xthread.h +168 -0
  44. data/lib/eio.rb +9 -0
  45. data/lib/eio/eventmachine.rb +24 -0
  46. data/lib/eio/middleware.rb +21 -0
  47. data/test/test_eio.rb +1161 -0
  48. data/test/test_eventmachine.rb +23 -0
  49. data/test/test_middleware.rb +20 -0
  50. metadata +148 -0
@@ -0,0 +1,336 @@
1
+ /*
2
+ * libeio API header
3
+ *
4
+ * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libeio@schmorp.de>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without modifica-
8
+ * tion, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Alternatively, the contents of this file may be used under the terms of
29
+ * the GNU General Public License ("GPL") version 2 or any later version,
30
+ * in which case the provisions of the GPL are applicable instead of
31
+ * the above. If you wish to allow the use of your version of this file
32
+ * only under the terms of the GPL and not to allow others to use your
33
+ * version of this file under the BSD license, indicate your decision
34
+ * by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL. If you do not delete the
36
+ * provisions above, a recipient may use your version of this file under
37
+ * either the BSD or the GPL.
38
+ */
39
+
40
+ #ifndef EIO_H_
41
+ #define EIO_H_
42
+
43
+ #ifdef __cplusplus
44
+ extern "C" {
45
+ #endif
46
+
47
+ #include <stddef.h>
48
+ #include <sys/types.h>
49
+
50
+ typedef struct eio_req eio_req;
51
+ typedef struct eio_dirent eio_dirent;
52
+
53
+ typedef int (*eio_cb)(eio_req *req);
54
+
55
+ #ifndef EIO_REQ_MEMBERS
56
+ # define EIO_REQ_MEMBERS
57
+ #endif
58
+
59
+ #ifndef EIO_STRUCT_STAT
60
+ # define EIO_STRUCT_STAT struct stat
61
+ #endif
62
+
63
+ #ifndef EIO_STRUCT_STATVFS
64
+ # define EIO_STRUCT_STATVFS struct statvfs
65
+ #endif
66
+
67
+ /* for readdir */
68
+
69
+ /* eio_readdir flags */
70
+ enum
71
+ {
72
+ EIO_READDIR_DENTS = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */
73
+ EIO_READDIR_DIRS_FIRST = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */
74
+ EIO_READDIR_STAT_ORDER = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */
75
+ EIO_READDIR_FOUND_UNKNOWN = 0x80, /* set by eio_readdir when *_ARRAY was set and any TYPE=UNKNOWN's were found */
76
+
77
+ EIO_READDIR_CUSTOM1 = 0x100, /* for use by apps */
78
+ EIO_READDIR_CUSTOM2 = 0x200 /* for use by apps */
79
+ };
80
+
81
+ /* using "typical" values in the hope that the compiler will do something sensible */
82
+ enum eio_dtype
83
+ {
84
+ EIO_DT_UNKNOWN = 0,
85
+ EIO_DT_FIFO = 1,
86
+ EIO_DT_CHR = 2,
87
+ EIO_DT_MPC = 3, /* multiplexed char device (v7+coherent) */
88
+ EIO_DT_DIR = 4,
89
+ EIO_DT_NAM = 5, /* xenix special named file */
90
+ EIO_DT_BLK = 6,
91
+ EIO_DT_MPB = 7, /* multiplexed block device (v7+coherent) */
92
+ EIO_DT_REG = 8,
93
+ EIO_DT_NWK = 9, /* HP-UX network special */
94
+ EIO_DT_CMP = 9, /* VxFS compressed */
95
+ EIO_DT_LNK = 10,
96
+ /* DT_SHAD = 11,*/
97
+ EIO_DT_SOCK = 12,
98
+ EIO_DT_DOOR = 13, /* solaris door */
99
+ EIO_DT_WHT = 14,
100
+ EIO_DT_MAX = 15 /* highest DT_VALUE ever, hopefully */
101
+ };
102
+
103
+ struct eio_dirent
104
+ {
105
+ int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
106
+ unsigned short namelen; /* size of filename without trailing 0 */
107
+ unsigned char type; /* one of EIO_DT_* */
108
+ signed char score; /* internal use */
109
+ ino_t inode; /* the inode number, if available, otherwise unspecified */
110
+ };
111
+
112
+ /* eio_msync flags */
113
+ enum
114
+ {
115
+ EIO_MS_ASYNC = 1,
116
+ EIO_MS_INVALIDATE = 2,
117
+ EIO_MS_SYNC = 4
118
+ };
119
+
120
+ /* eio_mtouch flags */
121
+
122
+ enum
123
+ {
124
+ EIO_MT_MODIFY = 1
125
+ };
126
+
127
+ /* eio_sync_file_range flags */
128
+
129
+ enum
130
+ {
131
+ EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
132
+ EIO_SYNC_FILE_RANGE_WRITE = 2,
133
+ EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
134
+ };
135
+
136
+ typedef double eio_tstamp; /* feel free to use double in your code directly */
137
+
138
+ /* the eio request structure */
139
+
140
+ enum
141
+ {
142
+ EIO_CUSTOM,
143
+ EIO_OPEN, EIO_CLOSE, EIO_DUP2,
144
+ EIO_READ, EIO_WRITE,
145
+ EIO_READAHEAD, EIO_SENDFILE,
146
+ EIO_STAT, EIO_LSTAT, EIO_FSTAT,
147
+ EIO_STATVFS, EIO_FSTATVFS,
148
+ EIO_TRUNCATE, EIO_FTRUNCATE,
149
+ EIO_UTIME, EIO_FUTIME,
150
+ EIO_CHMOD, EIO_FCHMOD,
151
+ EIO_CHOWN, EIO_FCHOWN,
152
+ EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC,
153
+ EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE,
154
+ EIO_MLOCK, EIO_MLOCKALL,
155
+ EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
156
+ EIO_MKNOD, EIO_READDIR,
157
+ EIO_LINK, EIO_SYMLINK, EIO_READLINK,
158
+ EIO_GROUP, EIO_NOP,
159
+ EIO_BUSY
160
+ };
161
+
162
+ /* mlockall constants */
163
+ enum
164
+ {
165
+ EIO_MCL_CURRENT = 1,
166
+ EIO_MCL_FUTURE = 2,
167
+ };
168
+
169
+ /* request priorities */
170
+
171
+ enum {
172
+ EIO_PRI_MIN = -4,
173
+ EIO_PRI_MAX = 4,
174
+ EIO_PRI_DEFAULT = 0,
175
+ };
176
+
177
+ /* eio request structure */
178
+ /* this structure is mostly read-only */
179
+ /* when initialising it, all members must be zero-initialised */
180
+ struct eio_req
181
+ {
182
+ eio_req volatile *next; /* private ETP */
183
+
184
+ ssize_t result; /* result of syscall, e.g. result = read (... */
185
+ off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset, mknod: dev_t */
186
+ size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range: length */
187
+ void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
188
+ void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
189
+ eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
190
+ eio_tstamp nv2; /* utime, futime: mtime */
191
+
192
+ int type; /* EIO_xxx constant ETP */
193
+ int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
194
+ long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */
195
+ long int3; /* chown, fchown: gid */
196
+ int errorno; /* errno value on syscall return */
197
+
198
+ unsigned char flags; /* private */
199
+ signed char pri; /* the priority */
200
+
201
+ void *data;
202
+ eio_cb finish;
203
+ void (*destroy)(eio_req *req); /* called when requets no longer needed */
204
+ void (*feed)(eio_req *req); /* only used for group requests */
205
+
206
+ EIO_REQ_MEMBERS
207
+
208
+ eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
209
+ };
210
+
211
+ /* _private_ request flags */
212
+ enum {
213
+ EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */
214
+ EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */
215
+ EIO_FLAG_PTR2_FREE = 0x04, /* need to free(ptr2) */
216
+ EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */
217
+ };
218
+
219
+ /* undocumented/unsupported/private helper */
220
+ /*void eio_page_align (void **addr, size_t *length);*/
221
+
222
+ /* returns < 0 on error, errno set
223
+ * need_poll, if non-zero, will be called when results are available
224
+ * and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself).
225
+ * done_poll is called when the need to poll is gone.
226
+ */
227
+ int eio_init (void (*want_poll)(void), void (*done_poll)(void));
228
+
229
+ /* must be called regularly to handle pending requests */
230
+ /* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
231
+ int eio_poll (void);
232
+
233
+ /* stop polling if poll took longer than duration seconds */
234
+ void eio_set_max_poll_time (eio_tstamp nseconds);
235
+ /* do not handle more then count requests in one call to eio_poll_cb */
236
+ void eio_set_max_poll_reqs (unsigned int nreqs);
237
+
238
+ /* set minimum required number
239
+ * maximum wanted number
240
+ * or maximum idle number of threads */
241
+ void eio_set_min_parallel (unsigned int nthreads);
242
+ void eio_set_max_parallel (unsigned int nthreads);
243
+ void eio_set_max_idle (unsigned int nthreads);
244
+ void eio_set_idle_timeout (unsigned int seconds);
245
+
246
+ unsigned int eio_nreqs (void); /* number of requests in-flight */
247
+ unsigned int eio_nready (void); /* number of not-yet handled requests */
248
+ unsigned int eio_npending (void); /* numbe rof finished but unhandled requests */
249
+ unsigned int eio_nthreads (void); /* number of worker threads in use currently */
250
+
251
+ /*****************************************************************************/
252
+ /* convinience wrappers */
253
+
254
+ #ifndef EIO_NO_WRAPPERS
255
+ eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */
256
+ eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ties a thread for this long, simulating busyness */
257
+ eio_req *eio_sync (int pri, eio_cb cb, void *data);
258
+ eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
259
+ eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
260
+ eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
261
+ eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
262
+ eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
263
+ eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
264
+ eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
265
+ eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
266
+ eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
267
+ eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
268
+ eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
269
+ eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
270
+ eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
271
+ eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
272
+ eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data);
273
+ eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data);
274
+ eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data);
275
+ eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data);
276
+ eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data);
277
+ eio_req *eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data);
278
+ eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
279
+ eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data);
280
+ eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data);
281
+ eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data);
282
+ eio_req *eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data);
283
+ eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
284
+ eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data);
285
+ eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data);
286
+ eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
287
+ eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
288
+ eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
289
+ eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
290
+ eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data);
291
+ eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
292
+ eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
293
+ eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
294
+ eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data);
295
+ #endif
296
+
297
+ /*****************************************************************************/
298
+ /* groups */
299
+
300
+ eio_req *eio_grp (eio_cb cb, void *data);
301
+ void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit);
302
+ void eio_grp_limit (eio_req *grp, int limit);
303
+ void eio_grp_add (eio_req *grp, eio_req *req);
304
+ void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the group */
305
+
306
+ /*****************************************************************************/
307
+ /* request api */
308
+
309
+ /* true if the request was cancelled, useful in the invoke callback */
310
+ #define EIO_CANCELLED(req) ((req)->flags & EIO_FLAG_CANCELLED)
311
+
312
+ #define EIO_RESULT(req) ((req)->result)
313
+ /* returns a pointer to the result buffer allocated by eio */
314
+ #define EIO_BUF(req) ((req)->ptr2)
315
+ #define EIO_STAT_BUF(req) ((EIO_STRUCT_STAT *)EIO_BUF(req))
316
+ #define EIO_STATVFS_BUF(req) ((EIO_STRUCT_STATVFS *)EIO_BUF(req))
317
+ #define EIO_PATH(req) ((char *)(req)->ptr1)
318
+
319
+ /* submit a request for execution */
320
+ void eio_submit (eio_req *req);
321
+ /* cancel a request as soon fast as possible, if possible */
322
+ void eio_cancel (eio_req *req);
323
+ /* destroy a request that has never been submitted */
324
+ void eio_destroy (eio_req *req);
325
+
326
+ /*****************************************************************************/
327
+ /* convinience functions */
328
+
329
+ ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count);
330
+
331
+ #ifdef __cplusplus
332
+ }
333
+ #endif
334
+
335
+ #endif
336
+
@@ -0,0 +1,303 @@
1
+ =head1 NAME
2
+
3
+ libeio - truly asynchronous POSIX I/O
4
+
5
+ =head1 SYNOPSIS
6
+
7
+ #include <eio.h>
8
+
9
+ =head1 DESCRIPTION
10
+
11
+ The newest version of this document is also available as an html-formatted
12
+ web page you might find easier to navigate when reading it for the first
13
+ time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>.
14
+
15
+ Note that this library is a by-product of the C<IO::AIO> perl
16
+ module, and many of the subtler points regarding requests lifetime
17
+ and so on are only documented in its documentation at the
18
+ moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>.
19
+
20
+ =head2 FEATURES
21
+
22
+ This library provides fully asynchronous versions of most POSIX functions
23
+ dealing with I/O. Unlike most asynchronous libraries, this not only
24
+ includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and
25
+ similar functions, as well as less rarely ones such as C<mknod>, C<futime>
26
+ or C<readlink>.
27
+
28
+ It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
29
+ FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
30
+ emulation elsewhere>).
31
+
32
+ The goal is to enable you to write fully non-blocking programs. For
33
+ example, in a game server, you would not want to freeze for a few seconds
34
+ just because the server is running a backup and you happen to call
35
+ C<readdir>.
36
+
37
+ =head2 TIME REPRESENTATION
38
+
39
+ Libeio represents time as a single floating point number, representing the
40
+ (fractional) number of seconds since the (POSIX) epoch (somewhere near
41
+ the beginning of 1970, details are complicated, don't ask). This type is
42
+ called C<eio_tstamp>, but it is guaranteed to be of type C<double> (or
43
+ better), so you can freely use C<double> yourself.
44
+
45
+ Unlike the name component C<stamp> might indicate, it is also used for
46
+ time differences throughout libeio.
47
+
48
+ =head2 FORK SUPPORT
49
+
50
+ Calling C<fork ()> is fully supported by this module. It is implemented in these steps:
51
+
52
+ 1. wait till all requests in "execute" state have been handled
53
+ (basically requests that are already handed over to the kernel).
54
+ 2. fork
55
+ 3. in the parent, continue business as usual, done
56
+ 4. in the child, destroy all ready and pending requests and free the
57
+ memory used by the worker threads. This gives you a fully empty
58
+ libeio queue.
59
+
60
+ =head1 INITIALISATION/INTEGRATION
61
+
62
+ Before you can call any eio functions you first have to initialise the
63
+ library. The library integrates into any event loop, but can also be used
64
+ without one, including in polling mode.
65
+
66
+ You have to provide the necessary glue yourself, however.
67
+
68
+ =over 4
69
+
70
+ =item int eio_init (void (*want_poll)(void), void (*done_poll)(void))
71
+
72
+ This function initialises the library. On success it returns C<0>, on
73
+ failure it returns C<-1> and sets C<errno> appropriately.
74
+
75
+ It accepts two function pointers specifying callbacks as argument, both of
76
+ which can be C<0>, in which case the callback isn't called.
77
+
78
+ =item want_poll callback
79
+
80
+ The C<want_poll> callback is invoked whenever libeio wants attention (i.e.
81
+ it wants to be polled by calling C<eio_poll>). It is "edge-triggered",
82
+ that is, it will only be called once when eio wants attention, until all
83
+ pending requests have been handled.
84
+
85
+ This callback is called while locks are being held, so I<you must
86
+ not call any libeio functions inside this callback>. That includes
87
+ C<eio_poll>. What you should do is notify some other thread, or wake up
88
+ your event loop, and then call C<eio_poll>.
89
+
90
+ =item done_poll callback
91
+
92
+ This callback is invoked when libeio detects that all pending requests
93
+ have been handled. It is "edge-triggered", that is, it will only be
94
+ called once after C<want_poll>. To put it differently, C<want_poll> and
95
+ C<done_poll> are invoked in pairs: after C<want_poll> you have to call
96
+ C<eio_poll ()> until either C<eio_poll> indicates that everything has been
97
+ handled or C<done_poll> has been called, which signals the same.
98
+
99
+ Note that C<eio_poll> might return after C<done_poll> and C<want_poll>
100
+ have been called again, so watch out for races in your code.
101
+
102
+ As with C<want_poll>, this callback is called while locks are being held,
103
+ so you I<must not call any libeio functions form within this callback>.
104
+
105
+ =item int eio_poll ()
106
+
107
+ This function has to be called whenever there are pending requests that
108
+ need finishing. You usually call this after C<want_poll> has indicated
109
+ that you should do so, but you can also call this function regularly to
110
+ poll for new results.
111
+
112
+ If any request invocation returns a non-zero value, then C<eio_poll ()>
113
+ immediately returns with that value as return value.
114
+
115
+ Otherwise, if all requests could be handled, it returns C<0>. If for some
116
+ reason not all requests have been handled, i.e. some are still pending, it
117
+ returns C<-1>.
118
+
119
+ =back
120
+
121
+ For libev, you would typically use an C<ev_async> watcher: the
122
+ C<want_poll> callback would invoke C<ev_async_send> to wake up the event
123
+ loop. Inside the callback set for the watcher, one would call C<eio_poll
124
+ ()> (followed by C<ev_async_send> again if C<eio_poll> indicates that not
125
+ all requests have been handled yet). The race is taken care of because
126
+ libev resets/rearms the async watcher before calling your callback,
127
+ and therefore, before calling C<eio_poll>. This might result in (some)
128
+ spurious wake-ups, but is generally harmless.
129
+
130
+ For most other event loops, you would typically use a pipe - the event
131
+ loop should be told to wait for read readiness on the read end. In
132
+ C<want_poll> you would write a single byte, in C<done_poll> you would try
133
+ to read that byte, and in the callback for the read end, you would call
134
+ C<eio_poll>. The race is avoided here because the event loop should invoke
135
+ your callback again and again until the byte has been read (as the pipe
136
+ read callback does not read it, only C<done_poll>).
137
+
138
+ =head2 CONFIGURATION
139
+
140
+ The functions in this section can sometimes be useful, but the default
141
+ configuration will do in most case, so you should skip this section on
142
+ first reading.
143
+
144
+ =over 4
145
+
146
+ =item eio_set_max_poll_time (eio_tstamp nseconds)
147
+
148
+ This causes C<eio_poll ()> to return after it has detected that it was
149
+ running for C<nsecond> seconds or longer (this number can be fractional).
150
+
151
+ This can be used to limit the amount of time spent handling eio requests,
152
+ for example, in interactive programs, you might want to limit this time to
153
+ C<0.01> seconds or so.
154
+
155
+ Note that:
156
+
157
+ a) libeio doesn't know how long your request callbacks take, so the time
158
+ spent in C<eio_poll> is up to one callback invocation longer then this
159
+ interval.
160
+
161
+ b) this is implemented by calling C<gettimeofday> after each request,
162
+ which can be costly.
163
+
164
+ c) at least one request will be handled.
165
+
166
+ =item eio_set_max_poll_reqs (unsigned int nreqs)
167
+
168
+ When C<nreqs> is non-zero, then C<eio_poll> will not handle more than
169
+ C<nreqs> requests per invocation. This is a less costly way to limit the
170
+ amount of work done by C<eio_poll> then setting a time limit.
171
+
172
+ If you know your callbacks are generally fast, you could use this to
173
+ encourage interactiveness in your programs by setting it to C<10>, C<100>
174
+ or even C<1000>.
175
+
176
+ =item eio_set_min_parallel (unsigned int nthreads)
177
+
178
+ Make sure libeio can handle at least this many requests in parallel. It
179
+ might be able handle more.
180
+
181
+ =item eio_set_max_parallel (unsigned int nthreads)
182
+
183
+ Set the maximum number of threads that libeio will spawn.
184
+
185
+ =item eio_set_max_idle (unsigned int nthreads)
186
+
187
+ Libeio uses threads internally to handle most requests, and will start and stop threads on demand.
188
+
189
+ This call can be used to limit the number of idle threads (threads without
190
+ work to do): libeio will keep some threads idle in preparation for more
191
+ requests, but never longer than C<nthreads> threads.
192
+
193
+ In addition to this, libeio will also stop threads when they are idle for
194
+ a few seconds, regardless of this setting.
195
+
196
+ =item unsigned int eio_nthreads ()
197
+
198
+ Return the number of worker threads currently running.
199
+
200
+ =item unsigned int eio_nreqs ()
201
+
202
+ Return the number of requests currently handled by libeio. This is the
203
+ total number of requests that have been submitted to libeio, but not yet
204
+ destroyed.
205
+
206
+ =item unsigned int eio_nready ()
207
+
208
+ Returns the number of ready requests, i.e. requests that have been
209
+ submitted but have not yet entered the execution phase.
210
+
211
+ =item unsigned int eio_npending ()
212
+
213
+ Returns the number of pending requests, i.e. requests that have been
214
+ executed and have results, but have not been finished yet by a call to
215
+ C<eio_poll>).
216
+
217
+ =back
218
+
219
+
220
+ =head1 ANATOMY OF AN EIO REQUEST
221
+
222
+ #TODO
223
+
224
+
225
+ =head1 HIGH LEVEL REQUEST API
226
+
227
+ #TODO
228
+
229
+ =back
230
+
231
+
232
+ =head1 LOW LEVEL REQUEST API
233
+
234
+ #TODO
235
+
236
+ =head1 EMBEDDING
237
+
238
+ Libeio can be embedded directly into programs. This functionality is not
239
+ documented and not (yet) officially supported.
240
+
241
+ Note that, when including C<libeio.m4>, you are responsible for defining
242
+ the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.).
243
+
244
+ If you need to know how, check the C<IO::AIO> perl module, which does
245
+ exactly that.
246
+
247
+
248
+ =head1 COMPILETIME CONFIGURATION
249
+
250
+ These symbols, if used, must be defined when compiling F<eio.c>.
251
+
252
+ =over 4
253
+
254
+ =item EIO_STACKSIZE
255
+
256
+ This symbol governs the stack size for each eio thread. Libeio itself
257
+ was written to use very little stackspace, but when using C<EIO_CUSTOM>
258
+ requests, you might want to increase this.
259
+
260
+ If this symbol is undefined (the default) then libeio will use its default
261
+ stack size (C<sizeof (long) * 4096> currently). If it is defined, but
262
+ C<0>, then the default operating system stack size will be used. In all
263
+ other cases, the value must be an expression that evaluates to the desired
264
+ stack size.
265
+
266
+ =back
267
+
268
+
269
+ =head1 PORTABILITY REQUIREMENTS
270
+
271
+ In addition to a working ISO-C implementation, libeio relies on a few
272
+ additional extensions:
273
+
274
+ =over 4
275
+
276
+ =item POSIX threads
277
+
278
+ To be portable, this module uses threads, specifically, the POSIX threads
279
+ library must be available (and working, which partially excludes many xBSD
280
+ systems, where C<fork ()> is buggy).
281
+
282
+ =item POSIX-compatible filesystem API
283
+
284
+ This is actually a harder portability requirement: The libeio API is quite
285
+ demanding regarding POSIX API calls (symlinks, user/group management
286
+ etc.).
287
+
288
+ =item C<double> must hold a time value in seconds with enough accuracy
289
+
290
+ The type C<double> is used to represent timestamps. It is required to
291
+ have at least 51 bits of mantissa (and 9 bits of exponent), which is good
292
+ enough for at least into the year 4000. This requirement is fulfilled by
293
+ implementations implementing IEEE 754 (basically all existing ones).
294
+
295
+ =back
296
+
297
+ If you know of other additional requirements drop me a note.
298
+
299
+
300
+ =head1 AUTHOR
301
+
302
+ Marc Lehmann <libeio@schmorp.de>.
303
+