cool.io 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,11 @@
1
+ language: ruby
2
+
1
3
  rvm:
2
- - 1.8.7
3
- - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
4
7
  - rbx
8
+
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: rbx
data/CHANGES.md CHANGED
@@ -1,9 +1,16 @@
1
+ 1.2.1
2
+ -----
3
+
4
+ * Release the GIL when libev polls (#24)
5
+ * Add Listener#listen method to change backlog size
6
+
1
7
  1.2.0
2
8
  -----
3
9
 
4
10
  * Support Windows environment via cross compilation
5
11
  * Include iobuffer library
6
12
  * Update to libev 4.15
13
+ * Remove Ruby 1.8 support
7
14
 
8
15
  1.1.0
9
16
  -----
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in cool.io.gemspec
4
4
  gemspec
@@ -205,23 +205,12 @@ static VALUE Coolio_Loop_run_once(VALUE self)
205
205
  return nevents;
206
206
  }
207
207
 
208
- /* Ruby 1.9 supports blocking system calls through rb_thread_blocking_region() */
209
208
  #ifdef HAVE_RB_THREAD_BLOCKING_REGION
210
209
  #define HAVE_EV_LOOP_ONESHOT
211
- static VALUE Coolio_Loop_ev_loop_oneshot_blocking(void *ptr)
212
- {
213
- /* The libev loop has now escaped through the Global VM Lock unscathed! */
214
- struct Coolio_Loop *loop_data = (struct Coolio_Loop *)ptr;
215
-
216
- RUN_LOOP(loop_data, EVLOOP_ONESHOT);
217
-
218
- return Qnil;
219
- }
220
210
 
221
211
  static void Coolio_Loop_ev_loop_oneshot(struct Coolio_Loop *loop_data)
222
212
  {
223
- /* Use Ruby 1.9's rb_thread_blocking_region call to make a blocking system call */
224
- rb_thread_blocking_region(Coolio_Loop_ev_loop_oneshot_blocking, loop_data, RUBY_UBF_IO, 0);
213
+ RUN_LOOP(loop_data, EVLOOP_ONESHOT);
225
214
  }
226
215
  #endif
227
216
 
@@ -37,6 +37,10 @@
37
37
  * either the BSD or the GPL.
38
38
  */
39
39
 
40
+ /* ########## COOLIO PATCHERY HO! ########## */
41
+ #include "ruby.h"
42
+ /* ######################################## */
43
+
40
44
  /* this big block deduces configuration from config.h */
41
45
  #ifndef EV_STANDALONE
42
46
  # ifdef EV_CONFIG_H
@@ -3237,9 +3241,27 @@ time_update (EV_P_ ev_tstamp max_block)
3237
3241
  }
3238
3242
  }
3239
3243
 
3244
+ /* ########## COOLIO PATCHERY HO! ########## */
3245
+ #if defined(HAVE_RB_THREAD_BLOCKING_REGION)
3246
+ static
3247
+ VALUE ev_backend_poll(void **args)
3248
+ {
3249
+ struct ev_loop *loop = (struct ev_loop *)args[0];
3250
+ ev_tstamp waittime = *(ev_tstamp *)args[1];
3251
+ backend_poll (EV_A_ waittime);
3252
+ }
3253
+ #endif
3254
+ /* ######################################## */
3255
+
3240
3256
  int
3241
3257
  ev_run (EV_P_ int flags)
