From a0a76c1a83445cf76fa29a1be1381bb861feb219 Mon Sep 17 00:00:00 2001
From: "Stephen R. van den Berg" <srb@cuci.nl>
Date: Sat, 2 Jun 2018 13:09:53 +0200
Subject: [PATCH] pgsql: Release lock on collision with another thread on the
 same portal.

---
 lib/modules/Sql.pmod/pgsql_util.pmod | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod
index 3b6f232fe2..85e3fbdb8f 100644
--- a/lib/modules/Sql.pmod/pgsql_util.pmod
+++ b/lib/modules/Sql.pmod/pgsql_util.pmod
@@ -468,14 +468,18 @@ class conxion {
       PD("Nostash locked by %s\n",
        describe_backtrace(nostash->current_locking_thread()->backtrace()));
 #endif
-    if (lock = (waitforreal ? nostash->lock : nostash->trylock)(1)) {
-      stashcount->wait_till_drained();
-#ifdef PG_DEBUGRACE
-      conxsess sess = conxsess(this);
-#endif
+    while (lock = (waitforreal ? nostash->lock : nostash->trylock)(1)) {
       int mode;
       if (sizeof(stash) && (mode = getstash(KEEP)) > KEEP)
         sendcmd(mode);		// Force out stash to the server
+      if (!stashcount->drained()) {
+        lock = 0;				// Unlock while we wait
+        stashcount->wait_till_drained();
+        continue;				// Try again
+      }
+#ifdef PG_DEBUGRACE
+      conxsess sess = conxsess(this);
+#endif
       started = lock;		// sendcmd() clears started, so delay assignment
 #ifdef PG_DEBUGRACE
       return sess;
-- 
GitLab