2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
25 #include <system_error>
27 #include "opthelpers.h"
31 #define WIN32_LEAN_AND_MEAN
38 semaphore::semaphore(unsigned int initial
)
40 if(initial
> static_cast<unsigned int>(std::numeric_limits
<int>::max()))
41 throw std::system_error(std::make_error_code(std::errc::value_too_large
));
42 mSem
= CreateSemaphore(nullptr, initial
, std::numeric_limits
<int>::max(), nullptr);
44 throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again
));
47 semaphore::~semaphore()
48 { CloseHandle(mSem
); }
50 void semaphore::post()
52 if(!ReleaseSemaphore(static_cast<HANDLE
>(mSem
), 1, nullptr))
53 throw std::system_error(std::make_error_code(std::errc::value_too_large
));
56 void semaphore::wait() noexcept
57 { WaitForSingleObject(static_cast<HANDLE
>(mSem
), INFINITE
); }
59 bool semaphore::try_wait() noexcept
60 { return WaitForSingleObject(static_cast<HANDLE
>(mSem
), 0) == WAIT_OBJECT_0
; }
66 /* Do not try using libdispatch on systems where it is absent. */
67 #if defined(AL_APPLE_HAVE_DISPATCH)
71 semaphore::semaphore(unsigned int initial
)
73 mSem
= dispatch_semaphore_create(initial
);
75 throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again
));
78 semaphore::~semaphore()
79 { dispatch_release(mSem
); }
81 void semaphore::post()
82 { dispatch_semaphore_signal(mSem
); }
84 void semaphore::wait() noexcept
85 { dispatch_semaphore_wait(mSem
, DISPATCH_TIME_FOREVER
); }
87 bool semaphore::try_wait() noexcept
88 { return dispatch_semaphore_wait(mSem
, DISPATCH_TIME_NOW
) == 0; }
92 #else /* !__APPLE__ */
98 semaphore::semaphore(unsigned int initial
)
100 if(sem_init(&mSem
, 0, initial
) != 0)
101 throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again
));
104 semaphore::~semaphore()
105 { sem_destroy(&mSem
); }
107 void semaphore::post()
109 if(sem_post(&mSem
) != 0)
110 throw std::system_error(std::make_error_code(std::errc::value_too_large
));
113 void semaphore::wait() noexcept
115 while(sem_wait(&mSem
) == -1 && errno
== EINTR
) {
119 bool semaphore::try_wait() noexcept
120 { return sem_trywait(&mSem
) == 0; }
124 #endif /* __APPLE__ */