cool.io 1.0.0 → 1.9.0

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 (83) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yaml +54 -0
  3. data/.gitignore +30 -0
  4. data/.rspec +3 -0
  5. data/{CHANGES → CHANGES.md} +175 -79
  6. data/{README.markdown → README.md} +43 -49
  7. data/Rakefile +44 -69
  8. data/appveyor.yml +18 -0
  9. data/cool.io.gemspec +18 -131
  10. data/examples/callbacked_echo_server.rb +24 -0
  11. data/ext/cool.io/buffer.c +781 -0
  12. data/ext/cool.io/cool.io.h +13 -0
  13. data/ext/cool.io/cool.io_ext.c +1 -0
  14. data/ext/cool.io/ev_wrap.h +4 -2
  15. data/ext/cool.io/extconf.rb +27 -16
  16. data/ext/cool.io/iowatcher.c +17 -8
  17. data/ext/cool.io/loop.c +36 -84
  18. data/ext/cool.io/stat_watcher.c +103 -25
  19. data/ext/cool.io/timer_watcher.c +3 -3
  20. data/ext/cool.io/utils.c +5 -0
  21. data/ext/cool.io/watcher.h +1 -1
  22. data/ext/libev/Changes +152 -3
  23. data/ext/libev/LICENSE +2 -1
  24. data/ext/libev/README +8 -8
  25. data/ext/libev/ev.c +1719 -348
  26. data/ext/libev/ev.h +146 -118
  27. data/ext/libev/ev_epoll.c +71 -20
  28. data/ext/libev/ev_kqueue.c +36 -16
  29. data/ext/libev/ev_poll.c +14 -11
  30. data/ext/libev/ev_port.c +43 -18
  31. data/ext/libev/ev_select.c +82 -25
  32. data/ext/libev/ev_vars.h +28 -21
  33. data/ext/libev/ev_win32.c +19 -10
  34. data/ext/libev/ev_wrap.h +166 -152
  35. data/ext/libev/test_libev_win32.c +1 -1
  36. data/gems.rb +9 -0
  37. data/lib/cool.io/async_watcher.rb +1 -1
  38. data/lib/cool.io/custom_require.rb +9 -0
  39. data/lib/cool.io/dns_resolver.rb +30 -22
  40. data/lib/cool.io/dsl.rb +32 -28
  41. data/lib/cool.io/io.rb +55 -35
  42. data/lib/cool.io/iowatcher.rb +1 -1
  43. data/lib/cool.io/listener.rb +35 -17
  44. data/lib/cool.io/loop.rb +17 -25
  45. data/lib/cool.io/meta.rb +6 -5
  46. data/lib/cool.io/server.rb +5 -4
  47. data/lib/cool.io/socket.rb +41 -30
  48. data/lib/cool.io/timer_watcher.rb +1 -1
  49. data/lib/cool.io/version.rb +7 -0
  50. data/lib/cool.io.rb +11 -10
  51. data/lib/coolio.rb +1 -1
  52. data/libev_ruby_gil.diff +175 -0
  53. data/libev_win_select.diff +130 -0
  54. data/spec/async_watcher_spec.rb +5 -5
  55. data/spec/dns_spec.rb +27 -8
  56. data/spec/iobuffer_spec.rb +147 -0
  57. data/spec/spec_helper.rb +15 -1
  58. data/spec/stat_watcher_spec.rb +81 -0
  59. data/spec/tcp_server_spec.rb +225 -0
  60. data/spec/tcp_socket_spec.rb +185 -0
  61. data/spec/timer_watcher_spec.rb +23 -19
  62. data/spec/udp_socket_spec.rb +58 -0
  63. data/spec/unix_listener_spec.rb +8 -8
  64. data/spec/unix_server_spec.rb +10 -8
  65. metadata +109 -112
  66. data/VERSION +0 -1
  67. data/examples/httpclient.rb +0 -38
  68. data/ext/http11_client/.gitignore +0 -5
  69. data/ext/http11_client/LICENSE +0 -31
  70. data/ext/http11_client/ext_help.h +0 -14
  71. data/ext/http11_client/extconf.rb +0 -6
  72. data/ext/http11_client/http11_client.c +0 -300
  73. data/ext/http11_client/http11_parser.c +0 -403
  74. data/ext/http11_client/http11_parser.h +0 -48
  75. data/ext/http11_client/http11_parser.rl +0 -173
  76. data/lib/cool.io/eventmachine.rb +0 -234
  77. data/lib/cool.io/http_client.rb +0 -419
  78. data/lib/rev.rb +0 -4
  79. data/spec/possible_tests/schedules_other_threads.rb +0 -48
  80. data/spec/possible_tests/test_on_resolve_failed.rb +0 -9
  81. data/spec/possible_tests/test_resolves.rb +0 -27
  82. data/spec/possible_tests/test_write_during_resolve.rb +0 -27
  83. data/spec/possible_tests/works_straight.rb +0 -71
