cool.io 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +25 -0
  2. data/CHANGES +199 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +4 -0
  5. data/Rakefile +98 -0
  6. data/VERSION +1 -0
  7. data/examples/echo_client.rb +38 -0
  8. data/examples/echo_server.rb +27 -0
  9. data/examples/google.rb +9 -0
  10. data/examples/httpclient.rb +38 -0
  11. data/ext/cool.io/.gitignore +5 -0
  12. data/ext/cool.io/cool.io.h +58 -0
  13. data/ext/cool.io/cool.io_ext.c +25 -0
  14. data/ext/cool.io/ev_wrap.h +8 -0
  15. data/ext/cool.io/extconf.rb +69 -0
  16. data/ext/cool.io/iowatcher.c +189 -0
  17. data/ext/cool.io/libev.c +8 -0
  18. data/ext/cool.io/loop.c +303 -0
  19. data/ext/cool.io/stat_watcher.c +191 -0
  20. data/ext/cool.io/timer_watcher.c +219 -0
  21. data/ext/cool.io/utils.c +122 -0
  22. data/ext/cool.io/watcher.c +264 -0
  23. data/ext/cool.io/watcher.h +71 -0
  24. data/ext/http11_client/.gitignore +5 -0
  25. data/ext/http11_client/ext_help.h +14 -0
  26. data/ext/http11_client/extconf.rb +6 -0
  27. data/ext/http11_client/http11_client.c +300 -0
  28. data/ext/http11_client/http11_parser.c +403 -0
  29. data/ext/http11_client/http11_parser.h +48 -0
  30. data/ext/http11_client/http11_parser.rl +173 -0
  31. data/ext/libev/Changes +364 -0
  32. data/ext/libev/LICENSE +36 -0
  33. data/ext/libev/README +58 -0
  34. data/ext/libev/README.embed +3 -0
  35. data/ext/libev/ev.c +3867 -0
  36. data/ext/libev/ev.h +826 -0
  37. data/ext/libev/ev_epoll.c +234 -0
  38. data/ext/libev/ev_kqueue.c +198 -0
  39. data/ext/libev/ev_poll.c +148 -0
  40. data/ext/libev/ev_port.c +164 -0
  41. data/ext/libev/ev_select.c +307 -0
  42. data/ext/libev/ev_vars.h +197 -0
  43. data/ext/libev/ev_win32.c +153 -0
  44. data/ext/libev/ev_wrap.h +186 -0
  45. data/ext/libev/test_libev_win32.c +123 -0
  46. data/ext/libev/update_ev_wrap +19 -0
  47. data/lib/.gitignore +2 -0
  48. data/lib/cool.io.rb +30 -0
  49. data/lib/cool.io/async_watcher.rb +43 -0
  50. data/lib/cool.io/dns_resolver.rb +220 -0
  51. data/lib/cool.io/eventmachine.rb +234 -0
  52. data/lib/cool.io/http_client.rb +419 -0
  53. data/lib/cool.io/io.rb +174 -0
  54. data/lib/cool.io/iowatcher.rb +17 -0
  55. data/lib/cool.io/listener.rb +93 -0
  56. data/lib/cool.io/loop.rb +130 -0
  57. data/lib/cool.io/meta.rb +49 -0
  58. data/lib/cool.io/server.rb +74 -0
  59. data/lib/cool.io/socket.rb +224 -0
  60. data/lib/cool.io/timer_watcher.rb +17 -0
  61. data/lib/coolio.rb +2 -0
  62. data/lib/rev.rb +4 -0
  63. data/spec/async_watcher_spec.rb +57 -0
  64. data/spec/possible_tests/schedules_other_threads.rb +48 -0
  65. data/spec/possible_tests/test_on_resolve_failed.rb +9 -0
  66. data/spec/possible_tests/test_resolves.rb +27 -0
  67. data/spec/possible_tests/test_write_during_resolve.rb +27 -0
  68. data/spec/possible_tests/works_straight.rb +71 -0
  69. data/spec/spec_helper.rb +5 -0
  70. data/spec/timer_watcher_spec.rb +55 -0
  71. data/spec/unix_listener_spec.rb +25 -0
  72. data/spec/unix_server_spec.rb +25 -0
  73. metadata +184 -0
