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

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:135:    if(mode>realbuffer->stashflushmode)    realbuffer->stashflushmode=mode;    return realbuffer->stashflushmode;   }      private inline mixed callout(function(mixed ...:void) f,    float|int delay,mixed ... args) {    return local_backend->call_out(f,delay,@args);   }    - private void nop() { } -  +    // Some pgsql utility functions      class bufcon {    inherit Stdio.Buffer;       private conxion realbuffer;       protected void create(conxion _realbuffer) {    realbuffer=_realbuffer;    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:180:    }    }      };      class conxiin {    inherit Stdio.Buffer:i;       final Thread.Condition fillread;    final Thread.Mutex fillreadmux; -  final function(:void) gottimeout; -  final int timeout; +     private int didreadcb;       protected bool range_error(int howmuch) {   #ifdef PG_DEBUG    if(howmuch<=0)    error("Out of range %d\n",howmuch);   #endif    if(fillread) { -  array cid=callout(gottimeout,timeout); +     Thread.MutexKey lock=fillreadmux->lock();    if(!didreadcb)    fillread.wait(lock);    didreadcb=0;    lock=0; -  local_backend->remove_call_out(cid); +     } else    throw(MAGICTERMINATE);    return true;    }       final int read_cb(mixed id,mixed b) {    Thread.MutexKey lock=fillreadmux->lock();    if(fillread)    didreadcb=1, fillread.signal();    lock=0;    return 0;    }       protected void create() {    i::create(); -  gottimeout=nop; // Preset it with a NOP -  timeout=128; // Just a reasonable amount +     fillreadmux=Thread.Mutex();    fillread=Thread.Condition();    }   };      class conxion {    inherit Stdio.Buffer:o;    final conxiin i;       private Thread.Queue qportals;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:465:    private string statuscmdcomplete;    private int bytesreceived;    final int _synctransact;    final Thread.Condition _ddescribe;    final Thread.Mutex _ddescribemux;    final Thread.MutexKey _unnamedportalkey,_unnamedstatementkey;    final array _params;    final string _query;    final string _preparedname;    final mapping(string:mixed) _tprepared; +  private function(:void) gottimeout; +  private int timeout;       private string _sprintf(int type, void|mapping flags) {    string res=UNDEFINED;    switch(type) {    case 'O':    res=sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n"    "query: %O\n"    "fd: %O portalname: %O datarows: %d"    " laststatus: %s\n",    _state,rowsreceived,eoffound,inflight,    _query,c&&c->socket?->query_fd(),    _portalname,datarowtypes&&sizeof(datarowtypes),    statuscmdcomplete||(_unnamedstatementkey?"*parsing*":""));    break;    }    return res;    }       protected void create(object _pgsqlsess,conxion _c,string query, -  int _portalbuffersize,int alltyped,array params,int forcetext) { +  int _portalbuffersize,int alltyped,array params,int forcetext, +  int _timeout) {    pgsqlsess = _pgsqlsess;    cr = (c = _c)->i;    _query = query;    datarows = Thread.Queue();    _ddescribe=Thread.Condition();    _ddescribemux=Thread.Mutex();    closemux=Thread.Mutex();    portalbuffersize=_portalbuffersize;    alltext = !alltyped;    _params = params;    _forcetext = forcetext;    _state = PORTALINIT; -  +  timeout = _timeout; +  gottimeout = _pgsqlsess->cancelquery;    }       //! Returns the command-complete status for this query.    //!    //! @seealso    //! @[affected_rows()]    //!    //! @note    //! This function is PostgreSQL-specific, and thus it is not available    //! through the generic SQL-interface.
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1004:    //! When using COPY FROM STDOUT, this method returns one row at a time    //! as a single string containing the entire row.    //!    //! @seealso    //! @[eof()], @[send_row()]    /*semi*/final array(mixed) fetch_row() {    int|array datarow;    if(arrayp(datarow=datarows->try_read()))    return datarow;    if(!eoffound) { -  if(!datarow -  && (PD("%O Block for datarow\n",_portalname), -  arrayp(datarow=datarows->read()))) +  if(!datarow) { +  PD("%O Block for datarow\n",_portalname); +  array cid=callout(gottimeout,timeout); +  datarow=datarows->read(); +  local_backend->remove_call_out(cid); +  if(arrayp(datarow))    return datarow; -  +  }    eoffound=1;    datarows->write(1); // Signal EOF for other threads    }    trydelayederror();    return 0;    }       //! @returns    //! Multiple result rows at a time (at least one).    //!    //! When using COPY FROM STDOUT, this method returns one row at a time    //! as a single string containing the entire row.    //!    //! @seealso    //! @[eof()], @[fetch_row()]    /*semi*/final array(array(mixed)) fetch_row_array() {    if(eoffound)    return 0;    array(array|int) datarow=datarows->try_read_array(); -  if(!datarow) +  if(!datarow) { +  array cid=callout(gottimeout,timeout);    datarow=datarows->read_array(); -  +  local_backend->remove_call_out(cid); +  }    if(arrayp(datarow[-1]))    return datarow;    trydelayederror();    eoffound=1;    datarows->write(1); // Signal EOF for other threads    return (datarow=datarow[..<1]);    }       //! @param copydata    //! When using COPY FROM STDIN, this method accepts a string or an
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1062:    PD("CopyData\n");    c->start()->add_int8('d')->add_hstring(copydata,4,4)->sendcmd(SENDOUT);    } else    _releasesession();    }       private void run_result_cb(    function(sql_result, array(mixed), mixed ...:void) callback,    array(mixed) args) {    int|array datarow; -  while(arrayp(datarow=datarows->read_array())) +  for(;;) { +  array cid=callout(gottimeout,timeout); +  datarow=datarows->read(); +  local_backend->remove_call_out(cid); +  if(!arrayp(datarow)) +  break;    callout(callback, 0, this, datarow, @args); -  +  }    trydelayederror();    eoffound=1;    callout(callback, 0, this, 0, @args);    }       //! Sets up a callback for every row returned from the database.    //! First argument passed is the resultobject itself, second argument    //! is the result row (zero on EOF).    //!    //! @seealso
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1086:    function(sql_result, array(mixed), mixed ...:void) callback,    mixed ... args) {    if(callback)    Thread.Thread(run_result_cb,callback,args);    }       private void run_result_array_cb(    function(sql_result, array(array(mixed)), mixed ...:void) callback,    array(mixed) args) {    array(array|int) datarow; -  while((datarow=datarows->read_array()) && arrayp(datarow[-1])) +  for(;;) { +  array cid=callout(gottimeout,timeout); +  datarow=datarows->read_array(); +  local_backend->remove_call_out(cid); +  if(!datarow || !arrayp(datarow[-1])) +  break;    callout(callback, 0, this, datarow, @args); -  +  }    trydelayederror();    eoffound=1;    if(sizeof(datarow)>1)    callout(callback, 0, this, datarow=datarow[..<1], @args);    callout(callback, 0, this, 0, @args);    }       //! Sets up a callback for sets of rows returned from the database.    //! First argument passed is the resultobject itself, second argument    //! is the array of result rows (zero on EOF).