diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2015-08-05 06:54:07 -0400 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-08-06 12:12:59 +1000 |
commit | f9572e20ad2de5372bd9c47ea0611a0b95dd92e5 (patch) | |
tree | 096d529d779ea59a4dce4c686d7f6da5f855a151 | |
parent | 0349d8aa5f07209fb9b53cfff8236abe8acedfa3 (diff) | |
download | mongo-f9572e20ad2de5372bd9c47ea0611a0b95dd92e5.tar.gz |
WT-2025 Assert that cursors are positioned for inserts
Merge pull request #2106 from wiredtiger/cursor-positioned
(cherry picked from commit c5c9936fb240c5bb4ec925f683476b7f075cfc78)
-rw-r--r-- | src/btree/col_modify.c | 2 | ||||
-rw-r--r-- | src/btree/row_modify.c | 2 | ||||
-rw-r--r-- | src/include/cursor.i | 6 | ||||
-rw-r--r-- | src/include/serial.i | 31 |
4 files changed, 23 insertions, 18 deletions
diff --git a/src/btree/col_modify.c b/src/btree/col_modify.c index dda56c19636..01db31057fc 100644 --- a/src/btree/col_modify.c +++ b/src/btree/col_modify.c @@ -160,7 +160,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, * The serial mutex acts as our memory barrier to flush these * writes before inserting them into the list. */ - if (WT_SKIP_FIRST(ins_head) == NULL || recno == 0) + if (cbt->ins_stack[0] == NULL || recno == 0) for (i = 0; i < skipdepth; i++) { cbt->ins_stack[i] = &ins_head->head[i]; ins->next[i] = cbt->next_stack[i] = NULL; diff --git a/src/btree/row_modify.c b/src/btree/row_modify.c index f0a10cdf528..2dd42de5900 100644 --- a/src/btree/row_modify.c +++ b/src/btree/row_modify.c @@ -192,7 +192,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, * The serial mutex acts as our memory barrier to flush these * writes before inserting them into the list. */ - if (WT_SKIP_FIRST(ins_head) == NULL) + if (cbt->ins_stack[0] == NULL) for (i = 0; i < skipdepth; i++) { cbt->ins_stack[i] = &ins_head->head[i]; ins->next[i] = cbt->next_stack[i] = NULL; diff --git a/src/include/cursor.i b/src/include/cursor.i index 606fee53749..47b772377c0 100644 --- a/src/include/cursor.i +++ b/src/include/cursor.i @@ -187,6 +187,12 @@ __cursor_func_init(WT_CURSOR_BTREE *cbt, int reenter) if (reenter) WT_RET(__curfile_leave(cbt)); + /* + * Any old insert position is now invalid. We rely on this being + * cleared to detect if a new skiplist is installed after a search. + */ + cbt->ins_stack[0] = NULL; + /* If the transaction is idle, check that the cache isn't full. */ WT_RET(__wt_txn_idle_cache_check(session)); diff --git a/src/include/serial.i b/src/include/serial.i index 9e5acde9616..5b290822a10 100644 --- a/src/include/serial.i +++ b/src/include/serial.i @@ -47,6 +47,10 @@ __insert_simple_func(WT_SESSION_IMPL *session, * return success: the levels we updated are correct and sufficient. * Even though we don't get the benefit of the memory we allocated, * we can't roll back. + * + * All structure setup must be flushed before the structure is entered + * into the list. We need a write barrier here, our callers depend on + * it. */ for (i = 0; i < skipdepth; i++) if (!WT_ATOMIC_CAS8(*ins_stack[i], new_ins->next[i], new_ins)) @@ -65,7 +69,8 @@ __insert_serial_func(WT_SESSION_IMPL *session, WT_INSERT_HEAD *ins_head, { u_int i; - WT_UNUSED(session); + /* The cursor should be positioned. */ + WT_ASSERT(session, ins_stack[0] != NULL); /* * Update the skiplist elements referencing the new WT_INSERT item. @@ -75,6 +80,10 @@ __insert_serial_func(WT_SESSION_IMPL *session, WT_INSERT_HEAD *ins_head, * upper levels in the skiplist, return success: the levels we updated * are correct and sufficient. Even though we don't get the benefit of * the memory we allocated, we can't roll back. + * + * All structure setup must be flushed before the structure is entered + * into the list. We need a write barrier here, our callers depend on + * it. */ for (i = 0; i < skipdepth; i++) { if (!WT_ATOMIC_CAS8(*ins_stack[i], new_ins->next[i], new_ins)) @@ -143,13 +152,6 @@ __wt_col_append_serial(WT_SESSION_IMPL *session, WT_PAGE *page, WT_INSERT *new_ins = *new_insp; WT_DECL_RET; - /* !!! - * Test for an uninitialized cursor, ins_stack[0] is cleared as part of - * initializing a cursor for a search. - */ - if (ins_stack[0] == NULL) - return (WT_RESTART); - /* Check for page write generation wrap. */ WT_RET(__page_write_gen_wrapped_check(page)); @@ -162,8 +164,8 @@ __wt_col_append_serial(WT_SESSION_IMPL *session, WT_PAGE *page, session, ins_head, ins_stack, new_ins, recnop, skipdepth); WT_PAGE_UNLOCK(session, page); - /* Free unused memory on error. */ if (ret != 0) { + /* Free unused memory on error. */ __wt_free(session, new_ins); return (ret); } @@ -196,13 +198,6 @@ __wt_insert_serial(WT_SESSION_IMPL *session, WT_PAGE *page, int simple; u_int i; - /* !!! - * Test for an uninitialized cursor, ins_stack[0] is cleared as part of - * initializing a cursor for a search. - */ - if (ins_stack[0] == NULL) - return (WT_RESTART); - /* Check for page write generation wrap. */ WT_RET(__page_write_gen_wrapped_check(page)); @@ -262,6 +257,10 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_PAGE *page, *updp = NULL; /* + * All structure setup must be flushed before the structure is entered + * into the list. We need a write barrier here, our callers depend on + * it. + * * Swap the update into place. If that fails, a new update was added * after our search, we raced. Check if our update is still permitted. */ |