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

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:514:    portal._portalname, ++queueoutidx, synctransact, sizeof(this));    }       final bufcon|conxsess start(void|int waitforreal) {    Thread.MutexKey lock;   #ifdef PG_DEBUGRACE    if (nostash->current_locking_thread())    PD("Nostash locked by %s\n",    describe_backtrace(nostash->current_locking_thread()->backtrace()));   #endif -  while (lock = (waitforreal ? nostash->lock : nostash->trylock)(1)) { +  while (lock = (waitforreal > 0 ? nostash->lock : nostash->trylock)(1)) {    int mode;    if (sizeof(stash) && (mode = getstash(KEEP)) > KEEP)    sendcmd(mode); // Force out stash to the server    if (!stashcount->drained()) {    lock = 0; // Unlock while we wait    stashcount->wait_till_drained();    continue; // Try again    }   #ifdef PG_DEBUGRACE    conxsess sess = conxsess(this);   #endif    started = lock; // sendcmd() clears started, so delay assignment   #ifdef PG_DEBUGRACE    return sess;   #else    return this;   #endif    } -  return bufcon(this)->start(); +  return !waitforreal && bufcon(this)->start();    }       private int write_cb() {    Thread.MutexKey lock = shortmux->lock();    if (this) { // Guard against async destructs    towrite -= output_to(socket, towrite);    lock = 0;    if (!i->fillread && !sizeof(this))    close();    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:933:    //!    //! @seealso    //! @[Sql.Result()->status_command_complete()]    /*semi*/final string status_command_complete() {    if (!statuscmdcomplete) {    if (!datarowtypes)    waitfordescribe();    {    Thread.MutexKey lock = closemux->lock();    if (_fetchlimit) { -  array reflock = ({ lock }); +  array reflock = ({ _fetchlimit = 0 }); +  for (;;) { +  reflock[0] = lock;    lock = 0; -  _sendexecute(_fetchlimit = 0, reflock); +  if (!_sendexecute(0, reflock)) { +  lock = closemux->lock(); +  continue; +  } +  }    } else    lock = 0; // Force release before acquiring next    lock = _ddescribemux->lock();    if (!statuscmdcomplete)    PT(_ddescribe->wait(lock));    }    if (this) // If object already destructed, skip the next call    trydelayederror(); // since you cannot call functions anymore    else    error(LOSTERROR);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1642:    pgsqlsess->readyforquerycount++, retval = SYNCSEND;    pgsqlsess->pportalcount = 0;    }    }    return retval;    }       private void replenishrows() {    if (_fetchlimit && datarows->size() <= _fetchlimit >> 1    && _state >= COMMITTED) { -  Thread.MutexKey lock = closemux->lock(); +  Thread.MutexKey lock; +  for (;;) { +  lock = closemux->lock();    if (_fetchlimit) {    _fetchlimit = pgsqlsess._fetchlimit;    if (bytesreceived) -  _fetchlimit = -  min((portalbuffersize >> 1) * index / bytesreceived || 1, _fetchlimit); +  _fetchlimit = min((portalbuffersize >> 1) +  * index / bytesreceived || 1, _fetchlimit);    if (_fetchlimit)    if (inflight <= (_fetchlimit - 1) >> 1) {    array reflock = ({ lock });    lock = 0; -  _sendexecute(_fetchlimit, reflock); +  if (!_sendexecute(_fetchlimit, reflock)) +  continue;    } else    PD("<%O _fetchlimit %d, inflight %d, skip execute\n",    _portalname, _fetchlimit, inflight);    } -  +  break;    }    } -  +  }       final void _processdataready(array datarow, void|int msglen) {    bytesreceived += msglen;    inflight--;    if (_state < CLOSED)    datarows->write(datarow);    if (++index == 1)    PD("<%O _fetchlimit %d=min(%d||1,%d), inflight %d\n", _portalname,    _fetchlimit, (portalbuffersize >> 1) * index / bytesreceived,    pgsqlsess._fetchlimit, inflight);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1697:    if (statusccomplete && !statuscmdcomplete) {    Thread.MutexKey lock = _ddescribemux->lock();    statuscmdcomplete = statusccomplete;    _ddescribe->broadcast();    }    inflight = 0;    conxsess plugbuffer;    array(Thread.MutexKey) reflock = ({closemux->lock()});    if (!catch(plugbuffer = c->start()))    plugbuffer->sendcmd(_closeportal(plugbuffer, reflock)); -  reflock = 0; +  reflock[0] = 0;    if (_state < CLOSED) {    stmtifkey = 0;    _state = CLOSED;    }    datarows->write(1); // Signal EOF    releaseconditions();    }       protected void _destruct() {    catch { // inside destructors, exceptions don't work    _releasesession("ABORT");    };    }    -  final void _sendexecute(int fetchlimit, +  final int _sendexecute(int fetchlimit,    void|array(Thread.MutexKey)|bufcon|conxsess plugbuffer) {    int flushmode;    array(Thread.MutexKey) reflock;    PD("Execute portal %O fetchlimit %d transtype %d\n", _portalname,    fetchlimit, transtype);    if (arrayp(plugbuffer)) {    reflock = plugbuffer; -  plugbuffer = c->start(1); +  if (!(plugbuffer = c->start(-1))) { +  reflock[0] = 0; +  return 0; // Found potential deadlock, release and try again    } -  +  }    CHAIN(plugbuffer)->add_int8('E')->add_hstring(({_portalname, 0}), 4, 8)    ->add_int32(fetchlimit);    if (!fetchlimit) {    if (transtype != NOTRANS)    pgsqlsess.intransaction = transtype == TRANSBEGIN;    flushmode = _closeportal(plugbuffer, reflock) == SYNCSEND    || transtype == TRANSEND ? SYNCSEND : FLUSHSEND;    } else    inflight += fetchlimit, flushmode = FLUSHSEND;    plugbuffer->sendcmd(flushmode, this); -  +  if (reflock) +  reflock[0] = 0; +  return 1;    }       inline private array setuptimeout() {    return local_backend->call_out(gottimeout, timeout);    }       inline private void scuttletimeout(array cid) {    if (local_backend)    local_backend->remove_call_out(cid);    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1753:    //! @returns    //! One result row at a time.    //!    //! 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 (!this) // If object already destructed, return fast +  return 0;    replenishrows();    if (arrayp(datarow = datarows->try_read()))    return datarow;    if (!eoffound) {    if (!datarow) {    PD("%O Block for datarow\n", _portalname);    array cid = setuptimeout();    PT(datarow = datarows->read());    if (!this) // If object already destructed, return fast    return 0;