@@ -0,0 +1,164 @@
1
+ /*
2
+ * libev solaris event port backend
3
+ *
4
+ * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@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
+ #include <sys/types.h>
41
+ #include <sys/time.h>
42
+ #include <poll.h>
43
+ #include <port.h>
44
+ #include <string.h>
45
+ #include <errno.h>
46
+
47
+ void inline_speed
48
+ port_associate_and_check (EV_P_ int fd, int ev)
49
+ {
50
+ if (0 >
51
+ port_associate (
52
+ backend_fd, PORT_SOURCE_FD, fd,
53
+ (ev & EV_READ ? POLLIN : 0)
54
+ | (ev & EV_WRITE ? POLLOUT : 0),
55
+ 0
56
+ )
57
+ )
58
+ {
59
+ if (errno == EBADFD)
60
+ fd_kill (EV_A_ fd);
61
+ else
62
+ ev_syserr ("(libev) port_associate");
63
+ }
64
+ }
65
+
66
+ static void
67
+ port_modify (EV_P_ int fd, int oev, int nev)
68
+ {
69
+ /* we need to reassociate no matter what, as closes are
70
+ * once more silently being discarded.
71
+ */
72
+ if (!nev)
73
+ {
74
+ if (oev)
75
+ port_dissociate (backend_fd, PORT_SOURCE_FD, fd);
76
+ }
77
+ else
78
+ port_associate_and_check (EV_A_ fd, nev);
79
+ }
80
+
81
+ static void
82
+ port_poll (EV_P_ ev_tstamp timeout)
83
+ {
84
+ int res, i;
85
+ struct timespec ts;
86
+ uint_t nget = 1;
87
+
88
+ EV_RELEASE_CB;
89
+ EV_TS_SET (ts, timeout);
90
+ res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
91
+ EV_ACQUIRE_CB;
92
+
93
+ if (res == -1)
94
+ {
95
+ if (errno != EINTR && errno != ETIME)
96
+ ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
97
+
98
+ return;
99
+ }
100
+
101
+ for (i = 0; i < nget; ++i)
102
+ {
103
+ if (port_events [i].portev_source == PORT_SOURCE_FD)
104
+ {
105
+ int fd = port_events [i].portev_object;
106
+
107
+ fd_event (
108
+ EV_A_
109
+ fd,
110
+ (port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
111
+ | (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
112
+ );
113
+
114
+ fd_change (EV_A_ fd, EV__IOFDSET);
115
+ }
116
+ }
117
+
118
+ if (expect_false (nget == port_eventmax))
119
+ {
120
+ ev_free (port_events);
121
+ port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1);
122
+ port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
123
+ }
124
+ }
125
+
126
+ int inline_size
127
+ port_init (EV_P_ int flags)
128
+ {
129
+ /* Initialize the kernel queue */
130
+ if ((backend_fd = port_create ()) < 0)
131
+ return 0;
132
+
133
+ fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
134
+
135
+ backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
136
+ backend_modify = port_modify;
137
+ backend_poll = port_poll;
138
+
139
+ port_eventmax = 64; /* initial number of events receivable per poll */
140
+ port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
141
+
142
+ return EVBACKEND_PORT;
143
+ }
144
+
145
+ void inline_size
146
+ port_destroy (EV_P)
147
+ {
148
+ ev_free (port_events);
149
+ }
150
+
151
+ void inline_size
152
+ port_fork (EV_P)
153
+ {
154
+ close (backend_fd);
155
+
156
+ while ((backend_fd = port_create ()) < 0)
157
+ ev_syserr ("(libev) port");
158
+
159
+ fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
160
+
161
+ /* re-register interest in fds */
162
+ fd_rearm_all (EV_A);
163
+ }
164
+
@@ -0,0 +1,307 @@
1
+ /*
2
+ * libev select fd activity backend
3
+ *
4
+ * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@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 _WIN32
41
+ /* for unix systems */
42
+ # include <sys/select.h>
43
+ # include <inttypes.h>
44
+ #endif
45
+
46
+ #ifndef EV_SELECT_USE_FD_SET
47
+ # ifdef NFDBITS
48
+ # define EV_SELECT_USE_FD_SET 0
49
+ # else
50
+ # define EV_SELECT_USE_FD_SET 1
51
+ # endif
52
+ #endif
53
+
54
+ #if EV_SELECT_IS_WINSOCKET
55
+ # undef EV_SELECT_USE_FD_SET
56
+ # define EV_SELECT_USE_FD_SET 1
57
+ # undef NFDBITS
58
+ # define NFDBITS 0
59
+ #endif
60
+
61
+ #if !EV_SELECT_USE_FD_SET
62
+ # define NFDBYTES (NFDBITS / 8)
63
+ #endif
64
+
65
+ #include <string.h>
66
+
67
+ static void
68
+ select_modify (EV_P_ int fd, int oev, int nev)
69
+ {
70
+ if (oev == nev)
71
+ return;
72
+
73
+ {
74
+ #if EV_SELECT_USE_FD_SET
75
+
76
+ #if EV_SELECT_IS_WINSOCKET
77
+ SOCKET handle = anfds [fd].handle;
78
+ #else
79
+ int handle = fd;
80
+ #endif
81
+
82
+ assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
83
+
84
+ /* FD_SET is broken on windows (it adds the fd to a set twice or more,
85
+ * which eventually leads to overflows). Need to call it only on changes.
86
+ */
87
+ #if EV_SELECT_IS_WINSOCKET
88
+ if ((oev ^ nev) & EV_READ)
89
+ #endif
90
+ if (nev & EV_READ)
91
+ FD_SET (handle, (fd_set *)vec_ri);
92
+ else
93
+ FD_CLR (handle, (fd_set *)vec_ri);
94
+
95
+ #if EV_SELECT_IS_WINSOCKET
96
+ if ((oev ^ nev) & EV_WRITE)
97
+ #endif
98
+ if (nev & EV_WRITE)
99
+ FD_SET (handle, (fd_set *)vec_wi);
100
+ else
101
+ FD_CLR (handle, (fd_set *)vec_wi);
102
+
103
+ #else
104
+
105
+ int word = fd / NFDBITS;
106
+ fd_mask mask = 1UL << (fd % NFDBITS);
107
+
108
+ if (expect_false (vec_max <= word))
109
+ {
110
+ int new_max = word + 1;
111
+
112
+ vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
113
+ vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
114
+ vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
115
+ vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
116
+ #ifdef _WIN32
117
+ vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
118
+ #endif
119
+
120
+ for (; vec_max < new_max; ++vec_max)
121
+ ((fd_mask *)vec_ri) [vec_max] =
122
+ ((fd_mask *)vec_wi) [vec_max] = 0;
123
+ }
124
+
125
+ ((fd_mask *)vec_ri) [word] |= mask;
126
+ if (!(nev & EV_READ))
127
+ ((fd_mask *)vec_ri) [word] &= ~mask;
128
+
129
+ ((fd_mask *)vec_wi) [word] |= mask;
130
+ if (!(nev & EV_WRITE))
131
+ ((fd_mask *)vec_wi) [word] &= ~mask;
132
+ #endif
133
+ }
134
+ }
135
+
136
+ static void
137
+ select_poll (EV_P_ ev_tstamp timeout)
138
+ {
139
+ struct timeval tv;
140
+ int res;
141
+ int fd_setsize;
142
+
143
+ EV_RELEASE_CB;
144
+ EV_TV_SET (tv, timeout);
145
+
146
+ #if EV_SELECT_USE_FD_SET
147
+ fd_setsize = sizeof (fd_set);
148
+ #else
149
+ fd_setsize = vec_max * NFDBYTES;
150
+ #endif
151
+
152
+ memcpy (vec_ro, vec_ri, fd_setsize);
153
+ memcpy (vec_wo, vec_wi, fd_setsize);
154
+
155
+ #ifdef _WIN32
156
+ /* pass in the write set as except set.
157
+ * the idea behind this is to work around a windows bug that causes
158
+ * errors to be reported as an exception and not by setting
159
+ * the writable bit. this is so uncontrollably lame.
160
+ */
161
+ memcpy (vec_eo, vec_wi, fd_setsize);
162
+ res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
163
+ #elif EV_SELECT_USE_FD_SET
164
+ fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
165
+ res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
166
+ #else
167
+ res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
168
+ #endif
169
+ EV_ACQUIRE_CB;
170
+
171
+ if (expect_false (res < 0))
172
+ {
173
+ #if EV_SELECT_IS_WINSOCKET
174
+ errno = WSAGetLastError ();
175
+ #endif
176
+ #ifdef WSABASEERR
177
+ /* on windows, select returns incompatible error codes, fix this */
178
+ if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
179
+ if (errno == WSAENOTSOCK)
180
+ errno = EBADF;
181
+ else
182
+ errno -= WSABASEERR;
183
+ #endif
184
+
185
+ #ifdef _WIN32
186
+ /* select on windows erroneously returns EINVAL when no fd sets have been
187
+ * provided (this is documented). what microsoft doesn't tell you that this bug
188
+ * exists even when the fd sets _are_ provided, so we have to check for this bug
189
+ * here and emulate by sleeping manually.
190
+ * we also get EINVAL when the timeout is invalid, but we ignore this case here
191
+ * and assume that EINVAL always means: you have to wait manually.
192
+ */
193
+ if (errno == EINVAL)
194
+ {
195
+ ev_sleep (timeout);
196
+ return;
197
+ }
198
+ #endif
199
+
200
+ if (errno == EBADF)
201
+ fd_ebadf (EV_A);
202
+ else if (errno == ENOMEM && !syserr_cb)
203
+ fd_enomem (EV_A);
204
+ else if (errno != EINTR)
205
+ ev_syserr ("(libev) select");
206
+
207
+ return;
208
+ }
209
+
210
+ #if EV_SELECT_USE_FD_SET
211
+
212
+ {
213
+ int fd;
214
+
215
+ for (fd = 0; fd < anfdmax; ++fd)
216
+ if (anfds [fd].events)
217
+ {
218
+ int events = 0;
219
+ #if EV_SELECT_IS_WINSOCKET
220
+ SOCKET handle = anfds [fd].handle;
221
+ #else
222
+ int handle = fd;
223
+ #endif
224
+
225
+ if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
226
+ if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
227
+ #ifdef _WIN32
228
+ if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
229
+ #endif
230
+
231
+ if (expect_true (events))
232
+ fd_event (EV_A_ fd, events);
233
+ }
234
+ }
235
+
236
+ #else
237
+
238
+ {
239
+ int word, bit;
240
+ for (word = vec_max; word--; )
241
+ {
242
+ fd_mask word_r = ((fd_mask *)vec_ro) [word];
243
+ fd_mask word_w = ((fd_mask *)vec_wo) [word];
244
+ #ifdef _WIN32
245
+ word_w |= ((fd_mask *)vec_eo) [word];
246
+ #endif
247
+
248
+ if (word_r || word_w)
249
+ for (bit = NFDBITS; bit--; )
250
+ {
251
+ fd_mask mask = 1UL << bit;
252
+ int events = 0;
253
+
254
+ events |= word_r & mask ? EV_READ : 0;
255
+ events |= word_w & mask ? EV_WRITE : 0;
256
+
257
+ if (expect_true (events))
258
+ fd_event (EV_A_ word * NFDBITS + bit, events);
259
+ }
260
+ }
261
+ }
262
+
263
+ #endif
264
+ }
265
+
266
+ int inline_size
267
+ select_init (EV_P_ int flags)
268
+ {
269
+ backend_fudge = 0.; /* posix says this is zero */
270
+ backend_modify = select_modify;
271
+ backend_poll = select_poll;
272
+
273
+ #if EV_SELECT_USE_FD_SET
274
+ vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
275
+ vec_ro = ev_malloc (sizeof (fd_set));
276
+ vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
277
+ vec_wo = ev_malloc (sizeof (fd_set));
278
+ #ifdef _WIN32
279
+ vec_eo = ev_malloc (sizeof (fd_set));
280
+ #endif
281
+ #else
282
+ vec_max = 0;
283
+ vec_ri = 0;
284
+ vec_ro = 0;
285
+ vec_wi = 0;
286
+ vec_wo = 0;
287
+ #ifdef _WIN32
288
+ vec_eo = 0;
289
+ #endif
290
+ #endif
291
+
292
+ return EVBACKEND_SELECT;
293
+ }
294
+
295
+ void inline_size
296
+ select_destroy (EV_P)
297
+ {
298
+ ev_free (vec_ri);
299
+ ev_free (vec_ro);
300
+ ev_free (vec_wi);
301
+ ev_free (vec_wo);
302
+ #ifdef _WIN32
303
+ ev_free (vec_eo);
304
+ #endif
305
+ }
306
+
307
+