1 /*- 2 * Copyright (c) 2014-2018 MongoDB, Inc. 3 * Copyright (c) 2008-2014 WiredTiger, Inc. 4 * All rights reserved. 5 * 6 * See the file LICENSE for redistribution information. 7 */ 8 9 /* 10 * Helpers for calling a function with a data handle in session->dhandle 11 * then restoring afterwards. 12 */ 13 #define WT_WITH_DHANDLE(s, d, e) do { \ 14 WT_DATA_HANDLE *__saved_dhandle = (s)->dhandle; \ 15 (s)->dhandle = (d); \ 16 e; \ 17 (s)->dhandle = __saved_dhandle; \ 18 } while (0) 19 20 #define WT_WITH_BTREE(s, b, e) WT_WITH_DHANDLE(s, (b)->dhandle, e) 21 22 /* Call a function without the caller's data handle, restore afterwards. */ 23 #define WT_WITHOUT_DHANDLE(s, e) WT_WITH_DHANDLE(s, NULL, e) 24 25 /* 26 * Call a function with the caller's data handle, restore it afterwards in case 27 * it is overwritten. 28 */ 29 #define WT_SAVE_DHANDLE(s, e) WT_WITH_DHANDLE(s, (s)->dhandle, e) 30 31 /* Check if a handle is inactive. */ 32 #define WT_DHANDLE_INACTIVE(dhandle) \ 33 (F_ISSET(dhandle, WT_DHANDLE_DEAD) || \ 34 !F_ISSET(dhandle, WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_OPEN)) 35 36 /* Check if a handle could be reopened. */ 37 #define WT_DHANDLE_CAN_REOPEN(dhandle) \ 38 (!WT_DHANDLE_INACTIVE(dhandle) && \ 39 F_ISSET(dhandle, WT_DHANDLE_OPEN) && \ 40 !F_ISSET(dhandle, WT_DHANDLE_DROPPED)) 41 42 /* The metadata cursor's data handle. */ 43 #define WT_SESSION_META_DHANDLE(s) \ 44 (((WT_CURSOR_BTREE *)((s)->meta_cursor))->btree->dhandle) 45 46 #define WT_DHANDLE_ACQUIRE(dhandle) \ 47 (void)__wt_atomic_add32(&(dhandle)->session_ref, 1) 48 49 #define WT_DHANDLE_RELEASE(dhandle) \ 50 (void)__wt_atomic_sub32(&(dhandle)->session_ref, 1) 51 52 #define WT_DHANDLE_NEXT(session, dhandle, head, field) do { \ 53 WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST));\ 54 if ((dhandle) == NULL) \ 55 (dhandle) = TAILQ_FIRST(head); \ 56 else { \ 57 WT_DHANDLE_RELEASE(dhandle); \ 58 (dhandle) = TAILQ_NEXT(dhandle, field); \ 59 } \ 60 if ((dhandle) != NULL) \ 61 WT_DHANDLE_ACQUIRE(dhandle); \ 62 } while (0) 63 64 /* 65 * WT_DATA_HANDLE -- 66 * A handle for a generic named data source. 67 */ 68 struct __wt_data_handle { 69 WT_RWLOCK rwlock; /* Lock for shared/exclusive ops */ 70 TAILQ_ENTRY(__wt_data_handle) q; 71 TAILQ_ENTRY(__wt_data_handle) hashq; 72 73 const char *name; /* Object name as a URI */ 74 uint64_t name_hash; /* Hash of name */ 75 const char *checkpoint; /* Checkpoint name (or NULL) */ 76 const char **cfg; /* Configuration information */ 77 const char *meta_base; /* Base metadata configuration */ 78 79 /* 80 * Sessions holding a connection's data handle will have a non-zero 81 * reference count; sessions using a connection's data handle will 82 * have a non-zero in-use count. Instances of cached cursors referencing 83 * the data handle appear in session_cache_ref. 84 */ 85 uint32_t session_ref; /* Sessions referencing this handle */ 86 int32_t session_inuse; /* Sessions using this handle */ 87 uint32_t excl_ref; /* Refs of handle by excl_session */ 88 time_t timeofdeath; /* Use count went to 0 */ 89 WT_SESSION_IMPL *excl_session; /* Session with exclusive use, if any */ 90 91 WT_DATA_SOURCE *dsrc; /* Data source for this handle */ 92 void *handle; /* Generic handle */ 93 94 enum { 95 WT_DHANDLE_TYPE_BTREE, 96 WT_DHANDLE_TYPE_TABLE 97 } type; 98 99 bool compact_skip; /* If the handle failed to compact */ 100 101 /* 102 * Data handles can be closed without holding the schema lock; threads 103 * walk the list of open handles, operating on them (checkpoint is the 104 * best example). To avoid sources disappearing underneath checkpoint, 105 * lock the data handle when closing it. 106 */ 107 WT_SPINLOCK close_lock; /* Lock to close the handle */ 108 109 /* Data-source statistics */ 110 WT_DSRC_STATS *stats[WT_COUNTER_SLOTS]; 111 WT_DSRC_STATS *stat_array; 112 113 /* Flags values over 0xff are reserved for WT_BTREE_* */ 114 /* AUTOMATIC FLAG VALUE GENERATION START */ 115 #define WT_DHANDLE_DEAD 0x01u /* Dead, awaiting discard */ 116 #define WT_DHANDLE_DISCARD 0x02u /* Close on release */ 117 #define WT_DHANDLE_DISCARD_KILL 0x04u /* Mark dead on release */ 118 #define WT_DHANDLE_DROPPED 0x08u /* Handle is dropped */ 119 #define WT_DHANDLE_EXCLUSIVE 0x10u /* Exclusive access */ 120 #define WT_DHANDLE_IS_METADATA 0x20u /* Metadata handle */ 121 #define WT_DHANDLE_LOCK_ONLY 0x40u /* Handle only used as a lock */ 122 #define WT_DHANDLE_OPEN 0x80u /* Handle is open */ 123 /* AUTOMATIC FLAG VALUE GENERATION STOP */ 124 uint32_t flags; 125 }; 126