Branch: Tag:

2014-11-17

2014-11-17 15:33:02 by Stephen R. van den Berg <srb@cuci.nl>

pgsql: Eliminate prepbuffer race (signal before wait and duplicate entries).

549:    }       final void _setrowdesc(array(mapping(string:mixed)) datarowdesc) { -  _datarowdesc=datarowdesc; +     Thread.MutexKey lock=_ddescribemux->lock(); -  +  _datarowdesc=datarowdesc;    _ddescribe->broadcast();    lock=0;    }
684:    break;    }    } -  prepbuffer=plugbuffer; -  int skipsignal=0; +     if(_tprepared)    if(_tprepared.datarowdesc) -  skipsignal=1, gotdatarowdesc(); +  prepbuffer=plugbuffer, gotdatarowdesc();    else if(dontcacheprefix->match(_query)) // Don't cache FETCH/COPY    m_delete(pgsqlsess->_prepareds,_query),_tprepared=0; -  if(!skipsignal) { -  Thread.MutexKey lock=prepbuffermux->lock(); +  Thread.MutexKey lock; +  if(!prepbuffer && !catch(lock=prepbuffermux->lock())) { +  prepbuffer=plugbuffer;    prepbufferready->signal();    lock=0;    }
708:    }       private void gotdatarowdesc() { -  if(!prepbuffer) { -  Thread.MutexKey lock=prepbuffermux->lock(); +  Thread.MutexKey lock; +  if(catch(lock=prepbuffermux->lock())) +  return; +  if(!prepbuffer)    prepbufferready->wait(lock); -  +  destruct(prepbuffermux);    lock=0;    if(_state==CLOSED)    return; -  prepbuffermux=0; -  } +     Stdio.Buffer plugbuffer=prepbuffer; -  prepbuffer=0; +  prepbuffer=0; // Free memory early    plugbuffer->add_int16(sizeof(_datarowdesc));    if(sizeof(_datarowdesc))    foreach(_datarowdesc;;mapping col)
842:    }    if(!_datarowdesc) {    lock=_ddescribemux->lock(); -  _ddescribe->broadcast(); +     _datarowdesc=({}); -  +  _ddescribe->broadcast();    }    lock=0;    }