blob: 15fbe3ed473381702ecb33de1d2e6382fc761f73 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <zircon/assert.h>
#include <limits>
#include <refcount/blocking_refcount.h>
namespace refcount {
BlockingRefCount::BlockingRefCount() : count_(0) {}
BlockingRefCount::BlockingRefCount(int32_t initial_count) : count_(initial_count) {
ZX_DEBUG_ASSERT(initial_count >= 0);
}
void BlockingRefCount::Inc() {
sync_mutex_lock(&lock_);
ZX_DEBUG_ASSERT(count_ >= 0);
ZX_DEBUG_ASSERT(count_ < std::numeric_limits<decltype(count_)>::max());
count_++;
sync_mutex_unlock(&lock_);
}
void BlockingRefCount::Dec() {
sync_mutex_lock(&lock_);
ZX_DEBUG_ASSERT(count_ > 0);
count_--;
if (count_ == 0) {
sync_condition_broadcast(&condition_);
}
sync_mutex_unlock(&lock_);
}
void BlockingRefCount::WaitForZero() const {
sync_mutex_lock(&lock_);
ZX_DEBUG_ASSERT(count_ >= 0);
while (count_ > 0) {
sync_condition_wait(&condition_, &lock_);
}
sync_mutex_unlock(&lock_);
}
} // namespace refcount