pike.git / lib / modules / Sql.pmod / pgsql_util.pmod

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:58:    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());   }    - final void closestatement(bufcon|conxion plugbuffer,string oldprep) { + final void closestatement(bufcon|conxsess plugbuffer,string oldprep) {    if(oldprep) {    PD("Close statement %s\n",oldprep); -  plugbuffer->add_int8('C')->add_hstring(({'S',oldprep,0}),4,4); +  CHAIN(plugbuffer)->add_int8('C')->add_hstring(({'S', oldprep, 0}), 4, 4);    }   }      private void run_local_backend() {    Thread.MutexKey lock;    int looponce;    do {    looponce=0;    if(lock=backendmux->trylock()) {    PD("Starting local backend\n");
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:143:   private inline mixed callout(function(mixed ...:void) f,    float|int delay,mixed ... args) {    return local_backend->call_out(f,delay,@args);   }      // Some pgsql utility functions      class bufcon {    inherit Stdio.Buffer;    + #ifdef PG_DEBUGRACE +  final bufcon `chain() { +  return this; +  } + #endif +     private conxion realbuffer;       protected void create(conxion _realbuffer) {    realbuffer=_realbuffer;    }       final int `stashcount() {    return realbuffer->stashcount;    }   
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:173:    Thread.MutexKey lock=realbuffer->shortmux->lock();    if(portal)    realbuffer->stashqueue->write(portal);    realbuffer->stash->add(this);    mode=mergemode(realbuffer,mode);    if(!--realbuffer->stashcount)    realbuffer->stashavail.signal();    lock=0;    this->clear();    if(lock=realbuffer->nostash->trylock(1)) { -  realbuffer->started=lock; lock=0; + #ifdef PG_DEBUGRACE +  conxsess sess = conxsess(realbuffer); +  realbuffer->started = lock; +  lock = 0; +  sess->sendcmd(SENDOUT); + #else +  realbuffer->started = lock; +  lock = 0;    realbuffer->sendcmd(SENDOUT); -  + #endif    }    } -  +    };      class conxiin {    inherit Stdio.Buffer:i;       final Thread.Condition fillread;    final Thread.Mutex fillreadmux;    final int procmsg;    private int didreadcb;   
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:247:    final multiset(function(void|mixed:void)) closecallbacks=(<>);       final Thread.Mutex nostash;    final Thread.MutexKey started;    final Thread.Queue stashqueue;    final Thread.Condition stashavail;    final Stdio.Buffer stash;    final int stashflushmode;    final int stashcount;    final int synctransact; + #ifdef PG_DEBUGRACE +  final mixed nostrack; + #endif   #ifdef PG_DEBUG    final int queueoutidx;    final int queueinidx=-1;   #endif       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 conxion|bufcon start(void|int waitforreal) { +  final bufcon|conxsess start(void|int waitforreal) {    Thread.MutexKey lock;    if(lock=(waitforreal?nostash->lock:nostash->trylock)(1)) { -  started=lock; + #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);    lock=0; -  + #ifdef PG_DEBUGRACE +  return sess; + #else    return this; -  + #endif    }    stashcount++;    return bufcon(this);    }       private int write_cb() {    Thread.MutexKey lock = shortmux->lock();    if (this) { // Guard against async destructs    towrite -= output_to(socket, towrite);    lock = 0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:441:    }       private string _sprintf(int type, void|mapping flags) {    string res=UNDEFINED;    switch(type) {    case 'O':    int fd=-1;    if(socket)    catch(fd=socket->query_fd());    res=predef::sprintf("conxion fd: %d input queue: %d/%d " -  "queued portals: %d output queue: %d/%d\n", +  "queued portals: %d output queue: %d/%d\n" +  "started: %d\n",    fd,sizeof(i),i->_size_object(), -  qportals->size(),sizeof(this),_size_object()); +  qportals->size(),sizeof(this),_size_object(), +  !!started);    break;    }    return res;    }       protected void create(object pgsqlsess,Thread.Queue _qportals,int nossl) {    o::create();    qportals = _qportals;    synctransact = 1;    socket=Stdio.File();
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:465:    shortmux=Thread.Mutex();    nostash=Thread.Mutex();    closenext = 0;    stashavail=Thread.Condition();    stashqueue=Thread.Queue();    stash=Stdio.Buffer();    Thread.Thread(connectloop,pgsqlsess,nossl);    }   };    + #ifdef PG_DEBUGRACE + class conxsess { +  final conxion chain; +  +  void create(conxion parent) { +  if (parent->started) +  werror("Overwriting conxsess %s %s\n", +  describe_backtrace(({"new ", backtrace()[..<1]})), +  describe_backtrace(({"old ", parent->nostrack}))); +  parent->nostrack = backtrace(); +  chain = parent; +  } +  +  final void sendcmd(int mode,void|sql_result portal) { +  chain->sendcmd(mode, portal); +  chain = 0; +  } +  +  void destroy() { +  if (chain) +  werror("Untransmitted conxsess %s\n", +  describe_backtrace(({"", backtrace()[..<1]}))); +  } + }; + #endif +    //! The result object returned by @[Sql.pgsql()->big_query()], except for   //! the noted differences it behaves the same as @[Sql.sql_result].   //!   //! @seealso   //! @[Sql.sql_result], @[Sql.pgsql], @[Sql.Sql], @[Sql.pgsql()->big_query()]   class sql_result {       private object pgsqlsess;    private int eoffound;    private conxion c;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:882:    pgsqlsess->_waittocommit++;    PD("Commit waiting for portals to finish\n");    catch(PT(pgsqlsess->_readyforcommit->wait(lock)));    pgsqlsess->_waittocommit--;    }    }    lock=0;    PD("Bind portal %O statement %O\n",_portalname,_preparedname);    _fetchlimit=pgsqlsess->_fetchlimit;    _openportal(); -  conxion bindbuffer=c->start(); +  conxsess bindbuffer = c->start();    _unnamedstatementkey=0; -  bindbuffer->add_int8('B')->add_hstring(plugbuffer,4,4); +  CHAIN(bindbuffer)->add_int8('B')->add_hstring(plugbuffer, 4, 4);    if(!_tprepared && sizeof(_preparedname)) -  closestatement(bindbuffer,_preparedname); +  closestatement(CHAIN(bindbuffer), _preparedname);    _sendexecute(_fetchlimit    && !(cachealways[_query]    || sizeof(_query)>=MINPREPARELENGTH &&    execfetchlimit->match(_query))    && _fetchlimit,bindbuffer);    }    } else    lock=0;    }   
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:928:    switch(_state) {    case COPYINPROGRESS:    case BOUND:    --pgsqlsess->_portalsinflight;    }    _state=CLOSED;    lock=0;    releaseconditions();    }    -  final int _closeportal(bufcon plugbuffer) { +  final int _closeportal(conxsess cs) { +  object plugbuffer = CHAIN(cs);    int retval=KEEP;    PD("%O Try Closeportal %d\n",_portalname,_state);    Thread.MutexKey lock=closemux->lock();    _fetchlimit=0; // disables further Executes    switch(_state) {    case PORTALINIT:    _unnamedstatementkey=0;    _state=CLOSING;    break;    case COPYINPROGRESS:
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1011:    _ddescribe->broadcast();    lock=0;    }    }       final void _releasesession(void|string statusccomplete) {    c->closecallbacks-=(<destroy>);    if(statusccomplete && !statuscmdcomplete)    statuscmdcomplete=statusccomplete;    inflight=0; -  catch { -  conxion plugbuffer=c->start(); +  conxsess plugbuffer; +  if (!catch(plugbuffer = c->start()))    plugbuffer->sendcmd(_closeportal(plugbuffer)); -  }; +     _state=CLOSED;    datarows->write(1); // Signal EOF    releaseconditions();    }       protected void destroy() {    catch { // inside destructors, exceptions don't work    _releasesession();    };    }    -  final void _sendexecute(int fetchlimit,void|bufcon plugbuffer) { +  final void _sendexecute(int fetchlimit,void|bufcon|conxsess plugbuffer) {    int flushmode;    PD("Execute portal %O fetchlimit %d\n",_portalname,fetchlimit);    if(!plugbuffer)    plugbuffer=c->start(1); -  plugbuffer->add_int8('E')->add_hstring(({_portalname,0}),4,8) +  CHAIN(plugbuffer)->add_int8('E')->add_hstring(({_portalname,0}), 4, 8)    ->add_int32(fetchlimit);    if(!fetchlimit)    flushmode=_closeportal(plugbuffer)==SYNCSEND?SYNCSEND:FLUSHSEND;    else    inflight+=fetchlimit, flushmode=FLUSHSEND;    plugbuffer->sendcmd(flushmode,this);    }       //! @returns    //! One result row at a time.
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1109:    //! The COPY FROM STDIN sequence needs to be completed by either    //! explicitly or implicitly destroying the result object, or by passing no    //! argument to this method.    //!    //! @seealso    //! @[fetch_row()], @[eof()]    /*semi*/final void send_row(void|string|array(string) copydata) {    trydelayederror();    if(copydata) {    PD("CopyData\n"); -  c->start()->add_int8('d')->add_hstring(copydata,4,4)->sendcmd(SENDOUT); +  object cs = c->start(); +  CHAIN(cs)->add_int8('d')->add_hstring(copydata, 4, 4); +  cs->sendcmd(SENDOUT);    } else    _releasesession();    }       private void run_result_cb(    function(sql_result, array(mixed), mixed ...:void) callback,    array(mixed) args) {    int|array datarow;    for(;;) {    array cid=callout(gottimeout,timeout);