zookeeper 1.1.1 → 1.1.2

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.
data/ext/c_zookeeper.rb CHANGED
@@ -156,7 +156,7 @@ class CZookeeper
156
156
 
157
157
  def state
158
158
  return ZOO_CLOSED_STATE if closed?
159
- zkrb_state
159
+ submit_and_block(:state)
160
160
  end
161
161
 
162
162
  # this implementation is gross, but i don't really see another way of doing it
@@ -176,13 +176,21 @@ class CZookeeper
176
176
  connected?
177
177
  end
178
178
 
179
-
180
179
  private
181
180
  # submits a job for processing
182
181
  # blocks the caller until result has returned
183
182
  def submit_and_block(meth, *args)
184
183
  cnt = Continuation.new(meth, *args)
185
- @reg.synchronized { |r| r.pending << cnt }
184
+ @reg.lock
185
+ begin
186
+ if meth == :state
187
+ @reg.pending.unshift(cnt)
188
+ else
189
+ @reg.pending << cnt
190
+ end
191
+ ensure
192
+ @reg.unlock rescue nil
193
+ end
186
194
  wake_event_loop!
187
195
  cnt.value
188
196
  end
@@ -232,10 +240,8 @@ class CZookeeper
232
240
 
233
241
  # this is the main loop
234
242
  until (@_shutting_down or @_closed or is_unrecoverable)
235
- submit_pending_calls if @reg.pending?
236
- # log_realtime("zkrb_iterate_event_loop") do
237
- zkrb_iterate_event_loop # XXX: check rc here
238
- # end
243
+ submit_pending_calls if @reg.anything_to_do?
244
+ zkrb_iterate_event_loop
239
245
  iterate_event_delivery
240
246
  end
241
247
 
@@ -260,31 +266,20 @@ class CZookeeper
260
266
  end
261
267
 
262
268
  def submit_pending_calls
263
- # this is ok, because the calling thread only ever *adds* to this hash,
264
- # and the keys are always unique
269
+ calls = @reg.next_batch()
265
270
 
266
- pending = nil
271
+ return if calls.empty?
267
272
 
268
- @reg.lock
269
- begin
270
- pending, @reg.pending = @reg.pending, []
271
- ensure
272
- @reg.unlock
273
- end
274
-
275
- return if pending.empty?
276
-
277
- logger.debug { "#{self.class}##{__method__} " }
278
-
279
- while cntn = pending.shift
280
- cntn.submit(self)
281
- @reg.in_flight[cntn.req_id] = cntn # in_flight is only ever touched by us
273
+ while cntn = calls.shift
274
+ cntn.submit(self) # this delivers state check results (and does other stuff)
275
+ if req_id = cntn.req_id # state checks will not have a req_id
276
+ @reg.in_flight[req_id] = cntn # in_flight is only ever touched by us
277
+ end
282
278
  end
283
279
  end
284
280
 
285
281
  def wake_event_loop!
286
- logger.debug { "#{self.class}##{__method__}" }
287
- @pipe_write && @pipe_write.write("\001")
282
+ @pipe_write && @pipe_write.write('1')
288
283
  end
289
284
 
290
285
  def iterate_event_delivery
data/ext/common.h CHANGED
@@ -1,7 +1,17 @@
1
1
  #ifndef ZKRB_COMMON_H
2
2
  #define ZKRB_COMMON_H
3
3
 
4
+ #include "ruby.h"
5
+
4
6
  //#define THREADED
5
7
  #undef THREADED // we are linking against the zookeeper_st lib, this is crucial
6
8
 
9
+ #ifndef RB_GC_GUARD_PTR
10
+ #define RB_GC_GUARD_PTR(V) (V);
11
+ #endif
12
+ #ifndef RB_GC_GUARD
13
+ #define RB_GC_GUARD(V) (V);
14
+ #endif
15
+
16
+
7
17
  #endif /* ZKRB_COMMON_H */
data/ext/zkrb.c CHANGED
@@ -56,6 +56,13 @@
56
56
  *
57
57
  * NOTE: This file depends on exception classes defined in lib/zookeeper/exceptions.rb
58
58
  *
59
+ * -------
60
+ *
61
+ * @rectalogic: any time you create a ruby value in C, and so there are no
62
+ * references to it in the VM except for your variable, and you then call into
63
+ * the VM (allowing a GC), and your reference is on the stack, then it needs to
64
+ * be volatile
65
+ *
59
66
  */
60
67
 
61
68
  #include "ruby.h"
@@ -269,7 +276,7 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
269
276
  zoo_set_debug_level(FIX2INT(log_level));
270
277
  }
271
278
 
272
- VALUE data;
279
+ volatile VALUE data;
273
280
  zkrb_instance_data_t *zk_local_ctx;
274
281
  data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx);
