diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod index 725c9afc062f24da6cca02b71cedb433c68525d5..6d92a1df551dbce74c55de56112ea6aeb9a175dd 100644 --- a/lib/modules/Sql.pmod/pgsql_util.pmod +++ b/lib/modules/Sql.pmod/pgsql_util.pmod @@ -171,6 +171,7 @@ private inline mixed callout(function(mixed ...:void) f, class bufcon { inherit Stdio.Buffer; + private int dirty; #ifdef PG_DEBUGRACE final bufcon `chain() { @@ -189,7 +190,9 @@ class bufcon { } final bufcon start(void|int waitforreal) { + dirty = 1; realbuffer->stashcount++; + dirty = 2; #ifdef PG_DEBUG if(waitforreal) error("pgsql.bufcon not allowed here\n"); @@ -211,8 +214,11 @@ class bufcon { realbuffer->socket->query_fd(), mode, realbuffer->stashflushmode); if (mode > realbuffer->stashflushmode) realbuffer->stashflushmode = mode; + dirty = 1; if(!--realbuffer->stashcount) - realbuffer->stashavail.signal(); + dirty = 0, realbuffer->stashavail.signal(); + else + dirty = 0; lock=0; this->clear(); if(lock=realbuffer->nostash->trylock(1)) { @@ -228,6 +234,21 @@ class bufcon { #endif } } + + protected void _destruct() { + switch (dirty) { + case 1: + werror("FIXME: Race condition detected %s\n", + describe_backtrace(({"", backtrace()[..<1]}))); + if (!realbuffer->stashcount) + break; + case 2: + Thread.MutexKey lock = realbuffer->shortmux->lock(2); + if (!--realbuffer->stashcount) + realbuffer->stashavail.signal(); + lock = 0; + } + } }; class conxiin { @@ -339,8 +360,7 @@ class conxion { return this; #endif } - stashcount++; - return bufcon(this); + return bufcon(this)->start(); } private int write_cb() { @@ -517,10 +537,10 @@ outer: catch(fd=socket->query_fd()); res=predef::sprintf("conxion fd: %d input queue: %d/%d " "queued portals: %d output queue: %d/%d\n" - "started: %d\n", + "started: %d stashcount: %d\n", fd,sizeof(i),i->_size_object(), qportals && qportals->size(), sizeof(this), _size_object(), - !!started); + !!started, stashcount); break; } return res;