cool.io 1.2.0 → 1.2.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.
@@ -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