@@ -1,19 +1,19 @@
1
1
  /*
2
2
  * libev select fd activity backend
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
8
8
  * tion, are permitted provided that the following conditions are met:
9
- *
9
+ *
10
10
  * 1. Redistributions of source code must retain the above copyright notice,
11
11
  * this list of conditions and the following disclaimer.
12
- *
12
+ *
13
13
  * 2. Redistributions in binary form must reproduce the above copyright
14
14
  * notice, this list of conditions and the following disclaimer in the
15
15
  * documentation and/or other materials provided with the distribution.
16
- *
16
+ *
17
17
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
18
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
19
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -39,8 +39,11 @@
39
39
 
40
40
  #ifndef _WIN32
41
41
  /* for unix systems */
42
- # include <sys/select.h>
43
42
  # include <inttypes.h>
43
+ # ifndef __hpux
44
+ /* for REAL unix systems */
45
+ # include <sys/select.h>
46
+ # endif
44
47
  #endif
45
48
 
46
49
  #ifndef EV_SELECT_USE_FD_SET
@@ -64,6 +67,54 @@
64
67
 
65
68
  #include <string.h>
66
69
 
70
+ #ifdef _WIN32
71
+ /*
72
+ ########## COOLIO PATCHERY HO! ##########
73
+
74
+ Ruby undefs FD_* utilities for own implementation.
75
+ It converts fd argument into socket handle internally on Windows,
76
+ so libev should not use Ruby's FD_* utilities.
77
+
78
+ Following FD_* utilities come from MinGW.
79
+ RubyInstaller is built by MinGW so this should work.
80
+ */
81
+ int PASCAL __WSAFDIsSet(SOCKET,fd_set*);
82
+ #define EV_WIN_FD_CLR(fd,set) do { u_int __i;\
83
+ for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) {\
84
+ if (((fd_set *)(set))->fd_array[__i] == (fd)) {\
85
+ while (__i < ((fd_set *)(set))->fd_count-1) {\
86
+ ((fd_set*)(set))->fd_array[__i] = ((fd_set*)(set))->fd_array[__i+1];\
87
+ __i++;\
88
+ }\
89
+ ((fd_set*)(set))->fd_count--;\
90
+ break;\
91
+ }\
92
+ }\
93
+ } while (0)
94
+ #define EV_WIN_FD_SET(fd, set) do { u_int __i;\
95
+ for (__i = 0; __i < ((fd_set *)(set))->fd_count ; __i++) {\
96
+ if (((fd_set *)(set))->fd_array[__i] == (fd)) {\
97
+ break;\
98
+ }\
99
+ }\
100
+ if (__i == ((fd_set *)(set))->fd_count) {\
101
+ if (((fd_set *)(set))->fd_count < FD_SETSIZE) {\
102
+ ((fd_set *)(set))->fd_array[__i] = (fd);\
103
+ ((fd_set *)(set))->fd_count++;\
104
+ }\
105
+ }\
106
+ } while(0)
107
+ #define EV_WIN_FD_ZERO(set) (((fd_set *)(set))->fd_count=0)
108
+ #define EV_WIN_FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set *)(set))
109
+ #define EV_WIN_FD_COUNT(set) (((fd_set *)(set))->fd_count)
110
+ /* ######################################## */
111
+ #else
112
+ #define EV_WIN_FD_CLR FD_CLR
113
+ #define EV_WIN_FD_SET FD_SET
114
+ #define EV_WIN_FD_ZERO FD_ZERO
115
+ #define EV_WIN_FD_ISSET FD_ISSET
116
+ #endif
117
+
67
118
  static void
