From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp36.i.mail.ru (smtp36.i.mail.ru [94.100.177.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id F251441C5DB for ; Mon, 29 Jun 2020 18:32:48 +0300 (MSK) From: Serge Petrenko Date: Mon, 29 Jun 2020 18:32:25 +0300 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 1/4] [tosquash] move wait_confirm from gc.c to txn_limbo.c List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: v.shpilevoy@tarantool.org, gorcunov@tarantool.org, sergos@tarantool.org, lvasiliev@tarantool.org Cc: tarantool-patches@dev.tarantool.org Move all the machinery for waiting for confirmation of the latest limbo entry from gc.c to txn_limbo.c Refactor gc_wait_confirm(void) to txn_limbo_wait_confirm(struct txn_limbo *) and make it return immediately when the limbo is empty to simplify code a bit. Refactoring needed for #5097 [TO BE SQUASHED INTO THE PREVIOUS COMMIT] --- src/box/gc.c | 83 ++------------------------------------------- src/box/txn_limbo.c | 74 ++++++++++++++++++++++++++++++++++++++++ src/box/txn_limbo.h | 7 ++++ 3 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/box/gc.c b/src/box/gc.c index 9b7c510f6..170c0a97f 100644 --- a/src/box/gc.c +++ b/src/box/gc.c @@ -68,23 +68,6 @@ gc_cleanup_fiber_f(va_list); static int gc_checkpoint_fiber_f(va_list); -/** - * Waitpoint stores information about the progress of confirmation. - * In the case of multimaster support, it will store a bitset - * or array instead of the boolean. - */ -struct confirm_waitpoint { - /** - * Variable for wake up the fiber that is waiting for - * the end of confirmation. - */ - struct fiber_cond confirm_cond; - /** - * Result flag. - */ - bool is_confirm; -}; - /** * Comparator used for ordering gc_consumer objects * lexicographically by their vclock in a binary tree. @@ -396,64 +379,6 @@ gc_add_checkpoint(const struct vclock *vclock) gc_schedule_cleanup(); } -static int -gc_txn_commit_cb(struct trigger *trigger, void *event) -{ - (void)event; - struct confirm_waitpoint *cwp = - (struct confirm_waitpoint *)trigger->data; - cwp->is_confirm = true; - fiber_cond_signal(&cwp->confirm_cond); - return 0; -} - -static int -gc_txn_rollback_cb(struct trigger *trigger, void *event) -{ - (void)event; - struct confirm_waitpoint *cwp = - (struct confirm_waitpoint *)trigger->data; - fiber_cond_signal(&cwp->confirm_cond); - return 0; -} - -/** - * Waiting for confirmation of all "sync" transactions - * during confirm timeout or fail. - */ -static int -gc_wait_confirm(void) -{ - /* initialization of a waitpoint. */ - struct confirm_waitpoint cwp; - fiber_cond_create(&cwp.confirm_cond); - cwp.is_confirm = false; - - /* Set triggers for the last limbo transaction. */ - struct trigger on_complete; - trigger_create(&on_complete, gc_txn_commit_cb, &cwp, NULL); - struct trigger on_rollback; - trigger_create(&on_rollback, gc_txn_rollback_cb, &cwp, NULL); - struct txn_limbo_entry *tle = txn_limbo_last_entry(&txn_limbo); - txn_on_commit(tle->txn, &on_complete); - txn_on_rollback(tle->txn, &on_rollback); - - int rc = fiber_cond_wait_timeout(&cwp.confirm_cond, - txn_limbo_confirm_timeout(&txn_limbo)); - fiber_cond_destroy(&cwp.confirm_cond); - if (rc != 0) { - /* Clear the triggers if the timeout has been reached. */ - trigger_clear(&on_complete); - trigger_clear(&on_rollback); - return -1; - } - if (!cwp.is_confirm) { - /* The transaction has been rollbacked. */ - return -1; - } - return 0; -} - static int gc_do_checkpoint(bool is_scheduled) { @@ -478,11 +403,9 @@ gc_do_checkpoint(bool is_scheduled) * Wait the confirms on all "sync" transactions before * create a snapshot. */ - if (!txn_limbo_is_empty(&txn_limbo)) { - rc = gc_wait_confirm(); - if (rc != 0) - goto out; - } + rc = txn_limbo_wait_confirm(&txn_limbo); + if (rc != 0) + goto out; rc = engine_commit_checkpoint(&checkpoint.vclock); if (rc != 0) diff --git a/src/box/txn_limbo.c b/src/box/txn_limbo.c index 18a50d4d3..d3751a28b 100644 --- a/src/box/txn_limbo.c +++ b/src/box/txn_limbo.c @@ -339,6 +339,80 @@ txn_limbo_confirm_timeout(struct txn_limbo *limbo) return replication_synchro_timeout; } +/** + * Waitpoint stores information about the progress of confirmation. + * In the case of multimaster support, it will store a bitset + * or array instead of the boolean. + */ +struct confirm_waitpoint { + /** + * Variable for wake up the fiber that is waiting for + * the end of confirmation. + */ + struct fiber_cond confirm_cond; + /** + * Result flag. + */ + bool is_confirm; +}; + +static int +txn_commit_cb(struct trigger *trigger, void *event) +{ + (void)event; + struct confirm_waitpoint *cwp = + (struct confirm_waitpoint *)trigger->data; + cwp->is_confirm = true; + fiber_cond_signal(&cwp->confirm_cond); + return 0; +} + +static int +txn_rollback_cb(struct trigger *trigger, void *event) +{ + (void)event; + struct confirm_waitpoint *cwp = + (struct confirm_waitpoint *)trigger->data; + fiber_cond_signal(&cwp->confirm_cond); + return 0; +} + +int +txn_limbo_wait_confirm(struct txn_limbo *limbo) +{ + if (txn_limbo_is_empty(limbo)) + return 0; + + /* initialization of a waitpoint. */ + struct confirm_waitpoint cwp; + fiber_cond_create(&cwp.confirm_cond); + cwp.is_confirm = false; + + /* Set triggers for the last limbo transaction. */ + struct trigger on_complete; + trigger_create(&on_complete, txn_commit_cb, &cwp, NULL); + struct trigger on_rollback; + trigger_create(&on_rollback, txn_rollback_cb, &cwp, NULL); + struct txn_limbo_entry *tle = txn_limbo_last_entry(limbo); + txn_on_commit(tle->txn, &on_complete); + txn_on_rollback(tle->txn, &on_rollback); + + int rc = fiber_cond_wait_timeout(&cwp.confirm_cond, + txn_limbo_confirm_timeout(limbo)); + fiber_cond_destroy(&cwp.confirm_cond); + if (rc != 0) { + /* Clear the triggers if the timeout has been reached. */ + trigger_clear(&on_complete); + trigger_clear(&on_rollback); + return -1; + } + if (!cwp.is_confirm) { + /* The transaction has been rolled back. */ + return -1; + } + return 0; +} + void txn_limbo_init(void) { diff --git a/src/box/txn_limbo.h b/src/box/txn_limbo.h index 987cf9271..138093c7c 100644 --- a/src/box/txn_limbo.h +++ b/src/box/txn_limbo.h @@ -198,6 +198,13 @@ txn_limbo_last_entry(struct txn_limbo *limbo) double txn_limbo_confirm_timeout(struct txn_limbo *limbo); +/** + * Waiting for confirmation of all "sync" transactions + * during confirm timeout or fail. + */ +int +txn_limbo_wait_confirm(struct txn_limbo *limbo); + void txn_limbo_init(); -- 2.24.3 (Apple Git-128)