pike.git
/
lib
/
modules
/
Sql.pmod
/
pgsql.pike
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Sql.pmod/pgsql.pike:56:
#pike __REAL_VERSION__ #require constant(Thread.Thread) #include "pgsql.h" #define ERROR(X ...) predef::error(X) final int _fetchlimit=FETCHLIMIT; final Thread.Mutex _unnamedportalmux;
-
private Thread.Mutex unnamedstatement;
+
private Thread.Mutex unnamedstatement
,termthread
;
+
private Thread.MutexKey termlock;
final int _portalsinflight; private .pgsql_util.conxion c; private string cancelsecret; private int backendpid, backendstatus; final mapping(string:mixed) _options; private array(string) lastmessage=({}); private int clearmessage; private mapping(string:array(mixed)) notifylist=([]); final mapping(string:string) _runtimeparameter;
pike.git/lib/modules/Sql.pmod/pgsql.pike:590:
return .pgsql_util.local_backend->call_out(f,delay,@args); } private int|.pgsql_util.sql_result portal; // state information procmessage #ifdef PG_DEBUG private string datarowdebug; private int datarowdebugcount; #endif final void _processloop(.pgsql_util.conxion ci) {
-
if(!this) // Oops, current object already destructed
-
return;
+
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; { Stdio.Buffer plugbuffer=Stdio.Buffer()->add_int32(PG_PROTOCOL(3,0)); if(user) plugbuffer->add("user\0",user,0); if(database) plugbuffer->add("database\0",database,0); _options.reconnect=undefinedp(_options.reconnect) || _options.reconnect; foreach(_options-.pgsql_util.censoroptions; string name; mixed value) plugbuffer->add(name,0,(string)value,0); plugbuffer->add_int8(0); PD("%O\n",(string)plugbuffer); if(catch(ci->start()->add_hstring(plugbuffer,4,4)->sendcmd(SENDOUT))) {
-
if(this) // Only when not destructed yet
+
if(_options.reconnect) _connectfail(); else destruct(waitforauthready);
-
+
termlock=0;
return; } } // Do not flush at this point, PostgreSQL 9.4 disapproves procmessage(); } private void procmessage() {
-
if(!this) // Oops, current object already destructed
-
return;
+
int terminating=0; .pgsql_util.conxion ci=c; // cache value FIXME sensible? .pgsql_util.conxiin cr=ci->i; // cache value FIXME sensible? mixed err; #ifdef PG_DEBUG PD("Processloop\n"); void showportal(int msgtype) { if(objectp(portal)) PD("%d<%O %d %c switch portal\n",
pike.git/lib/modules/Sql.pmod/pgsql.pike:1172:
if(!or._delayederror) or._delayederror=err; if(objectp(portal)) portal->_releasesession(); portal=0; if(!waitforauthready) continue; // Only continue if authentication did not fail } break; }
-
if(!this) { // Already destructed
-
ci->close(); // So close descriptors only
-
return;
-
}
+
PD("Closing database processloop %O\n",err);
-
catch { // Cater for destruct races
+
_delayederror=err; for(;objectp(portal);portal=qportals->read()) if(objectp(portal)) { #ifdef PG_DEBUG showportal(0); #endif portal->_purgeportal(); } if(!ci->close() && !terminating && _options.reconnect) _connectfail(); else destruct(waitforauthready);
-
}
;
+
termlock=0
;
if(err && !stringp(err)) throw(err); } //! Closes the connection to the database, any running queries are //! terminated instantly. //! //! @note //! This function is PostgreSQL-specific, and thus it is not available //! through the generic SQL-interface. /*semi*/final void close() { if(qportals && qportals->size()) catch(cancelquery());
-
catch(
c->close()
)
;
+
c->close();
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) { PD("Connect failed %O reconnectdelay %d\n",err,reconnectdelay); destruct(waitforauthready); if(!err || reconnectdelay) { int tdelay; switch(tdelay=reconnectdelay) { case 0: reconnectdelay=RECONNECTDELAY;