static void Bucket_dtor(pycbc_Bucket *self) { if (self->flags & PYCBC_CONN_F_CLOSED) { lcb_destroy(self->instance); self->instance = NULL; } if (self->instance) { lcb_set_cookie(self->instance, NULL); pycbc_schedule_dtor_event(self); } Py_XDECREF(self->dtorcb); Py_XDECREF(self->dfl_fmt); Py_XDECREF(self->tc); Py_XDECREF(self->bucket); Py_XDECREF(self->conncb); Py_XDECREF(self->dur_testhook); Py_XDECREF(self->iopswrap); if (self->instance) { lcb_destroy(self->instance); } #ifdef WITH_THREAD if (self->lock) { PyThread_free_lock(self->lock); self->lock = NULL; } #endif Py_TYPE(self)->tp_free((PyObject*)self); }
static ngx_int_t ngx_lcb_init_process(ngx_cycle_t *cycle) { ngx_lcb_main_conf_t *cmcf; struct lcb_create_io_ops_st options; lcb_error_t err; ngx_int_t rc; ngx_uint_t i; ngx_lcb_connection_t *conn; ngx_lcb_loc_conf_t **ccfp; /* initialize libcouchbase IO plugin */ memset(&options, 0, sizeof(options)); options.version = 2; options.v.v2.create = ngx_lcb_create_io_opts; options.v.v2.cookie = &lcb_cookie; err = lcb_create_io_ops(&lcb_cookie.io, &options); if (err != LCB_SUCCESS) { ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "couchbase: failed to create IO object for libcouchbase: 0x%02xd \"%s\"", err, lcb_strerror(NULL, err)); return NGX_ERROR; } lcb_cookie.log = cycle->log; lcb_cookie.pool = cycle->pool; /* materialize upstream connections */ rc = ngx_array_init(&lcb_connections, cycle->pool, 4, sizeof(ngx_lcb_connection_t)); if (rc != NGX_OK) { return NGX_ERROR; } cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_couchbase_module); ccfp = cmcf->connection_confs.elts; for (i = 0; i < cmcf->connection_confs.nelts; i++) { struct lcb_create_st opts = ccfp[i]->options; conn = ngx_array_push(&lcb_connections); if (conn == NULL) { return NGX_ERROR; } conn->log = cycle->log; conn->name = ccfp[i]->name; rc = ngx_array_init(&conn->backlog, cycle->pool, 4, sizeof(ngx_http_request_t *)); if (rc != NGX_OK) { return NGX_ERROR; } opts.v.v0.io = lcb_cookie.io; err = lcb_create(&conn->lcb, &opts); if (err != LCB_SUCCESS) { ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "couchbase: failed to create libcouchbase instance: 0x%02xd \"%s\"", err, lcb_strerror(NULL, err)); return NGX_ERROR; } (void)lcb_set_error_callback(conn->lcb, ngx_lcb_error_callback); (void)lcb_set_timeout(conn->lcb, ccfp[i]->connect_timeout * 1000); /* in usec */ (void)lcb_set_get_callback(conn->lcb, ngx_lcb_get_callback); (void)lcb_set_store_callback(conn->lcb, ngx_lcb_store_callback); (void)lcb_set_remove_callback(conn->lcb, ngx_lcb_remove_callback); (void)lcb_set_configuration_callback(conn->lcb, ngx_lcb_configuration_callback); (void)lcb_set_cookie(conn->lcb, conn); ngx_log_debug7(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "couchbase(%p): configured connection \"%V\": connect_timeout:%Mms " "address:%s bucket:%s user:%s password:%s", conn->lcb, &conn->name, ccfp[i]->connect_timeout, opts.v.v0.host ? opts.v.v0.host : "(null)", opts.v.v0.bucket ? opts.v.v0.bucket : "(null)", opts.v.v0.user ? opts.v.v0.user : "******", opts.v.v0.passwd ? opts.v.v0.passwd : "(null)"); } return NGX_OK; }
static int Connection__init__(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; char *conncache = NULL; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *timeout = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; struct lcb_cached_config_st cached_config = { { 0 } }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("_errors", &self->errors, "O") \ X("_flags", &self->flags, "I") \ X("bucket", &create_opts.v.v1.bucket, "z") \ X("username", &create_opts.v.v1.user, "z") \ X("password", &create_opts.v.v1.passwd, "z") \ X("host", &create_opts.v.v1.host, "z") \ X("conncache", &conncache, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("timeout", &timeout, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } if (create_opts.v.v1.bucket) { self->bucket = pycbc_SimpleStringZ(create_opts.v.v1.bucket); } create_opts.version = 1; create_opts.v.v1.type = conntype; if (iops_O && iops_O != Py_None) { self->iops = pycbc_iops_new(self, iops_O); create_opts.v.v1.io = self->iops; self->unlock_gil = 0; } Py_INCREF(self->errors); if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(0); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Connection_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Connection_set_transcoder(self, tc, NULL) == -1) { return -1; } #ifdef WITH_THREAD if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #endif if (conncache) { if (conntype != LCB_TYPE_BUCKET) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Cannot use connection cache with " "management connection"); return -1; } cached_config.cachefile = conncache; memcpy(&cached_config.createopt, &create_opts, sizeof(create_opts)); err = lcb_create_compat(LCB_CACHED_CONFIG, &cached_config, &self->instance, NULL); } else { err = lcb_create(&self->instance, &create_opts); } if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); if (timeout && timeout != Py_None) { if (Connection_set_timeout(self, timeout, NULL) == -1) { return -1; } } PYCBC_CONN_THR_BEGIN(self); err = lcb_connect(self->instance); PYCBC_CONN_THR_END(self); if (err != LCB_SUCCESS) { PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't schedule connection. This might be a result of " "an invalid hostname."); return -1; } err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_WAIT(err); return -1; } return 0; }
static int Bucket__init__(pycbc_Bucket *self, PyObject *args, PyObject *kwargs) { int rv; int conntype = LCB_TYPE_BUCKET; lcb_error_t err; PyObject *unlock_gil_O = NULL; PyObject *iops_O = NULL; PyObject *dfl_fmt = NULL; PyObject *tc = NULL; struct lcb_create_st create_opts = { 0 }; /** * This xmacro enumerates the constructor keywords, targets, and types. * This was converted into an xmacro to ease the process of adding or * removing various parameters. */ #define XCTOR_ARGS(X) \ X("connection_string", &create_opts.v.v3.connstr, "z") \ X("connstr", &create_opts.v.v3.connstr, "z") \ X("username", &create_opts.v.v3.username, "z") \ X("password", &create_opts.v.v3.passwd, "z") \ X("quiet", &self->quiet, "I") \ X("unlock_gil", &unlock_gil_O, "O") \ X("transcoder", &tc, "O") \ X("default_format", &dfl_fmt, "O") \ X("lockmode", &self->lockmode, "i") \ X("_flags", &self->flags, "I") \ X("_conntype", &conntype, "i") \ X("_iops", &iops_O, "O") static char *kwlist[] = { #define X(s, target, type) s, XCTOR_ARGS(X) #undef X NULL }; #define X(s, target, type) type static char *argspec = "|" XCTOR_ARGS(X); #undef X if (self->init_called) { PyErr_SetString(PyExc_RuntimeError, "__init__ was already called"); return -1; } self->init_called = 1; self->flags = 0; self->unlock_gil = 1; self->lockmode = PYCBC_LOCKMODE_EXC; #define X(s, target, type) target, rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist, XCTOR_ARGS(X) NULL); #undef X if (!rv) { PYCBC_EXCTHROW_ARGS(); return -1; } if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) { self->unlock_gil = 0; } create_opts.version = 3; create_opts.v.v3.type = conntype; if (iops_O && iops_O != Py_None) { self->iopswrap = pycbc_iowrap_new(self, iops_O); create_opts.v.v3.io = pycbc_iowrap_getiops(self->iopswrap); self->unlock_gil = 0; } if (dfl_fmt == Py_None || dfl_fmt == NULL) { /** Set to 0 if None or NULL */ dfl_fmt = pycbc_IntFromL(PYCBC_FMT_JSON); } else { Py_INCREF(dfl_fmt); /* later decref */ } rv = Bucket_set_format(self, dfl_fmt, NULL); Py_XDECREF(dfl_fmt); if (rv == -1) { return rv; } /** Set the transcoder */ if (tc && Bucket_set_transcoder(self, tc, NULL) == -1) { return -1; } #if defined(WITH_THREAD) if (!self->unlock_gil) { self->lockmode = PYCBC_LOCKMODE_NONE; } if (self->lockmode != PYCBC_LOCKMODE_NONE) { self->lock = PyThread_allocate_lock(); } #else self->unlock_gil = 0; self->lockmode = PYCBC_LOCKMODE_NONE; #endif err = lcb_create(&self->instance, &create_opts); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create instance. Either bad " "credentials/hosts/bucket names were " "passed, or there was an internal error in creating the " "object"); return -1; } if (pycbc_log_handler) { err = lcb_cntl(self->instance, LCB_CNTL_SET, LCB_CNTL_LOGGER, &pycbc_lcb_logprocs); if (err != LCB_SUCCESS) { self->instance = NULL; PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create log handler"); return -1; } } pycbc_callbacks_init(self->instance); lcb_set_cookie(self->instance, self); { const char *bucketstr; err = lcb_cntl(self->instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bucketstr); if (err == LCB_SUCCESS && bucketstr != NULL) { self->bucket = pycbc_SimpleStringZ(bucketstr); } } return 0; }