curb 0.7.14 → 0.7.15

Sign up to get free protection for your applications and to get access to all the features.
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