diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike index b4b4d1697ca01e14203b83ebb698901ee7bdbfe9..b1e4bd2ba79b351a3c9fe5fad4c63f53f86ecbe1 100644 --- a/lib/modules/Sql.pmod/pgsql.pike +++ b/lib/modules/Sql.pmod/pgsql.pike @@ -316,7 +316,7 @@ private .pgsql_util.conxion getsocket(void|int nossl) { .pgsql_util.conxion lcon=getsocket(1); lcon->add_int32(16)->add_int32(PG_PROTOCOL(1234,5678)) ->add_int32(backendpid)->add(cancelsecret)->sendcmd(FLUSHSEND); - lcon->close(); + lcon=0; #ifdef PG_DEBUGMORE PD("Closetrace %O\n",backtrace()); #endif @@ -598,8 +598,6 @@ private int datarowdebugcount; #endif final void _processloop(.pgsql_util.conxion ci) { - if(c && (!ci || c!=ci)) // If we are switching or dropping connections - c->close(); // force a close on the old socket (c=ci)->socket->set_id(procmessage); cancelsecret=0; portal=0; @@ -1185,7 +1183,8 @@ private void procmessage() { #endif portal->_purgeportal(); } - if(!ci->close() && !terminating && _options.reconnect) + c=ci=0; + if(!terminating && _options.reconnect) _connectfail(); else destruct(waitforauthready); @@ -1203,16 +1202,16 @@ private void procmessage() { /*semi*/final void close() { if(qportals && qportals->size()) catch(cancelquery()); + termlock=(termthread=Thread.Mutex())->lock(); c->close(); + termthread->lock(1); c=0; destruct(waitforauthready); } protected void destroy() { - termlock=(termthread=Thread.Mutex())->lock(); catch(close()); .pgsql_util.unregister_backend(); - termthread->lock(1); } final void _connectfail(void|mixed err) { @@ -1261,7 +1260,9 @@ private int reconnect() { #ifdef PG_STATS prepstmtused=0; #endif + termlock=(termthread=Thread.Mutex())->lock(); c->close(); + termthread->lock(1); c=0; PD("Flushing old cache\n"); foreach(_prepareds;;mapping tp) diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod index 9fe6b5b2fac2d3a65617fd64e144c69efd5a7406..ce5b97cedb9e936fb9d84207c5e464830f53c813 100644 --- a/lib/modules/Sql.pmod/pgsql_util.pmod +++ b/lib/modules/Sql.pmod/pgsql_util.pmod @@ -228,8 +228,7 @@ class conxion { private Thread.Queue qportals; final Thread.Mutex shortmux; - private Thread.Mutex termthread; - private Thread.MutexKey termlock; + private int closenext; final Stdio.File socket; private function(void|mixed:void) connectfail; @@ -339,10 +338,9 @@ outer: } final int close() { - int ret; - if(!termlock && nostash) - { termlock=termthread->lock(); - Thread.MutexKey lock=i->fillreadmux->lock(); + int ret=0; + if(!closenext && nostash) + { Thread.MutexKey lock=i->fillreadmux->lock(); if(i->fillread) { // Delayed close() after flushing the output buffer i->fillread.signal(); i->fillread=0; @@ -350,22 +348,21 @@ outer: lock=0; PD("%d>Delayed close, flush write\n",socket->query_fd()); i->read_cb(socket->query_id(),0); - return ret; + closenext=1; + } else { + destruct(nostash); + PD("%d>Close socket\n",socket->query_fd()); + ret=socket->close(); + foreach(closecallbacks;function(void|mixed:void) closecb;) + closecb(); + closecallbacks=(<>); } - destruct(nostash); - PD("%d>Close socket\n",socket->query_fd()); - ret=socket->close(); - foreach(closecallbacks;function(void|mixed:void) closecb;) - closecb(); - closecallbacks=(<>); - termlock=0; return ret; } protected void destroy() { catch(close()); // Exceptions don't work inside destructors connectfail=0; - termthread->lock(1); } final void connectloop(object pgsqlsess, int nossl) { @@ -440,7 +437,7 @@ outer: i=conxiin(); shortmux=Thread.Mutex(); nostash=Thread.Mutex(); - termthread=Thread.Mutex(); + closenext = 0; stashavail=Thread.Condition(); stashqueue=Thread.Queue(); stash=Stdio.Buffer();