From b06d10529edd22579ca901cac1c77c5602419b97 Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Fri, 21 Dec 2018 15:27:15 +0300 Subject: [PATCH] Make sure spinlock is not left unreleased when an exception is thrown A spinlock is not released when an exception is thrown after spinlock is acquired. This has caused infinite wait and eventual crash in maintenance daemon. This work moves the code than can fail to the outside of spinlock scope so that in the case of failure spinlock is not left locked since it was not locked in the first place. --- src/backend/distributed/transaction/backend_data.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/transaction/backend_data.c b/src/backend/distributed/transaction/backend_data.c index 119d5d1c1..7788a13b2 100644 --- a/src/backend/distributed/transaction/backend_data.c +++ b/src/backend/distributed/transaction/backend_data.c @@ -805,9 +805,15 @@ AssignDistributedTransactionId(void) void MarkCitusInitiatedCoordinatorBackend(void) { + /* + * GetLocalGroupId may throw exception which can cause leaving spin lock + * unreleased. Calling GetLocalGroupId function before the lock to avoid this. + */ + int localGroupId = GetLocalGroupId(); + SpinLockAcquire(&MyBackendData->mutex); - MyBackendData->citusBackend.initiatorNodeIdentifier = GetLocalGroupId(); + MyBackendData->citusBackend.initiatorNodeIdentifier = localGroupId; MyBackendData->citusBackend.transactionOriginator = true; SpinLockRelease(&MyBackendData->mutex);