YottaDB / YDB

Mirrored from https://gitlab.com/YottaDB/DB/YDB
Other
76 stars 37 forks source link

[#343] Ensure Ctrl-C on a long-running ZWRITE clears the internal zwrite-is-active flag or else debug-only assert failures can occur #344

Closed nars1 closed 6 years ago

nars1 commented 6 years ago

TREF(in_zwrite) is set to TRUE at the start of a ZWRITE. If the ZWRITE is run in direct mode (i.e. the YDB> prompt) and runs for a long time so the user interrupts it with a Ctrl-C, a YDB-I-CTLRC error is issued and control returns to the YDB> prompt. After that if the user runs an M command that contains an lvn, one gets an assert failure while running a debug build of YottaDB.

%YDB-F-ASSERT, Assert failed in sr_port/gtm_fetch.c line 73 for expression (!TREF(in_zwrite))

This is because TREF(in_zwrite) was not set to FALSE when the Ctrl-C happened. It should have been reset in mdb_condition_handler() but that had code to invoke NULLIFY_MERGE_ZWRITE_CONTEXT (the macro which resets TREF(in_zwrite) among other things) only if the error severity is ERROR or FATAL. But the CTRLC error severity is INFO and so it did not clear TREF(in_zwrite).

In V6.2-001, mdb_condition_handler() did the clear of TREF(in_zwrite) unconditionally but in V6.2-002, this was moved into a pre-existing if block (that checked whether severity is ERROR or FATAL) and folded into a new macro NULLIFY_MERGE_ZWRITE_CONTEXT. It is not clear why this change was necessary. Clearing the interrupted zwrite and/or merge context seems safe to do on any error even if it is a SUCCESS or INFO type. So have moved the NULLIFY_MERGE_ZWRITE_CONTEXT macro outside the "if" block. This way all zwrite-related context (including lvzwrite_block which is local-variable related context of ZWRITE) is now reset on a CTRLC error. Seems the right thing to do.