68
119
  select_modify (EV_P_ int fd, int oev, int nev)
69
120
  {
@@ -88,17 +139,17 @@ select_modify (EV_P_ int fd, int oev, int nev)
88
139
  if ((oev ^ nev) & EV_READ)
89
140
  #endif
90
141
  if (nev & EV_READ)
91
- FD_SET (handle, (fd_set *)vec_ri);
142
+ EV_WIN_FD_SET (handle, (fd_set *)vec_ri);
92
143
  else
93
- FD_CLR (handle, (fd_set *)vec_ri);
144
+ EV_WIN_FD_CLR (handle, (fd_set *)vec_ri);
94
145
 
95
146
  #if EV_SELECT_IS_WINSOCKET
96
147
  if ((oev ^ nev) & EV_WRITE)
97
148
  #endif
98
149
  if (nev & EV_WRITE)
99
- FD_SET (handle, (fd_set *)vec_wi);
150
+ EV_WIN_FD_SET (handle, (fd_set *)vec_wi);
100
151
  else
101
- FD_CLR (handle, (fd_set *)vec_wi);
152
+ EV_WIN_FD_CLR (handle, (fd_set *)vec_wi);
102
153
 
103
154
  #else
104
155
 
@@ -192,7 +243,12 @@ select_poll (EV_P_ ev_tstamp timeout)
192
243
  */
193
244
  if (errno == EINVAL)
194
245
  {
195
- ev_sleep (timeout);
246
+ if (timeout)
247
+ {
248
+ unsigned long ms = (unsigned long)(timeout * 1e3);
249
+ SleepEx (ms ? ms : 1, TRUE);
250
+ }
251
+
196
252
  return;
197
253
  }
198
254
  #endif
@@ -222,10 +278,10 @@ select_poll (EV_P_ ev_tstamp timeout)
222
278
  int handle = fd;
223
279
  #endif
224
280
 
225
- if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
226
- if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
281
+ if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
282
+ if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
227
283
  #ifdef _WIN32
228
- if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
284
+ if (EV_WIN_FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
229
285
  #endif
230
286
 
231
287
  if (expect_true (events))
@@ -263,27 +319,28 @@ select_poll (EV_P_ ev_tstamp timeout)
263
319
  #endif
264
320
  }
265
321
 
266
- int inline_size
322
+ inline_size
323
+ int
267
324
  select_init (EV_P_ int flags)
268
325
  {
269
- backend_fudge = 0.; /* posix says this is zero */
270
- backend_modify = select_modify;
271
- backend_poll = select_poll;
326
+ backend_mintime = 1e-6;
327
+ backend_modify = select_modify;
328
+ backend_poll = select_poll;
272
329
 
273
330
  #if EV_SELECT_USE_FD_SET
274
- vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
331
+ vec_ri = ev_malloc (sizeof (fd_set)); EV_WIN_FD_ZERO ((fd_set *)vec_ri);
275
332
  vec_ro = ev_malloc (sizeof (fd_set));
276
- vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
333
+ vec_wi = ev_malloc (sizeof (fd_set)); EV_WIN_FD_ZERO ((fd_set *)vec_wi);
277
334
  vec_wo = ev_malloc (sizeof (fd_set));
278
335
  #ifdef _WIN32
279
336
  vec_eo = ev_malloc (sizeof (fd_set));
280
337
  #endif
281
338
  #else
282
339
  vec_max = 0;
283
- vec_ri = 0;
284
- vec_ro = 0;
285
- vec_wi = 0;
286
- vec_wo = 0;
340
+ vec_ri = 0;
341
+ vec_ro = 0;
342
+ vec_wi = 0;
343
+ vec_wo = 0;
287
344
  #ifdef _WIN32
288
345
  vec_eo = 0;
289
346
  #endif
@@ -292,7 +349,8 @@ select_init (EV_P_ int flags)
292
349
  return EVBACKEND_SELECT;
293
350
  }
294
351
 
295
- void inline_size
352
+ inline_size
353
+ void
296
354
  select_destroy (EV_P)
297
355
  {
298
356
  ev_free (vec_ri);
@@ -304,4 +362,3 @@ select_destroy (EV_P)
304
362
  #endif
305
363
  }
306
364
 
307
-
data/ext/libev/ev_vars.h CHANGED
@@ -1,19 +1,19 @@
1
1
  /*
2
2
  * loop member variable declarations
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
8
8
  * tion, are permitted provided that the following conditions are met:
9
- *
9
+ *
10
10
  * 1. Redistributions of source code must retain the above copyright notice,
11
11
  * this list of conditions and the following disclaimer.
12
- *
12
+ *
13
13
  * 2. Redistributions in binary form must reproduce the above copyright
14
14
  * notice, this list of conditions and the following disclaimer in the
15
15
  * documentation and/or other materials provided with the distribution.
16
- *
16
+ *
17
17
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
18
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
19
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -43,6 +43,17 @@ VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
43
43
  VARx(ev_tstamp, mn_now) /* monotonic clock "now" */
44
44
  VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
45
45
 
46
+ /* for reverse feeding of events */
47
+ VARx(W *, rfeeds)
48
+ VARx(int, rfeedmax)
49
+ VARx(int, rfeedcnt)
50
+
51
+ VAR (pendings, ANPENDING *pendings [NUMPRI])
52
+ VAR (pendingmax, int pendingmax [NUMPRI])
53
+ VAR (pendingcnt, int pendingcnt [NUMPRI])
54
+ VARx(int, pendingpri) /* highest priority currently pending */
55
+ VARx(ev_prepare, pending_w) /* dummy pending watcher */
56
+
46
57
  VARx(ev_tstamp, io_blocktime)
47
58
  VARx(ev_tstamp, timeout_blocktime)
48
59
 
@@ -51,28 +62,17 @@ VARx(int, activecnt) /* total number of active events ("refcount") */
51
62
  VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */
52
63
 
53
64
  VARx(int, backend_fd)
54
- VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
65
+ VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */
55
66
  VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
56
67
  VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
57
68
 
58
69
  VARx(ANFD *, anfds)
59
70
  VARx(int, anfdmax)
60
71
 
61
- VAR (pendings, ANPENDING *pendings [NUMPRI])
62
- VAR (pendingmax, int pendingmax [NUMPRI])
63
- VAR (pendingcnt, int pendingcnt [NUMPRI])
64
- VARx(ev_prepare, pending_w) /* dummy pending watcher */
65
-
66
- /* for reverse feeding of events */
67
- VARx(W *, rfeeds)
68
- VARx(int, rfeedmax)
69
- VARx(int, rfeedcnt)
70
-
71
- #if EV_USE_EVENTFD || EV_GENWRAP
72
- VARx(int, evfd)
73
- #endif
74
72
  VAR (evpipe, int evpipe [2])
75
73
  VARx(ev_io, pipe_w)
74
+ VARx(EV_ATOMIC_T, pipe_write_wanted)
75
+ VARx(EV_ATOMIC_T, pipe_write_skipped)
76
76
 
77
77
  #if !defined(_WIN32) || EV_GENWRAP
78
78
  VARx(pid_t, curpid)
@@ -102,9 +102,13 @@ VARx(int, pollidxmax)
102
102
  #if EV_USE_EPOLL || EV_GENWRAP
103
103
  VARx(struct epoll_event *, epoll_events)
104
104
  VARx(int, epoll_eventmax)
105
+ VARx(int *, epoll_eperms)
106
+ VARx(int, epoll_epermcnt)
107
+ VARx(int, epoll_epermmax)
105
108
  #endif
106
109
 
107
110
  #if EV_USE_KQUEUE || EV_GENWRAP
111
+ VARx(pid_t, kqueue_fd_pid)
108
112
  VARx(struct kevent *, kqueue_changes)
109
113
  VARx(int, kqueue_changemax)
110
114
  VARx(int, kqueue_changecnt)
@@ -183,14 +187,17 @@ VARx(ev_io, sigfd_w)
183
187
  VARx(sigset_t, sigfd_set)
184
188
  #endif
185
189
 
190
+ VARx(unsigned int, origflags) /* original loop flags */
191
+
186
192
  #if EV_FEATURE_API || EV_GENWRAP
187
193
  VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
188
194
  VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
189
195
 
190
196
  VARx(void *, userdata)
191
- VAR (release_cb, void (*release_cb)(EV_P))
192
- VAR (acquire_cb, void (*acquire_cb)(EV_P))
193
- VAR (invoke_cb , void (*invoke_cb) (EV_P))
197
+ /* C++ doesn't support the ev_loop_callback typedef here. stinks. */
198
+ VAR (release_cb, void (*release_cb)(EV_P) EV_THROW)
199
+ VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_THROW)
200
+ VAR (invoke_cb , ev_loop_callback invoke_cb)
194
201
  #endif
