// the single threaded version of this call. will go away when we do direct // event delivery (soon) static VALUE method_zkrb_get_next_event_st(VALUE self) { volatile VALUE rval = Qnil; if (is_closed(self)) { zkrb_debug("we are closed, not gonna try to get an event"); return Qnil; } FETCH_DATA_PTR(self, zk); zkrb_event_t *event = zkrb_dequeue(zk->queue, 0); if (event != NULL) { rval = zkrb_event_to_ruby(event); zkrb_event_free(event); #if THREADED int fd = zk->queue->pipe_read; // we don't care in this case. this is just until i can remove the self // pipe from the queue char b[128]; while(read(fd, b, sizeof(b)) == sizeof(b)){} #endif } return rval; }
inline static void zkrb_debug_clientid_t(const clientid_t *cid) { int pass_len = sizeof(cid->passwd); int hex_len = 2 * pass_len + 1; char buf[hex_len]; hexbufify(buf, cid->passwd, pass_len); zkrb_debug("myid, client_id: %"PRId64", passwd: %*s", cid->client_id, hex_len, buf); }
static int destroy_zkrb_instance(struct zkrb_instance_data* ptr) { int rv = ZOK; if (ptr->zh) { const void *ctx = zoo_get_context(ptr->zh); /* Note that after zookeeper_close() returns, ZK handle is invalid */ zkrb_debug("obj_id: %lx, calling zookeeper_close", ptr->object_id); rv = zookeeper_close(ptr->zh); zkrb_debug("obj_id: %lx, zookeeper_close returned %d", ptr->object_id, rv); free((void *) ctx); } #warning [wickman] TODO: fire off warning if queue is not empty if (ptr->queue) { zkrb_debug("obj_id: %lx, freeing queue pointer: %p", ptr->object_id, ptr->queue); zkrb_queue_free(ptr->queue); } ptr->zh = NULL; ptr->queue = NULL; return rv; }
static int destroy_zkrb_instance(zkrb_instance_data_t* zk) { int rv = ZOK; zkrb_debug("destroy_zkrb_instance, zk_local_ctx: %p, zh: %p, queue: %p", zk, zk->zh, zk->queue); if (zk->zh) { const void *ctx = zoo_get_context(zk->zh); /* Note that after zookeeper_close() returns, ZK handle is invalid */ zkrb_debug("obj_id: %lx, calling zookeeper_close", zk->object_id); if (we_are_forked(zk)) { zkrb_debug("FORK DETECTED! orig_pid: %d, current pid: %d, " "using socket-closing hack before zookeeper_close", zk->orig_pid, getpid()); int fd = ((int *)zk->zh)[0]; // nasty, brutish, and wonderfully effective hack (see above) close(fd); } rv = zookeeper_close(zk->zh); zkrb_debug("obj_id: %lx, zookeeper_close returned %d, calling context: %p", zk->object_id, rv, ctx); zkrb_calling_context_free((zkrb_calling_context *) ctx); } zk->zh = NULL; if (zk->queue) { zkrb_debug("obj_id: %lx, freeing queue pointer: %p", zk->object_id, zk->queue); zkrb_queue_free(zk->queue); } zk->queue = NULL; return rv; }
static VALUE method_close_handle(VALUE self) { FETCH_DATA_PTR(self, zk); if (ZKRBDebugging) { zkrb_debug_inst(self, "CLOSING_ZK_INSTANCE"); print_zkrb_instance_data(zk); } // this is a value on the ruby side we can check to see if destroy_zkrb_instance // has been called rb_iv_set(self, "@_closed", Qtrue); /* Note that after zookeeper_close() returns, ZK handle is invalid */ int rc = destroy_zkrb_instance(zk); zkrb_debug("destroy_zkrb_instance returned: %d", rc); return INT2FIX(rc); }
static VALUE method_zkrb_iterate_event_loop(VALUE self) { FETCH_DATA_PTR(self, zk); fd_set rfds, wfds, efds; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); int fd=0, interest=0, events=0, rc=0, maxfd=0; struct timeval tv; zookeeper_interest(zk->zh, &fd, &interest, &tv); if (fd != -1) { if (interest & ZOOKEEPER_READ) { FD_SET(fd, &rfds); } else { FD_CLR(fd, &rfds); } if (interest & ZOOKEEPER_WRITE) { FD_SET(fd, &wfds); } else { FD_CLR(fd, &wfds); } } else { fd = 0; } // add our self-pipe to the read set, allow us to wake up in case our attention is needed int pipe_r_fd = get_self_pipe_read_fd(self); FD_SET(pipe_r_fd, &rfds); maxfd = (pipe_r_fd > fd) ? pipe_r_fd : fd; rc = rb_thread_select(maxfd+1, &rfds, &wfds, &efds, &tv); if (rc > 0) { if (FD_ISSET(fd, &rfds)) { events |= ZOOKEEPER_READ; } if (FD_ISSET(fd, &wfds)) { events |= ZOOKEEPER_WRITE; } // we got woken up by the self-pipe if (FD_ISSET(pipe_r_fd, &rfds)) { // one event has awoken us, so we clear one event from the pipe char b[1]; if (read(pipe_r_fd, b, 1) < 0) { rb_raise(rb_eRuntimeError, "read from pipe failed: %s", clean_errno()); } } rc = zookeeper_process(zk->zh, events); } else if (rc == 0) { zkrb_debug("timed out waiting for descriptor to be ready"); } else { log_err("select returned: %d", rc); } return INT2FIX(rc); }
static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) { VALUE hostPort=Qnil; VALUE options=Qnil; rb_scan_args(argc, argv, "11", &hostPort, &options); if (NIL_P(options)) { options = rb_hash_new(); } else { Check_Type(options, T_HASH); } Check_Type(hostPort, T_STRING); // Look up :zkc_log_level VALUE log_level = rb_hash_aref(options, ID2SYM(rb_intern("zkc_log_level"))); if (NIL_P(log_level)) { zoo_set_debug_level(0); // no log messages } else { Check_Type(log_level, T_FIXNUM); zoo_set_debug_level(FIX2INT(log_level)); } volatile VALUE data; zkrb_instance_data_t *zk_local_ctx; data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx); zk_local_ctx->queue = zkrb_queue_alloc(); if (zk_local_ctx->queue == NULL) rb_raise(rb_eRuntimeError, "could not allocate zkrb queue!"); zoo_deterministic_conn_order(0); zkrb_calling_context *ctx = zkrb_calling_context_alloc(ZKRB_GLOBAL_REQ, zk_local_ctx->queue); zk_local_ctx->object_id = FIX2LONG(rb_obj_id(self)); zk_local_ctx->zh = zookeeper_init( RSTRING_PTR(hostPort), // const char *host zkrb_state_callback, // watcher_fn session_timeout_msec(self), // recv_timeout &zk_local_ctx->myid, // cilentid_t ctx, // void *context 0); // flags zkrb_debug("method_zkrb_init, zk_local_ctx: %p, zh: %p, queue: %p, calling_ctx: %p", zk_local_ctx, zk_local_ctx->zh, zk_local_ctx->queue, ctx); if (!zk_local_ctx->zh) { rb_raise(rb_eRuntimeError, "error connecting to zookeeper: %d", errno); } zk_local_ctx->orig_pid = getpid(); rb_iv_set(self, "@_data", data); rb_funcall(self, rb_intern("zkc_set_running_and_notify!"), 0); return Qnil; }