eio 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+