Branch: Tag:

2018-12-16

2018-12-16 12:26:08 by Stephen R. van den Berg <srb@cuci.nl>

pgsql: Autoterminate dangling database connections at program exit.

84:   private Pike.Backend cb_backend;   private sql_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
147:   }      private void create() { +  atexit(destroy);    // Run callbacks from our local_backend until DefaultBackend has started    cb_backend = local_backend = Pike.SmallBackend();    call_out(default_backend_runs, 0);   }    -  + private void destroy() { +  foreach (clients; proxy client; ) +  destruct(client); + } +    private Regexp iregexp(string expr) {    Stdio.Buffer ret = Stdio.Buffer();    foreach (expr; ; int c)
178:    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)))
186:    }    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(sql_result|proxy parent) {
1718:    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;
1783:       if (!port)    port = PGSQL_DEFAULT_PORT; -  backendreg = register_backend(); +  register_backend(this);    shortmux = MUTEX();    PD("Connect\n");    waitforauthready = Thread.Condition();
2544:    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;
2612:    private void destroy() {    string errstring;    mixed err = catch(close()); -  backendreg = 0; +  clients[this] = 0;    if (untolderror) {    /*    * Flush out any asynchronously reported errors to stderr; because we are