curb 0.7.14 → 0.7.15

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 (5) hide show
  1. data/ext/curb.h +3 -3
  2. data/ext/curb_multi.c +13 -17
  3. data/lib/curb.rb +39 -6
  4. data/lib/curl.rb +0 -1
  5. metadata +39 -25
data/ext/curb.h CHANGED
@@ -20,12 +20,12 @@
20
20
  #include "curb_macros.h"
21
21
 
22
22
  // These should be managed from the Rake 'release' task.
23
- #define CURB_VERSION "0.7.14"
24
- #define CURB_VER_NUM 712
23
+ #define CURB_VERSION "0.7.15"
24
+ #define CURB_VER_NUM 715
25
25
  #define CURB_VER_MAJ 0
26
26
  #define CURB_VER_MIN 7
27
27
  #define CURB_VER_MIC 1
28
- #define CURB_VER_PATCH 4
28
+ #define CURB_VER_PATCH 5
29
29
 
30
30
 
31
31
  // Maybe not yet defined in Ruby
@@ -482,29 +482,23 @@ VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
482
482
 
483
483
  if (timeout_milliseconds == 0) { /* no delay */
484
484
  rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
485
+ rb_curl_multi_read_info( self, rbcm->handle );
486
+ if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
485
487
  continue;
486
488
  }
487
- else if (timeout_milliseconds < 0) {
488
- timeout_milliseconds = cCurlMutiDefaulttimeout; /* libcurl doesn't know how long to wait, use a default timeout */
489
- }
490
489
 
491
- if (timeout_milliseconds > cCurlMutiDefaulttimeout) {
492
- timeout_milliseconds = cCurlMutiDefaulttimeout; /* buggy versions libcurl sometimes reports huge timeouts... let's cap it */
490
+ if (timeout_milliseconds < 0 || timeout_milliseconds > cCurlMutiDefaulttimeout) {
491
+ timeout_milliseconds = cCurlMutiDefaulttimeout; /* libcurl doesn't know how long to wait, use a default timeout */
492
+ /* or buggy versions libcurl sometimes reports huge timeouts... let's cap it */
493
493
  }
494
494
 
495
495
  tv.tv_sec = 0; /* never wait longer than 1 second */
496
496
  tv.tv_usec = (int)(timeout_milliseconds * 1000); /* XXX: int is the right type for OSX, what about linux? */
497
497
 
498
- if (timeout_milliseconds == 0) { /* no delay */
499
- rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
500
- continue;
501
- }
502
-
503
- if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
504
-
505
498
  FD_ZERO(&fdread);
506
499
  FD_ZERO(&fdwrite);
507
500
  FD_ZERO(&fdexcep);
501
+
508
502
  /* load the fd sets from the multi handle */
509
503
  mcode = curl_multi_fdset(rbcm->handle, &fdread, &fdwrite, &fdexcep, &maxfd);
510
504
  if (mcode != CURLM_OK) {
@@ -529,17 +523,19 @@ VALUE ruby_curl_multi_perform(int argc, VALUE *argv, VALUE self) {
529
523
  case -1:
530
524
  rb_raise(rb_eRuntimeError, "select(): %s", strerror(errno));
531
525
  break;
532
- case 0:
526
+ case 0: /* timeout */
527
+ default: /* action */
528
+ rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
533
529
  rb_curl_multi_read_info( self, rbcm->handle );
534
530
  if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
535
- default:
536
- rb_curl_multi_run( self, rbcm->handle, &(rbcm->running) );
537
531
  break;
538
532
  }
539
533
  }
540
- rb_curl_multi_read_info( self, rbcm->handle );
541
- if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
534
+
542
535
  } while( rbcm->running );
536
+
537
+ rb_curl_multi_read_info( self, rbcm->handle );
538
+ if (block != Qnil) { rb_funcall(block, rb_intern("call"), 1, self); }
543
539
 
544
540
  return Qtrue;
545
541
  }
@@ -77,7 +77,7 @@ module Curl
77
77
  urls.each do|url|
78
78
  url_confs << {:url => url, :method => :get}.merge(easy_options)
79
79
  end
80
- self.http(url_confs, multi_options) {|c,code,method| blk.call(c) }
80
+ self.http(url_confs, multi_options) {|c,code,method| blk.call(c) if blk }
81
81
  end
82
82
 
83
83
  # call-seq:
@@ -148,17 +148,25 @@ module Curl
148
148
  #
149
149
  def http(urls_with_config, multi_options={}, &blk)
150
150
  m = Curl::Multi.new
151
+
152
+ # maintain a sane number of easy handles
153
+ multi_options[:max_connects] = max_connects = multi_options.key?(:max_connects) ? multi_options[:max_connects] : 10
154
+
155
+ free_handles = [] # keep a list of free easy handles
156
+
151
157
  # configure the multi handle
