Branch: Tag:

2018-05-22

2018-05-22 12:03:34 by Stephen R. van den Berg <srb@cuci.nl>

pgsql: Disentangle concurrent stash flushes explicitly.

- Solves the last remaining one-deadlock-per-month problem.
- Speeds up the critical path with regard to stash-flushing.

320:    realbuffer->socket->query_fd(), mode, realbuffer->stashflushmode);    if (mode > realbuffer->stashflushmode)    realbuffer->stashflushmode = mode; +  lock = 0;    dirty = 0;    this->clear();    if (lock = realbuffer->nostash->trylock(1)) {
475:   #endif    started = lock;    lock = 0; // Force release before acquiring next -  lock = shortmux->lock(); -  mode = getstash(KEEP); -  lock = 0; -  if (mode > KEEP) +  if (sizeof(stash) && getstash(KEEP) > KEEP)    sendcmd(mode); // Force out stash to the server   #ifdef PG_DEBUGRACE    return sess;
501:    }       private int getstash(int mode) { -  if (sizeof(stash)) { +  Thread.MutexKey lock = shortmux->lock();    add(stash); stash->clear();    foreach (stashqueue->try_read_array(); ; int|sql_result portal)    if (intp(portal))
513:    if (stashflushmode > mode)    mode = stashflushmode;    stashflushmode = KEEP; -  } +     return mode;    }   
538:    }    qportals->write(synctransact++);    } while (0); -  Thread.MutexKey lock = shortmux->lock(); +  if (sizeof(stash))    mode = getstash(mode); -  +  for(;;) {   #ifdef PG_DEBUG    mixed err =   #endif
563:    }    } while (0);    started = 0; +  if (sizeof(stash) && (started = nostash->trylock(1))) { + #ifdef PG_DEBUGRACE +  conxsess sess = conxsess(this); +  sess->sendcmd(SENDOUT); + #else +  mode = getstash(SENDOUT); +  continue; + #endif +  }    return;    }; -  lock = 0; +  break; +  } +  started = 0;    PD("Sendcmd failed %s\n", describe_backtrace(err));    destruct(this);    }