/* * __session_close_cache -- * Close any cached handles in a session. Called holding the schema lock. */ static int __session_close_cache(WT_SESSION_IMPL *session) { WT_BTREE_SESSION *btree_session; WT_DECL_RET; while ((btree_session = TAILQ_FIRST(&session->btrees)) != NULL) WT_TRET(__wt_session_discard_btree(session, btree_session)); WT_TRET(__wt_schema_close_tables(session)); return (ret); }
/* * __session_close -- * WT_SESSION->close method. */ static int __session_close(WT_SESSION *wt_session, const char *config) { WT_BTREE_SESSION *btree_session; WT_CONNECTION_IMPL *conn; WT_CURSOR *cursor; WT_SESSION_IMPL *session, **tp; int ret; conn = (WT_CONNECTION_IMPL *)wt_session->connection; session = (WT_SESSION_IMPL *)wt_session; SESSION_API_CALL(session, close, config, cfg); WT_UNUSED(cfg); while ((cursor = TAILQ_FIRST(&session->cursors)) != NULL) WT_TRET(cursor->close(cursor)); while ((btree_session = TAILQ_FIRST(&session->btrees)) != NULL) WT_TRET(__wt_session_remove_btree(session, btree_session, 0)); WT_TRET(__wt_schema_close_tables(session)); __wt_spin_lock(session, &conn->spinlock); /* Discard scratch buffers. */ __wt_scr_discard(session); /* Confirm we're not holding any hazard references. */ __wt_hazard_empty(session); /* Free the reconciliation information. */ __wt_rec_destroy(session); /* Free the eviction exclusive-lock information. */ __wt_free(session, session->excl); /* Destroy the thread's mutex. */ if (session->cond != NULL) (void)__wt_cond_destroy(session, session->cond); /* * Replace the session reference we're closing with the last entry in * the table, then clear the last entry. As far as the walk of the * server threads is concerned, it's OK if the session appears twice, * or if it doesn't appear at all, so these lines can race all they * want. */ for (tp = conn->sessions; *tp != session; ++tp) ; --conn->session_cnt; *tp = conn->sessions[conn->session_cnt]; conn->sessions[conn->session_cnt] = NULL; /* * Publish, making the session array entry available for re-use. There * must be a barrier here to ensure the cleanup above completes before * the entry is re-used. */ WT_PUBLISH(session->iface.connection, NULL); session = &conn->default_session; __wt_spin_unlock(session, &conn->spinlock); err: API_END_NOTFOUND_MAP(session, ret); }