zookeeper 1.0.3-java → 1.0.4-java

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
@@ -53,6 +53,13 @@ class CZookeeper
53
53
 
54
54
  @_session_timeout_msec = DEFAULT_SESSION_TIMEOUT_MSEC
55
55
 
56
+ if cid = opts[:client_id]
57
+ raise ArgumentError, "opts[:client_id] must be a CZookeeper::ClientId" unless cid.kind_of?(ClientId)
58
+ raise ArgumentError, "session_id must not be nil" if cid.session_id.nil?
59
+ end
60
+
61
+ @_client_id = opts[:client_id]
62
+
56
63
  @start_stop_mutex = Monitor.new
57
64
 
58
65
  # used to signal that we're running
data/ext/dbg.h CHANGED
@@ -45,7 +45,7 @@
45
45
  // like check_debug_goto, but the label is implicitly 'error'
46
46
  #define check_debug(A, M, ...) check_debug_goto(A, error, M, ##__VA_ARGS__)
47
47
 
48
- #define zkrb_debug(M, ...) if (ZKRBDebugging) fprintf(stderr, "DEBUG %p:%s:%d: " M "\n", pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__)
48
+ #define zkrb_debug(M, ...) if (ZKRBDebugging) fprintf(stderr, "DEBUG %p:%s:%d: " M "\n", (void *)pthread_self(), __FILE__, __LINE__, ##__VA_ARGS__)
49
49
  #define zkrb_debug_inst(O, M, ...) zkrb_debug("obj_id: %lx, " M, FIX2LONG(rb_obj_id(O)), ##__VA_ARGS__)
50
50
 
51
51
  // __dbg_h__
@@ -88,7 +88,8 @@ class ZookeeperBase
88
88
  update_pid! # from Forked
89
89
  end
90
90
  private :reopen_after_fork!
91
-
91
+
92
+
92
93
  def reopen(timeout = 10, watcher=nil)
93
94
  if watcher and (watcher != @default_watcher)
94
95
  raise "You cannot set the watcher to a different value this way anymore!"
@@ -97,11 +98,7 @@ class ZookeeperBase
97
98
  reopen_after_fork! if forked?
98
99
 
99
100
  @mutex.synchronize do
100
- if @czk
101
- @czk.close
102
- @czk = nil
103
- end
104
-
101
+ @czk.close if @czk
105
102
  @czk = CZookeeper.new(@host, @event_queue)
106
103
 
107
104
  # flushes all outstanding watcher reqs.
@@ -123,13 +120,14 @@ class ZookeeperBase
123
120
 
124
121
  @dispatcher = @czk = nil
125
122
 
123
+ update_pid!
126
124
  reopen_after_fork!
127
125
 
128
126
  # approximate the java behavior of raising java.lang.IllegalArgumentException if the host
129
127
  # argument ends with '/'
130
128
  raise ArgumentError, "Host argument #{host.inspect} may not end with /" if host.end_with?('/')
131
129
 
132
- @host = host
130
+ @host = host.dup
133
131
 
134
132
  @default_watcher = (watcher or get_default_global_watcher)
135
133
 
@@ -165,7 +163,7 @@ class ZookeeperBase
165
163
  shutdown_thread = Thread.new do
166
164
  @mutex.synchronize do
167
165
  stop_dispatch_thread!
168
- @czk.close
166
+ close!
169
167
  end
170
168
  end
171
169
 
data/ext/zookeeper_lib.c CHANGED
@@ -37,10 +37,34 @@ int ZKRBDebugging;
37
37
  // XXX(slyphon): need to check these for error, but what to do if they fail?
38
38
  pthread_mutex_t zkrb_q_mutex = PTHREAD_MUTEX_INITIALIZER;
39
39
 
40
- #define LOG_PTHREAD_ERR(A, M, ...) if (A) { log_err(M, ##__VA_ARGS__); errno=0; }
40
+ inline static int global_mutex_lock() {
41
+ int rv = pthread_mutex_lock(&zkrb_q_mutex);
42
+ if (rv != 0) log_err("global_mutex_lock error");
43
+ return rv;
44
+ }
41
45
 
