/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2018 Danny Robson */ #include "semaphore_win32.hpp" #include "../win32/except.hpp" #include "../win32/windows.hpp" #include using cruft::thread::semaphore; /////////////////////////////////////////////////////////////////////////////// semaphore::semaphore (): semaphore (1) { ; } //----------------------------------------------------------------------------- semaphore::semaphore (value_type initial): m_handle ( win32::error::try_call ( CreateSemaphore, nullptr, initial, std::numeric_limits::max (), nullptr ) ) { m_value = initial; } /////////////////////////////////////////////////////////////////////////////// semaphore::value_type semaphore::acquire (value_type const count) { CHECK_GE (count, 0); for (value_type i = 0; i < count; ++i) { if (WAIT_OBJECT_0 != WaitForSingleObject(m_handle.native(), INFINITE)) win32::error::throw_code(); --m_value; } return m_value; } //----------------------------------------------------------------------------- semaphore::value_type semaphore::acquire (void) { return acquire (1); } //----------------------------------------------------------------------------- semaphore::value_type semaphore::release (value_type count) { LONG previous; for (value_type i = 0; i < count; ++i) { if (!ReleaseSemaphore (m_handle.native(), count, &previous)) win32::error::throw_code (); ++m_value; } return previous + 1; } //----------------------------------------------------------------------------- semaphore::value_type semaphore::release (void) { return release (1); } /////////////////////////////////////////////////////////////////////////////// semaphore::value_type semaphore::value (void) const { return m_value; } //----------------------------------------------------------------------------- semaphore::value_type semaphore::operator++ (void) { return release (); } //----------------------------------------------------------------------------- semaphore::value_type semaphore::operator-- (void) { return acquire (); }