3242
3258
  {
3259
+ /* ########## COOLIO PATCHERY HO! ########## */
3260
+ #if defined(HAVE_RB_THREAD_BLOCKING_REGION)
3261
+ void *poll_args[2];
3262
+ #endif
3263
+ /* ######################################## */
3264
+
3243
3265
  #if EV_FEATURE_API
3244
3266
  ++loop_depth;
3245
3267
  #endif
@@ -3357,7 +3379,53 @@ ev_run (EV_P_ int flags)
3357
3379
  ++loop_count;
3358
3380
  #endif
3359
3381
  assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
3382
+
3383
+ /*
3384
+ ########################## COOLIO PATCHERY HO! ##########################
3385
+
3386
+ The original patch file is made by Tony Arcieri.
3387
+ https://github.com/celluloid/nio4r/blob/680143345726c5a64bb22376ca8fc3c6857019ae/ext/libev/ruby_gil.patch.
3388
+
3389
+ According to the grandwizards of Ruby, locking and unlocking of the global
3390
+ interpreter lock are apparently too powerful a concept for a mere mortal to
3391
+ wield (although redefining what + and - do to numbers is totally cool).
3392
+ And so it came to pass that the only acceptable way to release the global
3393
+ interpreter lock is through a convoluted callback system that thakes a
3394
+ function pointer. While the grandwizard of libev foresaw this sort of scenario,
3395
+ he too attempted to place an API with callbacks on it, one that runs before
3396
+ the system call, and one that runs immediately after.
3397
+
3398
+ And so it came to pass that trying to wrap everything up in callbacks created
3399
+ two incompatible APIs, Ruby's which releases the global interpreter lock and
3400
+ reacquires it when the callback returns, and libev's, which wants two
3401
+ callbacks, one which runs before the polling operation starts, and one which
3402
+ runs after it finishes.
3403
+
3404
+ These two systems are incompatible as they both want to use callbacks to
3405
+ solve the same problem, however libev wants to use before/after callbacks,
3406
+ and Ruby wants to use an "around" callback. This presents a significant
3407
+ problem as these two patterns of callbacks are diametrical opposites of each
3408
+ other and thus cannot be composed.
3409
+
3410
+ And thus we are left with no choice but to patch the internals of libev in
3411
+ order to release a mutex at just the precise moment.
3412
+
3413
+ Let this be a lesson to the all: CALLBACKS FUCKING BLOW
3414
+
3415
+ #######################################################################
3416
+ */
3417
+
3418
+ #if defined(HAVE_RB_THREAD_BLOCKING_REGION)
3419
+ poll_args[0] = (void *)loop;
3420
+ poll_args[1] = (void *)&waittime;
3421
+ rb_thread_blocking_region(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
3422
+ #else
3360
3423
  backend_poll (EV_A_ waittime);
3424
+ #endif
3425
+ /*
3426
+ ############################# END PATCHERY ############################
3427
+ */
3428
+
3361
3429
  assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
3362
3430
 
3363
3431
  pipe_write_wanted = 0; /* just an optimisation, no fence needed */
@@ -0,0 +1,97 @@
1
+ diff --git a/ext/libev/ev.c b/ext/libev/ev.c
2
+ index e5bd5ab..10f6ff2 100644
3
+ --- a/ext/libev/ev.c
4
+ +++ b/ext/libev/ev.c
5
+ @@ -37,6 +37,10 @@
6
+ * either the BSD or the GPL.
7
+ */
8
+
9
+ +/* ########## COOLIO PATCHERY HO! ########## */
10
+ +#include "ruby.h"
11
+ +/* ######################################## */
12
+ +
13
+ /* this big block deduces configuration from config.h */
14
+ #ifndef EV_STANDALONE
15
+ # ifdef EV_CONFIG_H
16
+ @@ -3237,9 +3241,27 @@ time_update (EV_P_ ev_tstamp max_block)
17
+ }
18
+ }
19
+
20
+ +/* ########## COOLIO PATCHERY HO! ########## */
21
+ +#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
22
+ +static
23
+ +VALUE ev_backend_poll(void **args)
24
+ +{
25
+ + struct ev_loop *loop = (struct ev_loop *)args[0];
26
+ + ev_tstamp waittime = *(ev_tstamp *)args[1];
27
+ + backend_poll (EV_A_ waittime);
28
+ +}
29
+ +#endif
30
+ +/* ######################################## */
31
+ +
32
+ int
33
+ ev_run (EV_P_ int flags)
34
+ {
35
+ +/* ########## COOLIO PATCHERY HO! ########## */
36
+ +#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
37
+ + void *poll_args[2];
38
+ +#endif
39
+ +/* ######################################## */
40
+ +
41
+ #if EV_FEATURE_API
42
+ ++loop_depth;
43
+ #endif
44
+ @@ -3357,7 +3379,53 @@ ev_run (EV_P_ int flags)
45
+ ++loop_count;
46
+ #endif
47
+ assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
48
+ +
49
+ +/*
50
+ +########################## COOLIO PATCHERY HO! ##########################
51
+ +
52
+ +The original patch file is made by Tony Arcieri.
53
+ +https://github.com/celluloid/nio4r/blob/680143345726c5a64bb22376ca8fc3c6857019ae/ext/libev/ruby_gil.patch.
54
+ +
55
+ +According to the grandwizards of Ruby, locking and unlocking of the global
56
+ +interpreter lock are apparently too powerful a concept for a mere mortal to
57
+ +wield (although redefining what + and - do to numbers is totally cool).
58
+ +And so it came to pass that the only acceptable way to release the global
59
+ +interpreter lock is through a convoluted callback system that thakes a
60
+ +function pointer. While the grandwizard of libev foresaw this sort of scenario,
61
+ +he too attempted to place an API with callbacks on it, one that runs before
62
+ +the system call, and one that runs immediately after.
63
+ +
64
+ +And so it came to pass that trying to wrap everything up in callbacks created
65
+ +two incompatible APIs, Ruby's which releases the global interpreter lock and
66
+ +reacquires it when the callback returns, and libev's, which wants two
67
+ +callbacks, one which runs before the polling operation starts, and one which
68
+ +runs after it finishes.
69
+ +
70
+ +These two systems are incompatible as they both want to use callbacks to
71
+ +solve the same problem, however libev wants to use before/after callbacks,
72
+ +and Ruby wants to use an "around" callback. This presents a significant
73
+ +problem as these two patterns of callbacks are diametrical opposites of each
74
+ +other and thus cannot be composed.
75
+ +
76
+ +And thus we are left with no choice but to patch the internals of libev in
77
+ +order to release a mutex at just the precise moment.
78
+ +
79
+ +Let this be a lesson to the all: CALLBACKS FUCKING BLOW
80
+ +
81
+ +#######################################################################
82
+ +*/
83
+ +
84
+ +#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
85
+ + poll_args[0] = (void *)loop;
86
+ + poll_args[1] = (void *)&waittime;
87
+ + rb_thread_blocking_region(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
88
+ +#else
89
+ backend_poll (EV_A_ waittime);
90
+ +#endif
91
+ +/*
92
+ +############################# END PATCHERY ############################
93
+ +*/
94
+ +
95
+ assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
96
+
97
+ pipe_write_wanted = 0; /* just an optimisation, no fence needed */
@@ -21,6 +21,10 @@ module Coolio
21
21
  @listen_socket.fileno
22
22
  end
23
23
 
24
+ def listen(backlog)
25
+ @listen_socket.listen(backlog)
26
+ end
27
+
24
28
  # Close the listener
25
29
  def close
26
30
  detach if attached?
@@ -53,9 +57,9 @@ module Coolio
53
57
  end
54
58
  end
55
59
 
56
- class TCPListener < Listener
57
- DEFAULT_BACKLOG = 1024
60
+ DEFAULT_BACKLOG = 1024
58
61
 
62
+ class TCPListener < Listener
59
63
  # Create a new Coolio::TCPListener on the specified address and port.
60
64
  # Accepts the following options:
61
65
  #
@@ -87,7 +91,9 @@ module Coolio
87
91
  # Optionally, it can also take anyn existing UNIXServer object
88
92
  # and create a Coolio::UNIXListener out of it.
89
93
  def initialize(*args)
90
- super(::UNIXServer === args.first ? args.first : ::UNIXServer.new(*args))
94
+ s = ::UNIXServer === args.first ? args.first : ::UNIXServer.new(*args)
95
+ s.instance_eval { listen(DEFAULT_BACKLOG) }
96
+ super(s)
91
97
  end
92
98
  end
93
99
  end
@@ -56,7 +56,7 @@ module Coolio
56
56
  raise ArgumentError, "port must be an integer" if nil == port
57
57
  ::TCPServer.new(host, port)
58
58
  end
59
- listen_socket.instance_eval { listen(1024) } # Change listen backlog to 1024
59
+ listen_socket.instance_eval { listen(DEFAULT_BACKLOG) } # Change listen backlog to 1024
60
60
  super(listen_socket, klass, *args, &block)
61
61
  end
62
62
  end
@@ -68,6 +68,7 @@ module Coolio
68
68
  class UNIXServer < Server
69
69
  def initialize(path, klass = UNIXSocket, *args, &block)
70
70
  s = ::UNIXServer === path ? path : ::UNIXServer.new(path)
71
+ s.instance_eval { listen(DEFAULT_BACKLOG) }
71
72
  super(s, klass, *args, &block)
72
73
  end
73
74
  end
@@ -1,5 +1,5 @@
1
1
  module Coolio
2
- VERSION = "1.2.0"
2
+ VERSION = "1.2.1"
3
3
 
4
4
  def self.version; VERSION; end
5
5
  end
@@ -11,13 +11,15 @@ describe Cool.io::UNIXServer, :env => :win do
11
11
 
12
12
  it "creates a new Cool.io::UNIXServer" do
13
13
  listener = Cool.io::UNIXListener.new(@tmp.path)
14
+ listener.listen(24)
14
15
  File.socket?(@tmp.path).should == true
15
16
  end
16
17
 
17
18
  it "builds off an existing ::UNIXServer" do
18
19
  unix_server = ::UNIXServer.new(@tmp.path)
19
20
  File.socket?(@tmp.path).should == true
20
- listener = Cool.io::UNIXServer.new(unix_server)
21
+ listener = Cool.io::UNIXServer.new(unix_server, Coolio::UNIXSocket)
22
+ listener.listen(24)
21
23
  File.socket?(@tmp.path).should == true
22
24
  listener.fileno.should == unix_server.fileno
23
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cool.io
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-05-27 00:00:00.000000000 Z
13
+ date: 2014-02-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake-compiler
@@ -124,6 +124,7 @@ files:
124
124
  - ext/libev/ev_vars.h
125
125
  - ext/libev/ev_win32.c
126
126
  - ext/libev/ev_wrap.h
127
+ - ext/libev/ruby_gil.patch
127
128
  - ext/libev/test_libev_win32.c
128
129
  - lib/.gitignore
129
130
  - lib/cool.io.rb
@@ -164,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
165
  version: '0'
165
166
  segments:
166
167
  - 0
167
- hash: 3111666693494633054
168
+ hash: 2606014626052723115
168
169
  required_rubygems_version: !ruby/object:Gem::Requirement
169
170
  none: false
170
171
  requirements:
@@ -173,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
174
  version: '0'
174
175
  segments:
175
176
  - 0
176
- hash: 3111666693494633054
177
+ hash: 2606014626052723115
177
178
  requirements: []
178
179
  rubyforge_project:
179
180
  rubygems_version: 1.8.23