grn_ctx *pull(void) { MRN_DBUG_ENTER_METHOD(); grn_ctx *ctx = NULL; { time_t now; time(&now); mrn::Lock lock(mutex_); if (pool_) { ctx = static_cast<grn_ctx *>(pool_->data); list_pop(pool_); if ((now - last_pull_time_) >= CLEAR_THREATHOLD_IN_SECONDS) { clear(); } } last_pull_time_ = now; } if (!ctx) { ctx = grn_ctx_open(0); } DBUG_RETURN(ctx); }
/* * call-seq: * Groonga::Context.new(options=nil) * * コンテキストを作成する。_options_に指定可能な値は以下の通 * り。 * * [+:encoding+] * エンコーディングを指定する。エンコーディングの指定方法 * はGroonga::Encodingを参照。 */ static VALUE rb_grn_context_initialize (int argc, VALUE *argv, VALUE self) { RbGrnContext *rb_grn_context; grn_ctx *context; int flags = 0; VALUE options, default_options; VALUE rb_encoding; rb_scan_args(argc, argv, "01", &options); default_options = rb_grn_context_s_get_default_options(rb_obj_class(self)); if (NIL_P(default_options)) default_options = rb_hash_new(); if (NIL_P(options)) options = rb_hash_new(); options = rb_funcall(default_options, rb_intern("merge"), 1, options); rb_grn_scan_options(options, "encoding", &rb_encoding, NULL); rb_grn_context = ALLOC(RbGrnContext); DATA_PTR(self) = rb_grn_context; rb_grn_context->self = self; context = rb_grn_context->context = grn_ctx_open(flags); rb_grn_context_check(context, self); GRN_CTX_USER_DATA(context)->ptr = rb_grn_context; if (!NIL_P(rb_encoding)) { grn_encoding encoding; encoding = RVAL2GRNENCODING(rb_encoding, NULL); GRN_CTX_SET_ENCODING(context, encoding); } debug("context new: %p\n", context); return Qnil; }
static int serve_threads(int nthreads, int port, const char *db_path, void *zmq_ctx, const char *send_endpoint, const char *recv_endpoint, const char *log_base_path) { int nfd; uint32_t i; thd_data thds[nthreads]; if ((nfd = bind_socket(port)) < 0) { print_error("cannot bind socket. please check port number with netstat."); return -1; } for (i = 0; i < nthreads; i++) { memset(&thds[i], 0, sizeof(thds[i])); if (!(thds[i].base = event_init())) { print_error("error in event_init() on thread %d.", i); } else { if (!(thds[i].httpd = evhttp_new(thds[i].base))) { print_error("error in evhttp_new() on thread %d.", i); } else { int r; if ((r = evhttp_accept_socket(thds[i].httpd, nfd))) { print_error("error in evhttp_accept_socket() on thread %d.", i); } else { if (send_endpoint) { if (!(thds[i].zmq_sock = zmq_socket(zmq_ctx, ZMQ_PUB))) { print_error("cannot create zmq_socket."); } else if (zmq_connect(thds[i].zmq_sock, send_endpoint)) { print_error("cannot connect zmq_socket."); zmq_close(thds[i].zmq_sock); thds[i].zmq_sock = NULL; } else { uint64_t hwm = 1; zmq_setsockopt(thds[i].zmq_sock, ZMQ_HWM, &hwm, sizeof(uint64_t)); } } else { thds[i].zmq_sock = NULL; } if (!(thds[i].ctx = grn_ctx_open(0))) { print_error("error in grn_ctx_open() on thread %d.", i); } else if (grn_ctx_use(thds[i].ctx, db)) { print_error("error in grn_db_open() on thread %d.", i); } else { GRN_TEXT_INIT(&(thds[i].cmd_buf), 0); thds[i].log_base_path = log_base_path; thds[i].thread_id = i; evhttp_set_gencb(thds[i].httpd, generic_handler, &thds[i]); evhttp_set_timeout(thds[i].httpd, 10); { struct timeval tv = {1, 0}; evtimer_set(&(thds[i].pulse), timeout_handler, &thds[i]); evtimer_add(&(thds[i].pulse), &tv); } if ((r = pthread_create(&(thds[i].thd), NULL, dispatch, thds[i].base))) { print_error("error in pthread_create() on thread %d.", i); } } } } } } /* recv thread from learner */ if (recv_endpoint) { recv_thd_data rthd; rthd.db_path = db_path; rthd.recv_endpoint = recv_endpoint; rthd.zmq_ctx = zmq_ctx; if (pthread_create(&(rthd.thd), NULL, recv_from_learner, &rthd)) { print_error("error in pthread_create() on thread %d.", i); } pthread_join(rthd.thd, NULL); } else { while (loop) { sleep(1000); } } /* join all httpd thread */ for (i = 0; i < nthreads; i++) { if (thds[i].thd) { pthread_join(thds[i].thd, NULL); } cleanup_httpd_thread(&(thds[i])); } return 0; }