42
- #define GLOBAL_MUTEX_LOCK(F) LOG_PTHREAD_ERR(pthread_mutex_lock(&zkrb_q_mutex), F)
43
- #define GLOBAL_MUTEX_UNLOCK(F) LOG_PTHREAD_ERR(pthread_mutex_unlock(&zkrb_q_mutex), F)
46
+ inline static int global_mutex_unlock() {
47
+ int rv = pthread_mutex_unlock(&zkrb_q_mutex);
48
+ if (rv != 0) log_err("global_mutex_unlock error");
49
+ return rv;
50
+ }
51
+
52
+ void atfork_prepare() {
53
+ global_mutex_lock();
54
+ }
55
+
56
+ void atfork_parent() {
57
+ global_mutex_unlock();
58
+ }
59
+
60
+ void atfork_child() {
61
+ global_mutex_unlock();
62
+ }
63
+
64
+ // set up handlers to make sure the thread being forked holds the lock at the
65
+ // time the process is copied, then immediately unlock the mutex in both parent
66
+ // and children
67
+ pthread_atfork(atfork_prepare, atfork_parent, atfork_child);
44
68
 
45
69
 
46
70
  void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
@@ -54,7 +78,7 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
54
78
  return;
55
79
  }
56
80
 
57
- pthread_mutex_lock(&q->mutex);
81
+ global_mutex_lock();
58
82
 
59
83
  q->tail->event = elt;
60
84
  q->tail->next = (zkrb_event_ll_t *) malloc(sizeof(zkrb_event_ll_t));
@@ -64,7 +88,7 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
64
88
 
65
89
  ssize_t ret = write(q->pipe_write, "0", 1); /* Wake up Ruby listener */
66
90
 
67
- pthread_mutex_unlock(&q->mutex);
91
+ global_mutex_unlock();
68
92
 