195
202
 
196
203
  #undef VARx
data/ext/libev/ev_win32.c CHANGED
@@ -6,14 +6,14 @@
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
8
8
  * tion, are permitted provided that the following conditions are met:
9
- *
9
+ *
10
10
  * 1. Redistributions of source code must retain the above copyright notice,
11
11
  * this list of conditions and the following disclaimer.
12
- *
12
+ *
13
13
  * 2. Redistributions in binary form must reproduce the above copyright
14
14
  * notice, this list of conditions and the following disclaimer in the
15
15
  * documentation and/or other materials provided with the distribution.
16
- *
16
+ *
17
17
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
18
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
19
  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
@@ -39,14 +39,21 @@
39
39
 
40
40
  #ifdef _WIN32
41
41
 
42
- /* timeb.h is actually xsi legacy functionality */
43
- #include <sys/timeb.h>
44
-
45
42
  /* note: the comment below could not be substantiated, but what would I care */
46
43
  /* MSDN says this is required to handle SIGFPE */
47
44
  /* my wild guess would be that using something floating-pointy is required */
48
45
  /* for the crt to do something about it */
49
- volatile double SIGFPE_REQ = 0.0f;
46
+ volatile double SIGFPE_REQ = 0.0f;
47
+
48
+ static SOCKET
49
+ ev_tcp_socket (void)
50
+ {
51
+ #if EV_USE_WSASOCKET
52
+ return WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0);
53
+ #else
54
+ return socket (AF_INET, SOCK_STREAM, 0);
55
+ #endif
56
+ }
50
57
 
