/*! Locks the monitor and/or increments lock counter; * throws EALREADY if the monitor is already locked */ void lock() { gu::Lock lock(mutex_); assert(locked_ >= 0); if (locked_ > 0) { log_warn << "Attempt to lock an already locked monitor."; locked_++; if (locked_ > 0) { gu_throw_error(EALREADY); } else { gu_throw_fatal << "More than " << (locked_ - 1) << " concurrent locks."; } } if (last_entered_ != -1) { while (drain_seqno_ != LLONG_MAX) lock.wait(cond_); /*! @note: last_entered_ probably changed since last check */ drain_common(last_entered_, lock); /* would_block() should return true when drain_seqno_ is set * so the monitor should be totally empty at this point. */ } locked_ = 1; log_debug << "Locked local monitor at " << (last_left_ + 1); }
void drain(wsrep_seqno_t seqno) { gu::Lock lock(mutex_); while (drain_seqno_ != GU_LLONG_MAX) { lock.wait(cond_); } drain_common(seqno, lock); // there can be some stale canceled entries update_last_left(); drain_seqno_ = GU_LLONG_MAX; cond_.broadcast(); }
void set_initial_position(wsrep_seqno_t seqno) { gu::Lock lock(mutex_); if (last_entered_ == -1 || seqno == -1) { // first call or reset last_entered_ = last_left_ = seqno; } else { // drain monitor up to seqno but don't reset last_entered_ // or last_left_ drain_common(seqno, lock); drain_seqno_ = GU_LLONG_MAX; } if (seqno != -1) { const size_t idx(indexof(seqno)); process_[idx].wait_cond_.broadcast(); } }