pike.git
/
lib
/
modules
/
Sql.pmod
/
pgsql_util.pmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:78:
#else #define MUTEX Thread.Mutex #endif //! The instance of the pgsql dedicated backend. final Pike.Backend local_backend; private Pike.Backend cb_backend; private Result qalreadyprinted; private Thread.Mutex backendmux = Thread.Mutex();
-
private
Thread.ResourceCount
clientsregistered
=
Thread.ResourceCount
();
+
final
multiset(proxy)
clients
=
set_weak_flag
(
(<>
)
, Pike.WEAK)
;
constant emptyarray = ({}); constant describenodata = (["datarowdesc":emptyarray, "datarowtypes":emptyarray, "datatypeoid":emptyarray]); private constant censoroptions = (<"use_ssl", "force_ssl", "cache_autoprepared_statements", "reconnect", "text_query", "is_superuser", "server_encoding", "server_version", "integer_datetimes", "session_authorization">);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:141:
* tradeoff. */ private Regexp execfetchlimit = iregexp("^\a*((UPDA|DELE)TE|INSERT)\a|\aLIMIT\a+[1-9][; \t\f\r\n]*$"); private void default_backend_runs() { // Runs as soon as the cb_backend = Pike.DefaultBackend; // DefaultBackend has started } private void create() {
+
atexit(_destruct);
// Run callbacks from our local_backend until DefaultBackend has started cb_backend = local_backend = Pike.SmallBackend(); call_out(default_backend_runs, 0); }
-
+
private void _destruct() {
+
foreach (clients; proxy client; )
+
destruct(client);
+
}
+
private Regexp iregexp(string expr) { Stdio.Buffer ret = Stdio.Buffer(); foreach (expr; ; int c) if (c >= 'A' && c <= 'Z') ret->add('[', c, c + 'a' - 'A', ']'); else if (c == '\a') // Replace with generic whitespace ret->add("[ \t\f\r\n]"); else ret->add_int8(c); return Regexp(ret->read());
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:172:
} } private void run_local_backend() { Thread.MutexKey lock; int looponce; do { looponce = 0; if (lock = backendmux->trylock()) { PD("Starting local backend\n");
-
while (
!clientsregistered->drained
() // Autoterminate when not needed
+
while (
sizeof
(
clients
)
// Autoterminate when not needed
|| sizeof(local_backend->call_out_info())) { mixed err; if (err = catch(local_backend(4096.0))) master()->handle_error(err); } PD("Terminating local backend\n"); lock = 0;
-
looponce =
!clientsregistered->drained
();
+
looponce =
sizeof
(
clients
);
} } while (looponce); } //! Registers yourself as a user of this backend. If the backend //! has not been started yet, it will be spawned automatically.
-
final
Thread.ResourceCountKey
register_backend() {
-
int startbackend =
clientsregistered->drained
();
-
Thread.ResourceCountKey
key
=
clientsregistered->acquire()
;
+
final
void
register_backend(
proxy client
) {
+
int startbackend =
!sizeof
(
clients
);
+
clients[client]
=
1
;
if (startbackend) Thread.Thread(run_local_backend);
-
return key;
+
} final void throwdelayederror(Result|proxy parent) { if (mixed err = parent->delayederror) { if (!objectp(parent->pgsqlsess)) parent->untolderror = 0; else if (parent->pgsqlsess) parent->pgsqlsess->untolderror = 0; parent.delayederror = 0; if (stringp(err))
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1893:
Thread.Thread(run_result_array_cb, callback, args); } }; class proxy { final int _fetchlimit = FETCHLIMIT; final MUTEX unnamedportalmux; final MUTEX unnamedstatement; private Thread.MutexKey termlock;
-
private Thread.ResourceCountKey backendreg;
+
final Thread.ResourceCount portalsinflight, statementsinflight; final int(0..1) wasparallelisable; final int(0..1) intransaction; final conxion c; private string cancelsecret; private int backendpid; final int(-128..127) backendstatus; final mapping(string:mixed) options; private array(string) lastmessage = emptyarray;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1958:
this::database = database; this::options = options; if (!host) host = PGSQL_DEFAULT_HOST; if (has_value(host,":") && sscanf(host,"%s:%d", host, port) != 2) error("Error in parsing the hostname argument\n"); this::host = host; if (!port) port = PGSQL_DEFAULT_PORT;
-
backendreg =
register_backend();
+
register_backend(
this
);
shortmux = MUTEX(); PD("Connect\n"); waitforauthready = Thread.Condition(); qportals = Thread.Queue(); readyforquerycount = 1; qportals->write(1); if (!(c = conxion(this, qportals, 0))) error("Couldn't connect to database on %s:%d\n", host, port); runtimeparameter = ([]); unnamedportalmux = MUTEX();
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2719:
break; case NOERROR: continue; // Normal production loop } error(a2nls(lastmessage += ({msg}))); } }; // We only get here if there is an error if (err == MAGICTERMINATE) { // Announce connection termination to server catch { void|bufcon|conxsess cs = ci->start();
-
CHAIN(cs)->add("X\0\0\0\4");
+
CHAIN(cs)->add(
PGSYNC)->add(
"X\0\0\0\4");
cs->sendcmd(SENDOUT); }; terminating = 1; err = 0; } else if (stringp(err)) { Result or; if (!objectp(or = portal)) or = this; if (!or.delayederror) or.delayederror = err;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2787:
lock = unnamedstatement->lock(1); if (c) c->purge(); } destruct(waitforauthready); } private void _destruct() { string errstring; mixed err = catch(close());
-
backendreg
= 0;
+
clients[this]
= 0;
if (untolderror) { /* * Flush out any asynchronously reported errors to stderr; because we are * inside a destructor, throwing an error will not work anymore. * Warnings will be silently discarded at this point. */ lastmessage = filter(lastmessage, lambda(string val) { return has_prefix(val, "ERROR ") || has_prefix(val, "FATAL "); }); if (err || (err = catch(errstring = geterror(1)))) werror(describe_backtrace(err));