51
58
  /* oh, the humanity! */
52
59
  static int
@@ -59,7 +66,7 @@ ev_pipe (int filedes [2])
59
66
  SOCKET listener;
60
67
  SOCKET sock [2] = { -1, -1 };
61
68
 
62
- if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
69
+ if ((listener = ev_tcp_socket ()) == INVALID_SOCKET)
63
70
  return -1;
64
71
 
65
72
  addr.sin_family = AF_INET;
@@ -75,12 +82,14 @@ ev_pipe (int filedes [2])
75
82
  if (listen (listener, 1))
76
83
  goto fail;
77
84
 
78
- if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
85
+ if ((sock [0] = ev_tcp_socket ()) == INVALID_SOCKET)
79
86
  goto fail;
80
87
 
81
88
  if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
82
89
  goto fail;
83
90
 
91
+ /* TODO: returns INVALID_SOCKET on winsock accept, not < 0. fix it */
92
+ /* when convenient, probably by just removing error checking altogether? */
84
93
  if ((sock [1] = accept (listener, 0, 0)) < 0)
85
94
  goto fail;
86
95
 
@@ -133,7 +142,7 @@ fail:
133
142
 
134
143
  #undef pipe
135
144
  #define pipe(filedes) ev_pipe (filedes)
136
-
145
+
137
146
  #define EV_HAVE_EV_TIME 1
138
147
  ev_tstamp
139
148
  ev_time (void)