Example #1
0
bool Condition::wait(UniqueLock<honey::Mutex>& external, honey::MonoClock::TimePoint time)
{
    honey::thread::priv::InterruptWait _(reinterpret_cast<honey::Condition&>(*this), external.mutex());

    timespec time_;
    //platform bug, should allow numeral<decltype(time_.tv_sec)>().max()
    time_.tv_sec = Alge::min(Seconds(time.time()).count(), numeral<int>().max());
    time_.tv_nsec = time.time() % Seconds(1);
    return !pthread_cond_timedwait(&_handle, &external.mutex().handle(), &time_);
}
void DatabasesCloner::_cancelCloners_inlock(UniqueLock& lk) {
    std::vector<std::shared_ptr<DatabaseCloner>> clonersToCancel;
    for (auto&& cloner : _databaseCloners) {
        if (cloner && cloner->isActive()) {
            clonersToCancel.push_back(cloner);
        }
    }

    lk.unlock();
    for (auto&& cloner : clonersToCancel) {
        cloner->cancel();
    }
    lk.lock();
}
Example #3
0
bool Condition::wait(UniqueLock<honey::Mutex>& external, honey::MonoClock::TimePoint time)
{
    auto _ = ScopeGuard(lock::lockGuard(external));

    _waitLock->lock();
    ++_waitCount;
    _waitLock->unlock();

    //Wait for both the semaphore and the high resolution timeout
    HANDLE handles[2] = { _sema };
    int handleCount = 1;
    if (time != honey::MonoClock::TimePoint::max())
    {
        //Convert to windows 100 nanosecond period, negative time means relative
        LARGE_INTEGER sleepTime;
        sleepTime.QuadPart = (-Alge::max(time - honey::MonoClock::now(), honey::MonoClock::Duration::zero()) / 100).count();
        verify(SetWaitableTimer(_timer, &sleepTime, 0, NULL, NULL, 0));
        handles[handleCount++] = _timer;
    }

    //Unfair but safe race condition: external unlock and wait should be atomic
    external.unlock();
    DWORD res = WaitForMultipleObjects(handleCount, handles, FALSE, INFINITE);

    _waitLock->lock();
    --_waitCount;
    bool lastWait = _broadcast && _waitCount == 0;
    _waitLock->unlock();

    //Unfair but safe race condition: wait done signal and external relock should be atomic
    if (lastWait)
        SetEvent(_waitDone);
    return res == WAIT_OBJECT_0;
} //external.lock()
void DatabasesCloner::_failed_inlock(UniqueLock& lk) {
    LOG(3) << "DatabasesCloner::_failed_inlock";
    if (!_active) {
        return;
    }
    _active = false;

    // TODO: shutdown outstanding work, like any cloners active
    auto finish = _finishFn;
    lk.unlock();

    LOG(3) << "calling _finishFn with status: " << _status;
    _finishFn(_status);
}
Example #5
0
void DatabaseCloner::_finishCallback_inlock(UniqueLock& lk, const Status& status) {
    if (lk.owns_lock()) {
        lk.unlock();
    }
    _finishCallback(status);
}