69
93
  if (ret < 0) {
70
94
  log_err("write to queue (%p) pipe failed!\n", q);
@@ -81,13 +105,13 @@ zkrb_event_t * zkrb_peek(zkrb_queue_t *q) {
81
105
 
82
106
  if (!q) return NULL;
83
107
 
84
- pthread_mutex_lock(&q->mutex);
108
+ global_mutex_lock();
85
109
 
86
110
  if (q != NULL && q->head != NULL && q->head->event != NULL) {
87
111
  event = q->head->event;
88
112
  }
89
113
 
90
- pthread_mutex_unlock(&q->mutex);
114
+ global_mutex_unlock();
91
115
 
92
116
  return event;
93
117
  }
@@ -99,7 +123,7 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
99
123
  zkrb_event_ll_t *old_root = NULL;
100
124
 
101
125
  if (need_lock)
102
- pthread_mutex_lock(&q->mutex);
126
+ global_mutex_lock();
103
127
 
104
128
  if (!ZKRB_QUEUE_EMPTY(q)) {
105
129
  old_root = q->head;
@@ -108,7 +132,7 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
108
132
  }
109
133
 
110
134
  if (need_lock)
111
- pthread_mutex_unlock(&q->mutex);
135
+ global_mutex_unlock();
112
136
 
113
137
  free(old_root);
114
138
  return rv;
@@ -117,12 +141,12 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
117
141
  void zkrb_signal(zkrb_queue_t *q) {
118
142
  if (!q) return;
119
143
 
120
- pthread_mutex_lock(&q->mutex);
144
+ global_mutex_lock();
121
145
 
122
146
  if (!write(q->pipe_write, "0", 1)) /* Wake up Ruby listener */
123
147
  log_err("zkrb_signal: write to pipe failed, could not wake");
124
148
 
125
- pthread_mutex_unlock(&q->mutex);
149
+ global_mutex_unlock();
126
150
  }
127
151
 
128
152
  zkrb_event_ll_t *zkrb_event_ll_t_alloc(void) {
@@ -147,8 +171,6 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
147
171
 
148
172
  rq->orig_pid = getpid();
149
173
 
150
- check(pthread_mutex_init(&rq->mutex, NULL) == 0, "pthread_mutex_init failed");
151
-
152
174
  rq->head = zkrb_event_ll_t_alloc();
153
175
  check_mem(rq->head);
154
176
 
@@ -175,8 +197,6 @@ void zkrb_queue_free(zkrb_queue_t *queue) {
175
197
  close(queue->pipe_read);
176
198
  close(queue->pipe_write);
177
199
 
178
- pthread_mutex_destroy(&queue->mutex);
179
-
180
200
  free(queue);
181
201
  }
182
202
 
data/ext/zookeeper_lib.h CHANGED
@@ -106,7 +106,6 @@ typedef struct {
106
106
  zkrb_event_ll_t *tail;
107
107
  int pipe_read;
108
108
  int pipe_write;
109
- pthread_mutex_t mutex;
110
109
  pid_t orig_pid;
111
110
  } zkrb_queue_t;
112
111
 
data/lib/zookeeper.rb CHANGED
@@ -5,12 +5,16 @@ require 'monitor'
5
5
  require 'forwardable'
6
6
  require 'logger'
7
7
 
8
- require 'backports'
9
-
10
8
  module Zookeeper
11
9
  # establishes the namespace
12
10
  end
13
11
 
12
+ require File.expand_path('../zookeeper/core_ext', __FILE__)
13
+
14
+ silence_warnings do
15
+ require 'backports'
16
+ end
17
+
14
18
  require_relative 'zookeeper/forked'
15
19
  require_relative 'zookeeper/latch'
16
20
  require_relative 'zookeeper/acls'
@@ -0,0 +1,30 @@
1
+ # @private
2
+ module ::Kernel
3
+ unless method_defined?(:silence_warnings)
4
+ def silence_warnings
5
+ with_warnings(nil) { yield }
6
+ end
7
+ end
8
+
9
+ unless method_defined?(:with_warnings)
10
+ def with_warnings(flag)
11
+ old_verbose, $VERBOSE = $VERBOSE, flag
12
+ yield
13
+ ensure
14
+ $VERBOSE = old_verbose
15
+ end
16
+ end
17
+ end
18
+
19
+ # @private
20
+ class ::Exception
21
+ unless method_defined?(:to_std_format)
22
+ def to_std_format
23
+ ary = ["#{self.class}: #{message}"]
24
+ ary.concat(backtrace || [])
25
+ ary.join("\n\t")
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -14,6 +14,6 @@ module Zookeeper
14
14
  def update_pid!
15
15
  self.original_pid = Process.pid
16
16
  end
17
- end
18
- end
17
+ end # Forked
18
+ end # Zookeeper
19
19
 
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.4'
3
3
  DRIVER_VERSION = '3.3.5'
4
4
  end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'fork hooks' do
4
+ def safe_kill_process(signal, pid)
5
+ Process.kill(signal, pid)
6
+ rescue Errno::ESRCH
7
+ nil
8
+ end
9
+
10
+ after do
11
+ Zookeeper::Forked.clear!
12
+
13
+ if @pid
14
+ safe_kill_process('KILL', @pid)
15
+ end
16
+ end
17
+
18
+ describe 'fork with a block' do
19
+ it %[should call the after_fork_in_child hooks in the child] do
20
+ child_hook_called = false
21
+
22
+ hook_order = []
23
+
24
+ Zookeeper.prepare_for_fork { hook_order << :prepare }
25
+ Zookeeper.after_fork_in_parent { hook_order << :parent }
26
+ Zookeeper.after_fork_in_child { hook_order << :child }
27
+
28
+ @pid = fork do
29
+ unless hook_order.first == :prepare
30
+ $stderr.puts "hook order wrong! #{hook_order.inspect}"
31
+ exit! 2
32
+ end
33
+
34
+ unless hook_order.last == :child
35
+ $stderr.puts "hook order wrong! #{hook_order.inspect}"
36
+ exit! 3
37
+ end
38
+
39
+ exit! 0
40
+ end
41
+
42
+ hook_order.first.should == :prepare
43
+ hook_order.last.should == :parent
44
+
45
+ _, st = Process.wait2(@pid)
46
+ st.exitstatus.should == 0
47
+
48
+ st.should be_exited
49
+ st.should be_success
50
+ end
51
+ end
52
+ end
53
+
@@ -27,14 +27,31 @@ unless defined?(::JRUBY_VERSION)
27
27
 
28
28
  after do
29
29
  if @pid and process_alive?(@pid)
30
- Process.kill('TERM', @pid)
31
- p Process.wait2(@pid)
30
+ begin
31
+ Process.kill('KILL', @pid)
32
+ p Process.wait2(@pid)
33
+ rescue Errno::ESRCH
34
+ end
32
35
  end
33
36
 
34
37
  @zk.close if @zk and !@zk.closed?
35
38
  with_open_zk(connection_string) { |z| rm_rf(z, path) }
36
39
  end
37
40
 
41
+ def wait_for_child_safely(pid, timeout=5)
42
+ time_to_stop = Time.now + timeout
43
+
44
+ until Time.now > time_to_stop
45
+ if a = Process.wait2(@pid, Process::WNOHANG)
46
+ return a.last
47
+ else
48
+ sleep(0.01)
49
+ end
50
+ end
51
+
52
+ nil
53
+ end
54
+
38
55
  it %[should do the right thing and not fail] do
39
56
  @zk.wait_until_connected
40
57
 
@@ -68,13 +85,21 @@ unless defined?(::JRUBY_VERSION)
68
85
  exit!(0)
69
86
  end
70
87
 
71
- logger.debug { "waiting on child #{@pid}" }
88
+ event_waiter_th = Thread.new do
89
+ @latch.await(10) unless @event
90
+ @event
91
+ end
72
92
 
73
- @latch.await until @event
93
+ logger.debug { "waiting on child #{@pid}" }
74
94
 
75
- _, status = Process.wait2(@pid)
95
+ status = wait_for_child_safely(@pid)
96
+ raise "Child process did not exit, likely hung" unless status
76
97
 
98
+ status.should_not be_signaled
77
99
  status.should be_success
100
+
101
+ event_waiter_th.join(5).should == event_waiter_th
102
+ @event.should_not be nil
78
103
  end
79
104
  end
80
105
  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: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 3
10
- version: 1.0.3
9
+ - 4
10
+ version: 1.0.4
11
11
  platform: java
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-09 00:00:00 Z
23
+ date: 2012-05-10 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: backports
@@ -122,6 +122,7 @@ files:
122
122
  - lib/zookeeper/common/queue_with_pipe.rb
123
123
  - lib/zookeeper/compatibility.rb
124
124
  - lib/zookeeper/constants.rb
125
+ - lib/zookeeper/core_ext.rb
125
126
  - lib/zookeeper/em_client.rb
126
127
  - lib/zookeeper/exceptions.rb
127
128
  - lib/zookeeper/forked.rb
@@ -136,6 +137,7 @@ files:
136
137
  - spec/compatibilty_spec.rb
137
138
  - spec/default_watcher_spec.rb
138
139
  - spec/em_spec.rb
140
+ - spec/fork_hook_specs.rb
139
141
  - spec/forked_connection_spec.rb
140
142
  - spec/latch_spec.rb
141
143
  - spec/log4j.properties
@@ -187,6 +189,7 @@ test_files:
187
189
  - spec/compatibilty_spec.rb
188
190
  - spec/default_watcher_spec.rb
189
191
  - spec/em_spec.rb
192
+ - spec/fork_hook_specs.rb
190
193
  - spec/forked_connection_spec.rb
191
194
  - spec/latch_spec.rb
192
195
  - spec/log4j.properties