pike.git/
lib/
modules/
Sql.pmod/
pgsql_util.pmod
Branch:
Tag:
Non-build tags
All tags
No tags
2017-06-27
2017-06-27 10:30:15 by Stephen R. van den Berg <srb@cuci.nl>
b1fe665f3bfa5be45c4261195f9f27dcfa038b11 (
75
lines) (+
42
/-
33
)
[
Show
|
Annotate
]
Branch:
8.1
pgsql: Disentangle portal-sync race for concurrent db-errors.
26:
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",
193:
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;
300:
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
307:
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
332:
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);
366:
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 {
380:
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);
1167:
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)