Previous approach was to use polling with a period of 100 msec. The new approach is to associate a pipe with the queue that we use to send events from ZK to Ruby land. When the Ruby consumer runs out of events to process, it does rb_thread_select() on the pipe. Whenever the ZK side enqueues a new event, we write into the pipe.
* Previous coding depending on recursive mutexes; since we can't easily guarantee those and use the static PTHREAD_MUTEX_INITIALIZER, just avoid the need for recursive mutexes for now. * Add a missing pthread_mutex_unlock() to an error return path. * Fix harmless compiler warning.
ZK allows a path to be created that has no associated data. In the previous coding, doing a #get() on such a path would result in raising a Ruby exception: zoo_get() returns data_len == -1 for the path, which isn't a legal string length.
This patch fixes a per-connection memory leak: the previous coding allocated a zkrb_calling_context for each ZK handle but neglected to free it. This patch also raises a Ruby exception if any operations on performed on a closed ZK handle, until #reopen() is called. Such operations would just segfault anyway.