/* * __conn_add_data_source -- * WT_CONNECTION->add_data_source method. */ static int __conn_add_data_source(WT_CONNECTION *wt_conn, const char *prefix, WT_DATA_SOURCE *dsrc, const char *config) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; WT_NAMED_DATA_SOURCE *ndsrc; ndsrc = NULL; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, add_data_source, config, cfg); WT_UNUSED(cfg); WT_ERR(__wt_calloc_def(session, 1, &ndsrc)); WT_ERR(__wt_strdup(session, prefix, &ndsrc->prefix)); ndsrc->dsrc = dsrc; /* Link onto the environment's list of data sources. */ __wt_spin_lock(session, &conn->api_lock); TAILQ_INSERT_TAIL(&conn->dsrcqh, ndsrc, q); __wt_spin_unlock(session, &conn->api_lock); if (0) { err: if (ndsrc != NULL) __wt_free(session, ndsrc->prefix); __wt_free(session, ndsrc); } API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_add_collator -- * WT_CONNECTION->add_collator method. */ static int __conn_add_collator(WT_CONNECTION *wt_conn, const char *name, WT_COLLATOR *collator, const char *config) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_NAMED_COLLATOR *ncoll; WT_SESSION_IMPL *session; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, add_collator, config, cfg); WT_UNUSED(cfg); WT_ERR(__wt_calloc_def(session, 1, &ncoll)); WT_ERR(__wt_strdup(session, name, &ncoll->name)); ncoll->collator = collator; __wt_spin_lock(session, &conn->api_lock); TAILQ_INSERT_TAIL(&conn->collqh, ncoll, q); __wt_spin_unlock(session, &conn->api_lock); ncoll = NULL; err: __wt_free(session, ncoll); API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_add_compressor -- * WT_CONNECTION->add_compressor method. */ static int __conn_add_compressor(WT_CONNECTION *wt_conn, const char *name, WT_COMPRESSOR *compressor, const char *config) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_NAMED_COMPRESSOR *ncomp; WT_SESSION_IMPL *session; WT_UNUSED(name); WT_UNUSED(compressor); ncomp = NULL; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, add_compressor, config, cfg); WT_UNUSED(cfg); WT_ERR(__wt_calloc_def(session, 1, &ncomp)); WT_ERR(__wt_strdup(session, name, &ncomp->name)); ncomp->compressor = compressor; __wt_spin_lock(session, &conn->api_lock); TAILQ_INSERT_TAIL(&conn->compqh, ncomp, q); ncomp = NULL; __wt_spin_unlock(session, &conn->api_lock); err: if (ncomp != NULL) { __wt_free(session, ncomp->name); __wt_free(session, ncomp); } API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_load_extension -- * WT_CONNECTION->load_extension method. */ static int __conn_load_extension( WT_CONNECTION *wt_conn, const char *path, const char *config) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_DLH *dlh; WT_SESSION_IMPL *session; int (*load)(WT_CONNECTION *, WT_CONFIG_ARG *); const char *init_name, *terminate_name; dlh = NULL; init_name = terminate_name = NULL; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, load_extension, config, cfg); WT_ERR(__wt_config_gets(session, cfg, "entry", &cval)); WT_ERR(__wt_strndup(session, cval.str, cval.len, &init_name)); /* * This assumes the underlying shared libraries are reference counted, * that is, that re-opening a shared library simply increments a ref * count, and closing it simply decrements the ref count, and the last * close discards the reference entirely -- in other words, we do not * check to see if we've already opened this shared library. * * Fill in the extension structure and call the load function. */ WT_ERR(__wt_dlopen(session, path, &dlh)); WT_ERR(__wt_dlsym(session, dlh, init_name, 1, &load)); WT_ERR(load(wt_conn, (WT_CONFIG_ARG *)cfg)); /* Remember the unload function for when we close. */ WT_ERR(__wt_config_gets(session, cfg, "terminate", &cval)); WT_ERR(__wt_strndup(session, cval.str, cval.len, &terminate_name)); WT_ERR(__wt_dlsym(session, dlh, terminate_name, 0, &dlh->terminate)); /* Link onto the environment's list of open libraries. */ __wt_spin_lock(session, &conn->api_lock); TAILQ_INSERT_TAIL(&conn->dlhqh, dlh, q); __wt_spin_unlock(session, &conn->api_lock); dlh = NULL; err: if (dlh != NULL) WT_TRET(__wt_dlclose(session, dlh)); __wt_free(session, init_name); __wt_free(session, terminate_name); API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_load_extension -- * WT_CONNECTION->load_extension method. */ static int __conn_load_extension( WT_CONNECTION *wt_conn, const char *path, const char *config) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_DLH *dlh; WT_SESSION_IMPL *session; int (*entry)(WT_SESSION *, WT_EXTENSION_API *, const char *); const char *entry_name; dlh = NULL; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, load_extension, config, cfg); entry_name = NULL; WT_ERR(__wt_config_gets(session, cfg, "entry", &cval)); WT_ERR(__wt_strndup(session, cval.str, cval.len, &entry_name)); /* * This assumes the underlying shared libraries are reference counted, * that is, that re-opening a shared library simply increments a ref * count, and closing it simply decrements the ref count, and the last * close discards the reference entirely -- in other words, we do not * check to see if we've already opened this shared library. */ WT_ERR(__wt_dlopen(session, path, &dlh)); WT_ERR(__wt_dlsym(session, dlh, entry_name, &entry)); /* Call the entry function. */ WT_ERR(entry(&session->iface, &__api, config)); /* Link onto the environment's list of open libraries. */ __wt_spin_lock(session, &conn->api_lock); TAILQ_INSERT_TAIL(&conn->dlhqh, dlh, q); __wt_spin_unlock(session, &conn->api_lock); if (0) { err: if (dlh != NULL) WT_TRET(__wt_dlclose(session, dlh)); } __wt_free(session, entry_name); API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_add_extractor -- * WT_CONNECTION->add_extractor method. */ static int __conn_add_extractor(WT_CONNECTION *wt_conn, const char *name, WT_EXTRACTOR *extractor, const char *config) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; WT_UNUSED(name); WT_UNUSED(extractor); ret = ENOTSUP; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, add_extractor, config, cfg); WT_UNUSED(cfg); err: API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_reconfigure -- * WT_CONNECTION->reconfigure method. */ static int __conn_reconfigure(WT_CONNECTION *wt_conn, const char *config) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; /* * Special version of cfg that doesn't include the default config: used * to limit changes to values that the application sets explicitly. * Note that any function using this value has to be prepared to handle * not-found as a valid option return. */ const char *raw_cfg[] = { config, NULL }; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, reconfigure, config, cfg); /* Turning on statistics clears any existing values. */ if ((ret = __wt_config_gets(session, raw_cfg, "statistics", &cval)) == 0) { conn->statistics = cval.val == 0 ? 0 : 1; if (conn->statistics) __wt_stat_clear_connection_stats(&conn->stats); } WT_ERR_NOTFOUND_OK(ret); WT_ERR(__wt_conn_cache_pool_config(session, cfg)); WT_ERR(__wt_cache_config(conn, raw_cfg)); WT_ERR(__conn_verbose_config(session, raw_cfg)); /* Wake up the cache pool server so any changes are noticed. */ if (F_ISSET(conn, WT_CONN_CACHE_POOL)) WT_ERR(__wt_cond_signal( session, __wt_process.cache_pool->cache_pool_cond)); err: API_END(session); return (ret); }
/* * __conn_open_session -- * WT_CONNECTION->open_session method. */ static int __conn_open_session(WT_CONNECTION *wt_conn, WT_EVENT_HANDLER *event_handler, const char *config, WT_SESSION **wt_sessionp) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session, *session_ret; conn = (WT_CONNECTION_IMPL *)wt_conn; session_ret = NULL; CONNECTION_API_CALL(conn, session, open_session, config, cfg); WT_UNUSED(cfg); WT_ERR(__wt_open_session(conn, 0, event_handler, config, &session_ret)); *wt_sessionp = &session_ret->iface; err: API_END_NOTFOUND_MAP(session, ret); }
/* * __conn_close -- * WT_CONNECTION->close method. */ static int __conn_close(WT_CONNECTION *wt_conn, const char *config) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_NAMED_COLLATOR *ncoll; WT_NAMED_COMPRESSOR *ncomp; WT_NAMED_DATA_SOURCE *ndsrc; WT_SESSION *wt_session; WT_SESSION_IMPL *s, *session; uint32_t i; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, close, config, cfg); WT_UNUSED(cfg); /* * Close open, external sessions. * Additionally, the session's hazard pointer memory isn't discarded * during normal session close because access to it isn't serialized. * Discard it now. Note the loop for the hazard pointer memory, it's * the entire session array, not only the active session count, as the * active session count may be less than the maximum session count. */ for (s = conn->sessions, i = 0; i < conn->session_cnt; ++s, ++i) if (s->active && !F_ISSET(s, WT_SESSION_INTERNAL)) { wt_session = &s->iface; WT_TRET(wt_session->close(wt_session, config)); } for (s = conn->sessions, i = 0; i < conn->session_size; ++s, ++i) if (!F_ISSET(s, WT_SESSION_INTERNAL)) __wt_free(session, s->hazard); /* * Shut down server threads other than the eviction server, which is * needed later to close btree handles. Some of these threads access * btree handles, so take care in ordering shutdown to make sure they * exit before files are closed. */ F_CLR(conn, WT_CONN_SERVER_RUN); WT_TRET(__wt_checkpoint_destroy(conn)); WT_TRET(__wt_statlog_destroy(conn)); /* Clean up open LSM handles. */ WT_ERR(__wt_lsm_cleanup(&conn->iface)); /* Close open btree handles. */ WT_TRET(__wt_conn_btree_discard(conn)); /* Free memory for collators */ while ((ncoll = TAILQ_FIRST(&conn->collqh)) != NULL) __conn_remove_collator(conn, ncoll); /* Free memory for compressors */ while ((ncomp = TAILQ_FIRST(&conn->compqh)) != NULL) __conn_remove_compressor(conn, ncomp); /* Free memory for data sources */ while ((ndsrc = TAILQ_FIRST(&conn->dsrcqh)) != NULL) __conn_remove_data_source(conn, ndsrc); WT_TRET(__wt_connection_close(conn)); /* We no longer have a session, don't try to update it. */ session = NULL; err: API_END_NOTFOUND_MAP(session, ret); }