From c9ad7bba1e7afaf9ce4970a200ee737f176734a2 Mon Sep 17 00:00:00 2001 From: "Stephen R. van den Berg" <srb@cuci.nl> Date: Mon, 7 May 2018 20:20:22 +0200 Subject: [PATCH] pgsql: Eliminate rare deadlock on heavy interleaved queries. --- lib/modules/Sql.pmod/pgsql_util.pmod | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod index 081dacd0fd..49e0d80648 100644 --- a/lib/modules/Sql.pmod/pgsql_util.pmod +++ b/lib/modules/Sql.pmod/pgsql_util.pmod @@ -384,6 +384,11 @@ class conxion { final bufcon|conxsess start(void|int waitforreal) { Thread.MutexKey lock; +#ifdef PG_DEBUGRACE + if (nostash->current_locking_thread()) + PD("Nostash locked by %s\n", + describe_backtrace(nostash->current_locking_thread()->backtrace())); +#endif if (lock = (waitforreal ? nostash->lock : nostash->trylock)(1)) { int mode; #ifdef PG_DEBUGRACE @@ -1304,7 +1309,7 @@ class sql_result { void|bufcon|conxsess plugbuffer = CHAIN(cs); int retval = KEEP; PD("%O Try Closeportal %d\n", _portalname, _state); - Thread.MutexKey lock = closemux->lock(); + Thread.MutexKey lock = closemux->lock(2); // When called from _sendexecute(), it is already locked _fetchlimit = 0; // disables further Executes switch (_state) { case PARSING: @@ -1348,16 +1353,19 @@ class sql_result { private void replenishrows() { if (_fetchlimit && sizeof(datarows) <= _fetchlimit >> 1) { - _fetchlimit = pgsqlsess._fetchlimit; - if (bytesreceived) - _fetchlimit = - min((portalbuffersize >> 1) * index / bytesreceived || 1, _fetchlimit); Thread.MutexKey lock = closemux->lock(); - if (_fetchlimit && inflight <= (_fetchlimit - 1) >> 1) - _sendexecute(_fetchlimit); - else if (!_fetchlimit) - PD("<%O _fetchlimit %d, inflight %d, skip execute\n", - _portalname, _fetchlimit, inflight); + if (_fetchlimit) { + _fetchlimit = pgsqlsess._fetchlimit; + if (bytesreceived) + _fetchlimit = + min((portalbuffersize >> 1) * index / bytesreceived || 1, _fetchlimit); + if (_fetchlimit) + if (inflight <= (_fetchlimit - 1) >> 1) + _sendexecute(_fetchlimit); + else + PD("<%O _fetchlimit %d, inflight %d, skip execute\n", + _portalname, _fetchlimit, inflight); + } } } -- GitLab