152
158
  multi_options.each { |k,v| m.send("#{k}=", v) }
153
159
  callbacks = [:on_progress,:on_debug,:on_failure,:on_success,:on_body,:on_header]
154
160
 
155
- urls_with_config.each do|conf|
156
- c = conf.dup # avoid being destructive to input
161
+ add_free_handle = proc do|conf, easy|
162
+ c = conf.dup # avoid being destructive to input
157
163
  url = c.delete(:url)
158
164
  method = c.delete(:method)
159
165
  headers = c.delete(:headers)
160
166
 
161
- easy = Curl::Easy.new(url)
167
+ easy = Curl::Easy.new if easy.nil?
168
+
169
+ easy.url = url
162
170
 
163
171
  # assign callbacks
164
172
  callbacks.each do |cb|
@@ -191,10 +199,35 @@ module Curl
191
199
  #
192
200
  c.each { |k,v| easy.send("#{k}=",v) }
193
201
 
194
- easy.on_complete {|curl,code| blk.call(curl,code,method) } if blk
202
+ easy.on_complete {|curl,code|
203
+ free_handles << curl
204
+ blk.call(curl,code,method) if blk
205
+ }
195
206
  m.add(easy)
196
207
  end
197
- m.perform
208
+
209
+ max_connects.times do
210
+ conf = urls_with_config.pop
211
+ add_free_handle.call conf, nil
212
+ break if urls_with_config.empty?
213
+ end
214
+
215
+ consume_free_handles = proc do
216
+ # as we idle consume free handles
217
+ if urls_with_config.size > 0 && free_handles.size > 0
218
+ easy = free_handles.pop
219
+ conf = urls_with_config.pop
220
+ add_free_handle.call conf, easy
221
+ end
222
+ end
223
+
224
+ until urls_with_config.empty?
225
+ m.perform do
226
+ consume_free_handles.call
227
+ end
228
+ consume_free_handles.call
229
+ end
230
+ free_handles = nil
198
231
  end
199
232
 
200
233
  # call-seq:
@@ -1,2 +1 @@
1
1
  require 'curb'
2
-
metadata CHANGED
@@ -1,29 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: curb
3
- version: !ruby/object:Gem::Version
4
- version: 0.7.14
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 7
9
+ - 15
10
+ version: 0.7.15
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Ross Bamford
9
14
  - Todd A. Fisher
10
15
  autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
- date: 2011-03-17 00:00:00.000000000 -04:00
18
+
19
+ date: 2011-03-20 00:00:00 -04:00
14
20
  default_executable:
15
21
  dependencies: []
16
- description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings
17
- for the libcurl(3), a fully-featured client-side URL transfer library. cURL and
18
- libcurl live at http://curl.haxx.se/
22
+
23
+ description: Curb (probably CUrl-RuBy or something) provides Ruby-language bindings for the libcurl(3), a fully-featured client-side URL transfer library. cURL and libcurl live at http://curl.haxx.se/
19
24
  email: todd.fisher@gmail.com
20
25
  executables: []
21
- extensions:
26
+
27
+ extensions:
22
28
  - ext/extconf.rb
23
- extra_rdoc_files:
29
+ extra_rdoc_files:
24
30
  - LICENSE
25
31
  - README
26
- files:
32
+ files:
27
33
  - LICENSE
28
34
  - README
29
35
  - Rakefile
@@ -66,32 +72,40 @@ files:
66
72
  has_rdoc: true
67
73
  homepage: http://curb.rubyforge.org/
68
74
  licenses: []
75
+
69
76
  post_install_message:
70
- rdoc_options:
77
+ rdoc_options:
71
78
  - --main
72
79
  - README
73
- require_paths:
80
+ require_paths:
74
81
  - lib
75
82
  - ext
76
- required_ruby_version: !ruby/object:Gem::Requirement
83
+ required_ruby_version: !ruby/object:Gem::Requirement
77
84
  none: false
78
- requirements:
79
- - - ! '>='
80
- - !ruby/object:Gem::Version
81
- version: '0'
82
- required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
93
  none: false
84
- requirements:
85
- - - ! '>='
86
- - !ruby/object:Gem::Version
87
- version: '0'
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
88
101
  requirements: []
102
+
89
103
  rubyforge_project: curb
90
- rubygems_version: 1.6.2
104
+ rubygems_version: 1.4.1
91
105
  signing_key:
92
106
  specification_version: 3
93
107
  summary: Ruby libcurl bindings
94
- test_files:
108
+ test_files:
95
109
  - tests/alltests.rb
96
110
  - tests/bug_curb_easy_blocks_ruby_threads.rb
97
111
  - tests/bug_curb_easy_post_with_string_no_content_length_header.rb