275
282
 
@@ -665,13 +672,12 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
665
672
  check_debug(!is_closed(self), "we're closed in the middle of method_zkrb_get_next_event, bailing");
666
673
 
667
674
  zkrb_event_t *event = zkrb_dequeue(zk->queue, 1);
668
-
669
- /* Wait for an event using rb_thread_select() on the queue's pipe */
675
+
670
676
  if (event == NULL) {
671
677
  if (NIL_P(blocking) || (blocking == Qfalse)) {
672
678
  goto error;
673
679
  }
674
- else {
680
+ else {
675
681
  // if we're shutting down, don't enter this section, we don't want to block
676
682
  check_debug(!is_shutting_down(self), "method_zkrb_get_next_event, we're shutting down, don't enter blocking section");
677
683
 
@@ -707,7 +713,7 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
707
713
  // the single threaded version of this call. will go away when we do direct
708
714
  // event delivery (soon)
709
715
  static VALUE method_zkrb_get_next_event_st(VALUE self) {
710
- VALUE rval = Qnil;
716
+ volatile VALUE rval = Qnil;
711
717
 
712
718
  if (is_closed(self)) {
713
719
  zkrb_debug("we are closed, not gonna try to get an event");
@@ -8,6 +8,10 @@ module Zookeeper
8
8
 
9
9
  # for keeping track of which continuations are pending, and which ones have
10
10
  # been submitted and are awaiting a repsonse
11
+ #
12
+ # `state_check` are high-priority checks that query the connection about
13
+ # its current state, they always run before other continuations
14
+ #
11
15
  class Registry < Struct.new(:pending, :in_flight)
12
16
  extend Forwardable
13
17
 
@@ -23,15 +27,26 @@ module Zookeeper
23
27
  begin
24
28
  yield self
25
29
  ensure
26
- @mutex.unlock
30
+ @mutex.unlock rescue nil
27
31
  end
28
32
  end
29
33
 
30
34
  # does not lock the mutex, returns true if there are pending jobs
31
- def pending?
32
- !self.pending.empty?
35
+ def anything_to_do?
36
+ !pending.empty?
33
37
  end
34
- end
38
+
39
+ # returns the pending continuations, resetting the list
40
+ # this method is synchronized
41
+ def next_batch()
42
+ @mutex.lock
43
+ begin
44
+ pending.slice!(0,pending.length)
45
+ ensure
46
+ @mutex.unlock rescue nil
47
+ end
48
+ end
49
+ end # Registry
35
50
 
36
51
  # *sigh* what is the index in the *args array of the 'callback' param
37
52
  CALLBACK_ARG_IDX = {
@@ -43,6 +58,7 @@ module Zookeeper
43
58
  :get_acl => 2,
44
59
  :set_acl => 3,
45
60
  :get_children => 2,
61
+ :state => 0,
46
62
  }
47
63
 
48
64
  # maps the method name to the async return hash keys it should use to
@@ -111,9 +127,10 @@ module Zookeeper
111
127
  def submit(czk)
112
128
  rc, *_ = czk.__send__(:"zkrb_#{@meth}", *async_args)
113
129
 
114
- if user_callback? or (rc != ZOK) # if this is an async call, or we failed to submit it
115
- @rval = [rc] # create the repsonse
116
- deliver! # wake the caller and we're out
130
+ # if this is an state call, async call, or we failed to submit it
131
+ if (@meth == :state) or user_callback? or (rc != ZOK)
132
+ @rval = [rc] # create the repsonse
133
+ deliver! # wake the caller and we're out
117
134
  end
118
135
  end
119
136
 
@@ -121,11 +138,16 @@ module Zookeeper
121
138
  @args.first
122
139
  end
123
140
 
141
+ def state_call?
142
+ @meth == :state
143
+ end
144
+
124
145
  protected
125
146
 
126
147
  # an args array with the only difference being that if there's a user
127
148
  # callback provided, we don't handle delivering the end result
128
149
  def async_args
150
+ return [] if @meth == :state # special-case :P
129
151
  ary = @args.dup
130
152
 
131
153
  logger.debug { "async_args, meth: #{meth} ary: #{ary.inspect}, #{callback_arg_idx}" }
@@ -147,7 +169,7 @@ module Zookeeper
147
169
  begin
148
170
  @cond.signal
149
171
  ensure
150
- @mutex.unlock
172
+ @mutex.unlock rescue nil
151
173
  end
152
174
  end
153
175
  end # Base
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.1.1'
2
+ VERSION = '1.1.2'
3
3
  DRIVER_VERSION = '3.3.5'
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zookeeper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 1
10
- version: 1.1.1
9
+ - 2
10
+ version: 1.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Phillip Pearson
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2012-05-15 00:00:00 Z
23
+ date: 2012-05-17 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: backports