diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-05-09 23:05:09 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-05-09 23:05:09 +1000 |
commit | 4feb6ae1ca7c225d867750330c8a5b7fabc75624 (patch) | |
tree | 4719d0855976bb656a55cf6521d5631fcf418ebf | |
parent | da7f73fb780ea9ecc2d4a1478f654b20838080e5 (diff) | |
download | mongo-4feb6ae1ca7c225d867750330c8a5b7fabc75624.tar.gz |
Have a real session attached to each connection handle.
closes #180
-rw-r--r-- | src/btree/bt_cache.c | 4 | ||||
-rw-r--r-- | src/btree/bt_evict.c | 4 | ||||
-rw-r--r-- | src/conn/conn_api.c | 31 | ||||
-rw-r--r-- | src/conn/conn_btree.c | 9 | ||||
-rw-r--r-- | src/conn/conn_handle.c | 4 | ||||
-rw-r--r-- | src/conn/conn_open.c | 17 | ||||
-rw-r--r-- | src/include/api.h | 13 | ||||
-rw-r--r-- | src/session/session_api.c | 6 | ||||
-rw-r--r-- | src/session/session_btree.c | 2 | ||||
-rw-r--r-- | src/support/err.c | 60 |
10 files changed, 85 insertions, 65 deletions
diff --git a/src/btree/bt_cache.c b/src/btree/bt_cache.c index b4256ba6f85..ce34ac63dcf 100644 --- a/src/btree/bt_cache.c +++ b/src/btree/bt_cache.c @@ -19,7 +19,7 @@ __wt_cache_create(WT_CONNECTION_IMPL *conn, const char *cfg[]) WT_DECL_RET; WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; WT_RET(__wt_calloc_def(session, 1, &conn->cache)); cache = conn->cache; @@ -90,7 +90,7 @@ __wt_cache_destroy(WT_CONNECTION_IMPL *conn) WT_SESSION_IMPL *session; WT_CACHE *cache; - session = &conn->default_session; + session = conn->default_session; cache = conn->cache; if (cache == NULL) diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c index bab00b68384..1ecdc473e87 100644 --- a/src/btree/bt_evict.c +++ b/src/btree/bt_evict.c @@ -258,7 +258,7 @@ __wt_cache_evict_server(void *arg) * We need a session handle because we're reading/writing pages. * Start with the default session to keep error handling simple. */ - session = &conn->default_session; + session = conn->default_session; WT_ERR(__wt_open_session(conn, 1, NULL, NULL, &session)); while (F_ISSET(conn, WT_SERVER_RUN)) { @@ -296,7 +296,7 @@ err: __wt_err(session, ret, "eviction server error"); __wt_free(session, cache->evict); - if (session != &conn->default_session) + if (session != conn->default_session) (void)session->iface.close(&session->iface, NULL); return (NULL); diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c index 83892d31f09..b559797243c 100644 --- a/src/conn/conn_api.c +++ b/src/conn/conn_api.c @@ -121,7 +121,7 @@ __conn_remove_collator(WT_CONNECTION_IMPL *conn, WT_NAMED_COLLATOR *ncoll) { WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; /* Remove from the connection's list. */ TAILQ_REMOVE(&conn->collqh, ncoll, q); @@ -174,7 +174,7 @@ __conn_remove_compressor(WT_CONNECTION_IMPL *conn, WT_NAMED_COMPRESSOR *ncomp) { WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; /* Remove from the connection's list. */ TAILQ_REMOVE(&conn->compqh, ncomp, q); @@ -232,7 +232,7 @@ __conn_remove_data_source( { WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; /* Remove from the connection's list. */ TAILQ_REMOVE(&conn->dsrcqh, ndsrc, q); @@ -382,7 +382,7 @@ __conn_config(WT_CONNECTION_IMPL *conn, const char **cfg, WT_ITEM **cbufp) cbuf = NULL; fh = NULL; - session = &conn->default_session; + session = conn->default_session; /* Check for an optional configuration file. */ #define WT_CONFIGFILE "WiredTiger.config" @@ -524,7 +524,7 @@ __conn_home(WT_CONNECTION_IMPL *conn, const char *home, const char **cfg) WT_CONFIG_ITEM cval; WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; /* If the application specifies a home directory, use it. */ if (home != NULL) @@ -580,7 +580,7 @@ __conn_single(WT_CONNECTION_IMPL *conn, const char **cfg) int created; char buf[256]; - session = &conn->default_session; + session = conn->default_session; #define WT_FLAGFILE "WiredTiger" /* @@ -725,16 +725,11 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, TAILQ_INSERT_TAIL(&__wt_process.connqh, conn, q); __wt_spin_unlock(NULL, &__wt_process.spinlock); - session = &conn->default_session; + conn->default_session = session = &conn->dummy_session; session->iface.connection = &conn->iface; session->name = "wiredtiger_open"; - - /* - * Configure any event handlers provided by the application as soon as - * possible so errors are handled correctly. - */ - if (event_handler != NULL) - session->event_handler = event_handler; + session->event_handler = (event_handler != NULL) ? + event_handler : __wt_event_handler_default; /* Remaining basic initialization of the connection structure. */ WT_ERR(__wt_connection_init(conn)); @@ -757,7 +752,7 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, WT_ERR(__wt_config_gets(session, cfg, "hazard_max", &cval)); conn->hazard_size = (uint32_t)cval.val; WT_ERR(__wt_config_gets(session, cfg, "session_max", &cval)); - conn->session_size = (uint32_t)cval.val; + conn->session_size = (uint32_t)cval.val + WT_NUM_INTERNAL_SESSIONS; WT_ERR(__wt_config_gets(session, cfg, "sync", &cval)); if (!cval.val) F_SET(conn, WT_CONN_NOSYNC); @@ -828,16 +823,16 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, WT_ERR(ret); } + WT_ERR(__wt_open_session(conn, 1, NULL, NULL, &conn->default_session)); + session = conn->default_session; + /* * Check on the turtle and metadata files, creating them if necessary * (which avoids application threads racing to create the metadata file * later). We need a session handle for this, open one. */ - WT_ERR(__wt_open_session(conn, 0, NULL, NULL, &session)); if ((ret = __wt_turtle_init(session, &exist)) == 0 && !exist) ret = __wt_schema_create(session, WT_METADATA_URI, NULL); - WT_TRET(session->iface.close(&session->iface, NULL)); - session = &conn->default_session; WT_ERR(ret); STATIC_ASSERT(offsetof(WT_CONNECTION_IMPL, iface) == 0); diff --git a/src/conn/conn_btree.c b/src/conn/conn_btree.c index 9763329fe21..6bd9a2c94aa 100644 --- a/src/conn/conn_btree.c +++ b/src/conn/conn_btree.c @@ -367,11 +367,7 @@ __wt_conn_btree_discard(WT_CONNECTION_IMPL *conn) WT_DECL_RET; WT_SESSION_IMPL *session; - /* - * We need a session handle because we're potentially reading/writing - * pages. - */ - WT_RET(__wt_open_session(conn, 1, NULL, NULL, &session)); + session = conn->default_session; /* * Close open btree handles: first, everything but the metadata file @@ -407,8 +403,5 @@ restart: WT_TRET(__conn_btree_discard(session, btree)); } - /* Discard our session. */ - WT_TRET(session->iface.close(&session->iface, NULL)); - return (ret); } diff --git a/src/conn/conn_handle.c b/src/conn/conn_handle.c index 42c9ac7e871..d02ef1ec7e3 100644 --- a/src/conn/conn_handle.c +++ b/src/conn/conn_handle.c @@ -16,7 +16,7 @@ __wt_connection_init(WT_CONNECTION_IMPL *conn) { WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; TAILQ_INIT(&conn->btqh); /* WT_BTREE list */ TAILQ_INIT(&conn->dlhqh); /* Library list */ @@ -49,7 +49,7 @@ __wt_connection_destroy(WT_CONNECTION_IMPL *conn) { WT_SESSION_IMPL *session; - session = &conn->default_session; + session = conn->default_session; /* Check there's something to destroy. */ if (conn == NULL) diff --git a/src/conn/conn_open.c b/src/conn/conn_open.c index de64ba3c818..17e1a41ccf2 100644 --- a/src/conn/conn_open.c +++ b/src/conn/conn_open.c @@ -18,9 +18,8 @@ __wt_connection_open(WT_CONNECTION_IMPL *conn, const char *cfg[]) WT_SESSION_IMPL *session; /* Default session. */ - conn->default_session.iface.connection = &conn->iface; - - session = &conn->default_session; + session = conn->default_session; + session->iface.connection = &conn->iface; /* WT_SESSION_IMPL and hazard arrays. */ WT_ERR(__wt_calloc(session, @@ -64,7 +63,7 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn) WT_DLH *dlh; WT_FH *fh; - session = &conn->default_session; + session = conn->default_session; /* * Complain if files weren't closed (ignoring the lock and logging @@ -96,6 +95,16 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn) WT_TRET(__wt_dlclose(session, dlh)); } + /* + * Close the default session and switch back to the dummy session in + * case of any error messages from the remaining operations while + * destroying the connection handle. + */ + if (session != &conn->dummy_session) { + WT_TRET(session->iface.close(&session->iface, NULL)); + conn->default_session = &conn->dummy_session; + } + /* Destroy the handle. */ __wt_connection_destroy(conn); diff --git a/src/include/api.h b/src/include/api.h index fba3c512e16..22b7c93df4d 100644 --- a/src/include/api.h +++ b/src/include/api.h @@ -141,14 +141,21 @@ struct __wt_named_data_source { }; /* + * Allocate some additional slots for internal sessions. There is a default + * session for each connection, plus a session for the eviction thread. + */ +#define WT_NUM_INTERNAL_SESSIONS 2 + +/* * WT_CONNECTION_IMPL -- * Implementation of WT_CONNECTION */ struct __wt_connection_impl { WT_CONNECTION iface; - WT_SESSION_IMPL default_session;/* For operations without an - application-supplied session */ + /* For operations without an application-supplied session */ + WT_SESSION_IMPL *default_session; + WT_SESSION_IMPL dummy_session; WT_SPINLOCK fh_lock; /* File handle queue spinlock */ WT_SPINLOCK serial_lock; /* Serial function call spinlock */ @@ -272,7 +279,7 @@ struct __wt_connection_impl { API_CALL(s, session, n, NULL, NULL, cfg, cfgvar); #define CONNECTION_API_CALL(conn, s, n, cfg, cfgvar) \ - s = &conn->default_session; \ + s = conn->default_session; \ API_CALL(s, connection, n, NULL, NULL, cfg, cfgvar); \ #define CURSOR_API_CALL(cur, s, n, bt) \ diff --git a/src/session/session_api.c b/src/session/session_api.c index 3cd20c934db..2a285b25810 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -75,7 +75,7 @@ __session_close(WT_SESSION *wt_session, const char *config) */ WT_PUBLISH(session->iface.connection, NULL); - session = &conn->default_session; + session = conn->default_session; __wt_spin_unlock(session, &conn->spinlock); err: API_END_NOTFOUND_MAP(session, ret); @@ -152,7 +152,7 @@ __session_create(WT_SESSION *wt_session, const char *uri, const char *config) WT_UNUSED(cfg); /* Disallow objects in the WiredTiger name space. */ - WT_RET(__wt_schema_name_check(session, uri)); + WT_ERR(__wt_schema_name_check(session, uri)); WT_ERR(__wt_schema_create(session, uri, config)); @@ -473,7 +473,7 @@ __wt_open_session(WT_CONNECTION_IMPL *conn, int internal, WT_UNUSED(config); - session = &conn->default_session; + session = conn->default_session; session_ret = NULL; __wt_spin_lock(session, &conn->spinlock); diff --git a/src/session/session_btree.c b/src/session/session_btree.c index 13d659fe1e1..485a06ee698 100644 --- a/src/session/session_btree.c +++ b/src/session/session_btree.c @@ -165,7 +165,7 @@ __wt_session_get_btree(WT_SESSION_IMPL *session, return (ret); } } - + /* * Reading the metadata doubles as an existence check. If it fails, we * can't open the file anyway, so it might as well not exist. diff --git a/src/support/err.c b/src/support/err.c index 9cc36b2a557..9a279ff6e5b 100644 --- a/src/support/err.c +++ b/src/support/err.c @@ -12,12 +12,14 @@ * Default WT_EVENT_HANDLER->handle_error implementation: send to stderr. */ static int -__handle_error_default(int error, const char *errmsg) +__handle_error_default(WT_EVENT_HANDLER *handler, int error, const char *errmsg) { size_t len_err, len_errmsg; const char *err; int cprint; + WT_UNUSED(handler); + if (error != 0) { err = wiredtiger_strerror(error); len_err = strlen(err); @@ -38,16 +40,41 @@ __handle_error_default(int error, const char *errmsg) * Default WT_EVENT_HANDLER->handle_message implementation: send to stdout. */ static int -__handle_message_default(const char *message) +__handle_message_default(WT_EVENT_HANDLER *handler, const char *message) { int cprint; + WT_UNUSED(handler); + cprint = printf("%s\n", message); return (cprint >= 0 ? 0 : EIO); } /* + * __handle_progress_default -- + * Default WT_EVENT_HANDLER->handle_progress implementation: ignore. + */ +static int +__handle_progress_default( + WT_EVENT_HANDLER *handler, const char *operation, uint64_t progress) +{ + WT_UNUSED(handler); + WT_UNUSED(operation); + WT_UNUSED(progress); + + return (0); +} + +static WT_EVENT_HANDLER __event_handler_default = { + __handle_error_default, + __handle_message_default, + __handle_progress_default +}; + +WT_EVENT_HANDLER *__wt_event_handler_default = &__event_handler_default; + +/* * __handler_failure -- * Report the failure of an application-configured event handler. */ @@ -71,15 +98,15 @@ __handler_failure(WT_SESSION_IMPL *session, /* * Use the error handler to report the failure, unless it was the error * handler that failed. If it was the error handler that failed, or a - * called to the error handler fails, use the default error handler. + * call to the error handler fails, use the default error handler. */ handler = session->event_handler; if (!error_handler_failed && - handler != NULL && handler->handle_error != NULL && - handler->handle_error(handler, error, s) == 0) + handler->handle_error != __handle_error_default && + handler->handle_error(handler, error, s) == 0) return; - (void)__handle_error_default(error, s); + (void)__handle_error_default(NULL, error, s); } /* @@ -140,20 +167,13 @@ __eventv(WT_SESSION_IMPL *session, int msg_event, int error, */ handler = session->event_handler; if (msg_event) { - if (handler == NULL || handler->handle_message == NULL) - ret = __handle_message_default(s); - else - ret = handler->handle_message(handler, s); + ret = handler->handle_message(handler, s); if (ret != 0) __handler_failure(session, ret, "message", 0); } else { - if (handler == NULL || handler->handle_error == NULL) - ret = __handle_error_default(error, s); - else { - ret = handler->handle_error(handler, error, s); - if (ret != 0) - __handler_failure(session, ret, "error", 1); - } + ret = handler->handle_error(handler, error, s); + if (ret != 0 && handler->handle_error != __handle_error_default) + __handler_failure(session, ret, "error", 1); } return (ret); @@ -243,11 +263,7 @@ __wt_vmsg(WT_SESSION_IMPL *session, const char *fmt, va_list ap) (void)vsnprintf(s, sizeof(s), fmt, ap); handler = session->event_handler; - if (handler == NULL || handler->handle_message == NULL) - return (__handle_message_default(s)); - else - return (handler->handle_message(handler, s)); - /* NOTREACHED */ + return (handler->handle_message(handler, s)); } /* |