pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:18:
#include "pgsql.h"
//! The instance of the pgsql dedicated backend.
final Pike.Backend local_backend = Pike.SmallBackend();
private Thread.Mutex backendmux = Thread.Mutex();
private int clientsregistered;
constant emptyarray = ({});
+ constant describenodata
+ = (["datarowdesc":emptyarray,"datarowtypes":emptyarray]);
final multiset censoroptions=(<"use_ssl","force_ssl",
"cache_autoprepared_statements","reconnect","text_query","is_superuser",
"server_encoding","server_version","integer_datetimes",
"session_authorization">);
/* Statements matching createprefix cause the prepared statement cache
* to be flushed to prevent stale references to (temporary) tables
*/
final Regexp createprefix=iregexp("^\a*(CREATE|DROP)\a");
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:185: Inside #if defined(PG_DEBUG)
realbuffer->stashcount++;
#ifdef PG_DEBUG
if(waitforreal)
error("pgsql.bufcon not allowed here\n");
#endif
return this;
}
final void sendcmd(int mode,void|sql_result portal) {
Thread.MutexKey lock=realbuffer->shortmux->lock();
- if(portal)
+ if(portal) {
realbuffer->stashqueue->write(portal);
-
+ if (mode == SYNCSEND) {
+ add(PGSYNC);
+ realbuffer->stashqueue->write(1);
+ mode = SENDOUT;
+ }
+ }
realbuffer->stash->add(this);
- mode=mergemode(realbuffer,mode);
+ mergemode(realbuffer, mode);
if(!--realbuffer->stashcount)
realbuffer->stashavail.signal();
lock=0;
this->clear();
if(lock=realbuffer->nostash->trylock(1)) {
#ifdef PG_DEBUGRACE
conxsess sess = conxsess(realbuffer);
realbuffer->started = lock;
lock = 0;
sess->sendcmd(SENDOUT);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:292:
private inline void queueup(sql_result portal) {
qportals->write(portal); portal->_synctransact=synctransact;
PD("%d>%O %d %d Queue portal %d bytes\n",socket->query_fd(),
portal._portalname,++queueoutidx,synctransact,sizeof(this));
}
final bufcon|conxsess start(void|int waitforreal) {
Thread.MutexKey lock;
if(lock=(waitforreal?nostash->lock:nostash->trylock)(1)) {
+ int mode;
#ifdef PG_DEBUGRACE
conxsess sess = conxsess(this);
#endif
started = lock;
lock=shortmux->lock();
if(stashcount)
PT(stashavail.wait(lock));
- add(stash); stash->clear();
- foreach(stashqueue->try_read_array();;sql_result portal)
- queueup(portal);
+ mode = getstash(KEEP);
lock=0;
-
+ if (mode > KEEP)
+ sendcmd(mode); // Force out stash to the server
#ifdef PG_DEBUGRACE
return sess;
#else
return this;
#endif
}
stashcount++;
return bufcon(this);
}
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:324:
Thread.MutexKey lock = shortmux->lock();
if (this) { // Guard against async destructs
towrite -= output_to(socket, towrite);
lock = 0;
if (!i->fillread && !sizeof(this))
close();
}
return 0;
}
- final void sendcmd(void|int mode, void|sql_result portal) {
- Thread.MutexKey lock;
-
- int emptystash() {
- int ret = 0;
- if (started) {
- lock = shortmux->lock();
+ private int getstash(int mode) {
if (sizeof(stash)) {
- add(stash);
- stash->clear();
- foreach (stashqueue->try_read_array();; sql_result portal)
+ add(stash); stash->clear();
+ foreach (stashqueue->try_read_array();; int|sql_result portal)
+ if (intp(portal))
+ qportals->write(synctransact++);
+ else
queueup(portal);
- ret = 1;
- }
+
mode = mergemode(this, mode);
stashflushmode = KEEP;
}
- return ret;
- };
+ return mode;
+ }
- emptystash();
- do {
+ final void sendcmd(void|int mode, void|sql_result portal) {
+ Thread.MutexKey lock;
if (portal)
queueup(portal);
-
+ unfinalised:
+ do {
switch (mode) {
default:
- continue;
+ break unfinalised;
case SYNCSEND:
PD("%d>Sync %d %d Queue\n",
socket->query_fd(), synctransact, ++queueoutidx);
add(PGSYNC);
mode = SENDOUT;
break;
case FLUSHLOGSEND:
- PD("%d>%O %d Queue simplequery %d bytes\n",
- socket->query_fd(), portal._portalname, ++queueoutidx, sizeof(this));
+ PD("%d>%O %d Queue simplequery %d bytes\n", socket->query_fd(),
+ portal._portalname, ++queueoutidx, sizeof(this));
mode = FLUSHSEND;
}
qportals->write(synctransact++);
- } while (!lock && emptystash());
+ } while(0);
+ lock = shortmux->lock();
+ mode = getstash(mode);
catch {
outer:
do {
switch(mode) {
default:
PD("%d>Skip flush %d Queue %O\n",
socket->query_fd(), mode, (string)this);
break outer;
-
+ case FLUSHLOGSEND:
case FLUSHSEND:
PD("Flush\n");
add(PGFLUSH);
-
+ case SYNCSEND:
case SENDOUT:;
}
- if(!lock)
- lock=shortmux->lock();
+
if(towrite=sizeof(this)) {
PD("%d>Sendcmd %O\n",socket->query_fd(),((string)this)[..towrite-1]);
towrite-=output_to(socket,towrite);
}
} while(0);
lock=started=0;
return;
};
lock=0;
catch(connectfail());
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1157:
}
protected void destroy() {
catch { // inside destructors, exceptions don't work
_releasesession();
};
}
final void _sendexecute(int fetchlimit,void|bufcon|conxsess plugbuffer) {
int flushmode;
- PD("Execute portal %O fetchlimit %d\n",_portalname,fetchlimit);
+ PD("Execute portal %O fetchlimit %d transtype %d\n", _portalname,
+ fetchlimit, transtype);
if(!plugbuffer)
plugbuffer=c->start(1);
CHAIN(plugbuffer)->add_int8('E')->add_hstring(({_portalname,0}), 4, 8)
->add_int32(fetchlimit);
if (!fetchlimit) {
if (transtype != NOTRANS)
pgsqlsess._intransaction = transtype == TRANSBEGIN;
flushmode = _closeportal(plugbuffer) == SYNCSEND
|| transtype == TRANSEND ? SYNCSEND : FLUSHSEND;
} else