summaryrefslogtreecommitdiff
path: root/src/conn
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@wiredtiger.com>2011-08-05 11:04:41 -0400
committerKeith Bostic <keith.bostic@wiredtiger.com>2011-08-05 11:04:41 -0400
commit37136dc8a5ce7b05328132bece265aff6fd745e5 (patch)
treeaea375c21c32286ff2ecd29ae21de042ac56b299 /src/conn
parentc297a0ac75343103fd2b8179e3fb7f4de0b4e180 (diff)
downloadmongo-37136dc8a5ce7b05328132bece265aff6fd745e5.tar.gz
Rename the env/ directory to be the conn/ directory, moving a few things
(session dump code, global functions) items into support/. --HG-- rename : src/env/env_handle.c => src/conn/conn_handle.c rename : src/env/env_open.c => src/conn/conn_open.c rename : src/env/env_stat.c => src/conn/conn_stat.c rename : src/env/env_workq.c => src/conn/workq.c rename : src/env/env_global.c => src/support/global.c rename : src/env/env_session.c => src/support/sess_dump.c
Diffstat (limited to 'src/conn')
-rw-r--r--src/conn/conn_handle.c66
-rw-r--r--src/conn/conn_open.c129
-rw-r--r--src/conn/conn_stat.c22
-rw-r--r--src/conn/workq.c102
4 files changed, 319 insertions, 0 deletions
diff --git a/src/conn/conn_handle.c b/src/conn/conn_handle.c
new file mode 100644
index 00000000000..799b405a4d5
--- /dev/null
+++ b/src/conn/conn_handle.c
@@ -0,0 +1,66 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2011 WiredTiger, Inc.
+ * All rights reserved.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_connection_config --
+ * Set configuration for a just-created WT_CONNECTION_IMPL handle.
+ */
+int
+__wt_connection_config(WT_CONNECTION_IMPL *conn)
+{
+ WT_SESSION_IMPL *session;
+
+ session = &conn->default_session;
+
+ /* Global mutex */
+ WT_RET(__wt_mtx_alloc(session, "WT_CONNECTION_IMPL", 0, &conn->mtx));
+
+ TAILQ_INIT(&conn->dbqh); /* WT_BTREE list */
+ TAILQ_INIT(&conn->dlhqh); /* Library list */
+ TAILQ_INIT(&conn->fhqh); /* File list */
+
+ /* Statistics. */
+ WT_RET(__wt_stat_alloc_conn_stats(session, &conn->stats));
+
+ /* Diagnostic output separator. */
+ conn->sep = "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=";
+
+ return (0);
+}
+
+/*
+ * __wt_connection_destroy --
+ * Destroy the connection's underlying WT_CONNECTION_IMPL structure.
+ */
+int
+__wt_connection_destroy(WT_CONNECTION_IMPL *conn)
+{
+ WT_SESSION_IMPL *session;
+ int ret;
+
+ session = &conn->default_session;
+ ret = 0;
+
+ /* Check there's something to destroy. */
+ if (conn == NULL)
+ return (0);
+
+ if (conn->mtx != NULL)
+ (void)__wt_mtx_destroy(session, conn->mtx);
+
+ /* Free allocated memory. */
+ __wt_free(session, conn->home);
+ __wt_free(session, conn->sessions);
+ __wt_free(session, conn->session_array);
+ __wt_free(session, conn->hazard);
+ __wt_free(session, conn->stats);
+
+ __wt_free(NULL, conn);
+ return (ret);
+}
diff --git a/src/conn/conn_open.c b/src/conn/conn_open.c
new file mode 100644
index 00000000000..cb2f46f17ad
--- /dev/null
+++ b/src/conn/conn_open.c
@@ -0,0 +1,129 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2011 WiredTiger, Inc.
+ * All rights reserved.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_connection_open --
+ * Open a connection.
+ */
+int
+__wt_connection_open(WT_CONNECTION_IMPL *conn, const char *home, mode_t mode)
+{
+ WT_SESSION_IMPL *session;
+ int ret;
+
+ WT_UNUSED(home);
+ WT_UNUSED(mode);
+
+ /* Default session. */
+ conn->default_session.iface.connection = &conn->iface;
+
+ session = &conn->default_session;
+ ret = 0;
+
+ /* WT_SESSION_IMPL and hazard arrays. */
+ WT_RET(__wt_calloc(session,
+ conn->session_size, sizeof(WT_SESSION_IMPL *), &conn->sessions));
+ WT_RET(__wt_calloc(session,
+ conn->session_size, sizeof(WT_SESSION_IMPL),
+ &conn->session_array));
+ WT_RET(__wt_calloc(session,
+ conn->session_size * conn->hazard_size, sizeof(WT_HAZARD),
+ &conn->hazard));
+
+ /* Create the cache. */
+ WT_RET(__wt_cache_create(conn));
+
+ /* Start worker threads. */
+ F_SET(conn, WT_WORKQ_RUN | WT_SERVER_RUN);
+ WT_MEMORY_FLUSH;
+
+ WT_ERR(__wt_thread_create(
+ &conn->cache_evict_tid, __wt_cache_evict_server, conn));
+ WT_ERR(__wt_thread_create(
+ &conn->cache_read_tid, __wt_cache_read_server, conn));
+ WT_ERR(__wt_thread_create(&conn->workq_tid, __wt_workq_srvr, conn));
+
+ return (0);
+
+err: (void)__wt_connection_close(conn);
+ return (ret);
+}
+
+/*
+ * __wt_connection_close --
+ * Close a connection handle.
+ */
+int
+__wt_connection_close(WT_CONNECTION_IMPL *conn)
+{
+ WT_BTREE *btree;
+ WT_SESSION_IMPL *session;
+ WT_DLH *dlh;
+ WT_FH *fh;
+ int ret, secondary_err;
+
+ session = &conn->default_session;
+ ret = secondary_err = 0;
+
+ /* Complain if WT_BTREE handles weren't closed. */
+ while ((btree = TAILQ_FIRST(&conn->dbqh)) != NULL) {
+ __wt_errx(session,
+ "Connection has open btree handles: %s", btree->name);
+ session->btree = btree;
+ WT_TRET(__wt_btree_close(session));
+ secondary_err = WT_ERROR;
+ }
+
+ /* Complain if files weren't closed. */
+ while ((fh = TAILQ_FIRST(&conn->fhqh)) != NULL && fh != conn->log_fh) {
+ __wt_errx(session,
+ "connection has open file handles: %s", fh->name);
+ WT_TRET(__wt_close(session, fh));
+ secondary_err = WT_ERROR;
+ }
+
+ /* Shut down the server threads. */
+ F_CLR(conn, WT_SERVER_RUN);
+ WT_MEMORY_FLUSH;
+
+ /* Force the cache server threads to run and wait for them to exit. */
+ __wt_workq_evict_server_exit(conn);
+ __wt_thread_join(conn->cache_evict_tid);
+ __wt_workq_read_server_exit(conn);
+ __wt_thread_join(conn->cache_read_tid);
+
+ /*
+ * Close down and wait for the workQ thread; this only happens after
+ * all other server threads have exited, as they may be waiting on a
+ * request from the workQ, or vice-versa.
+ */
+ F_CLR(conn, WT_WORKQ_RUN);
+ WT_MEMORY_FLUSH;
+ __wt_thread_join(conn->workq_tid);
+
+ /* Discard the cache. */
+ __wt_cache_destroy(conn);
+
+ /* Close extensions. */
+ while ((dlh = TAILQ_FIRST(&conn->dlhqh)) != NULL)
+ WT_TRET(__wt_dlclose(session, dlh));
+
+ if (conn->log_fh != NULL) {
+ WT_TRET(__wt_close(session, conn->log_fh));
+ conn->log_fh = NULL;
+ }
+
+ /* Destroy the handle. */
+ WT_TRET(__wt_connection_destroy(conn));
+
+ if (ret == 0)
+ ret = secondary_err;
+
+ return ((ret == 0) ? secondary_err : ret);
+}
diff --git a/src/conn/conn_stat.c b/src/conn/conn_stat.c
new file mode 100644
index 00000000000..dc56253f378
--- /dev/null
+++ b/src/conn/conn_stat.c
@@ -0,0 +1,22 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2011 WiredTiger, Inc.
+ * All rights reserved.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_conn_stat_init --
+ * Initialize the Btree statistics.
+ */
+void
+__wt_conn_stat_init(WT_SESSION_IMPL *session)
+{
+ WT_CONNECTION_IMPL *conn;
+
+ conn = S2C(session);
+
+ __wt_cache_stats_update(conn);
+}
diff --git a/src/conn/workq.c b/src/conn/workq.c
new file mode 100644
index 00000000000..ffc6298a015
--- /dev/null
+++ b/src/conn/workq.c
@@ -0,0 +1,102 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2011 WiredTiger, Inc.
+ * All rights reserved.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_workq_srvr --
+ * Routine to process the WT_SESSION_IMPL work queue.
+ */
+void *
+__wt_workq_srvr(void *arg)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_SESSION_IMPL **tp, *session;
+ int call_evict, call_read, request;
+
+ conn = (WT_CONNECTION_IMPL *)arg;
+
+ /* Walk the WT_SESSION_IMPL list and execute requests. */
+ while (F_ISSET(conn, WT_WORKQ_RUN)) {
+ ++conn->api_gen;
+ WT_STAT_INCR(conn->stats, workq_passes);
+
+ call_evict = call_read = request = 0;
+ for (tp = conn->sessions; (session = *tp) != NULL; ++tp) {
+ switch (session->wq_state) {
+ case WT_WORKQ_NONE:
+ break;
+ case WT_WORKQ_FUNC:
+ request = 1;
+ (void)session->wq_func(session);
+ break;
+ case WT_WORKQ_READ:
+ /*
+ * Call a function which makes a request of the
+ * read server. There are two read states: READ
+ * (the initial request), and READ_SCHED (the
+ * function has been called and we're waiting on
+ * the read to complete). There are two states
+ * because we can race with the server: if the
+ * called function adds itself to the queue just
+ * as the server is going to sleep, the server
+ * might not see the request. So, READ_SCHED
+ * means we don't have to call the function, but
+ * we do have check if the server is running.
+ *
+ * The read state is eventually reset by the
+ * read server, so we set it before we call the
+ * function that will contact the server, so we
+ * can't race on that update.
+ */
+ session->wq_state = WT_WORKQ_READ_SCHED;
+
+ /* Queue the request for the read server. */
+ if (session->wq_func(session) != 0)
+ break;
+ /* FALLTHROUGH */
+ case WT_WORKQ_READ_SCHED:
+ call_read = 1;
+ break;
+ case WT_WORKQ_EVICT:
+ /*
+ * See comment above regarding read scheduling;
+ * eviction works the same as read, as far as
+ * the workq is concerned.
+ *
+ * We don't have to call a function to contact
+ * the eviction server, currently the eviction
+ * server checks the list of open tables each
+ * time it runs.
+ */
+ session->wq_state = WT_WORKQ_EVICT_SCHED;
+
+ /* Queue the request for the eviction server. */
+ if (session->wq_func(session) != 0)
+ break;
+ /* FALLTHROUGH */
+ case WT_WORKQ_EVICT_SCHED:
+ call_evict = 1;
+ break;
+ }
+ }
+
+ /* If a read is scheduled, check on the read server. */
+ if (call_read)
+ __wt_workq_read_server(conn, 0);
+
+ /* Check on the eviction server. */
+ __wt_workq_evict_server(conn, call_evict);
+
+ /* If we didn't find work, yield the processor. */
+ if (!request) {
+ WT_STAT_INCR(conn->stats, workq_yield);
+ __wt_yield();
+ }
+ }
+ return (NULL);
+}