mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-05 14:25:36 +00:00
building on windows
This commit is contained in:
parent
b45bb06fac
commit
15b801c820
|
@ -94,6 +94,7 @@ make
|
||||||
0. record to playback example
|
0. record to playback example
|
||||||
0. clean up API and improve documentation
|
0. clean up API and improve documentation
|
||||||
0. use a documentation generator and host the docs somewhere
|
0. use a documentation generator and host the docs somewhere
|
||||||
|
0. -fvisibility=hidden and then explicitly export stuff
|
||||||
|
|
||||||
## Planned Uses for libsoundio
|
## Planned Uses for libsoundio
|
||||||
|
|
||||||
|
|
200
src/os.cpp
200
src/os.cpp
|
@ -12,50 +12,95 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__MACH__)
|
#if defined(_WIN32)
|
||||||
#define SOUNDIO_OS_KQUEUE
|
#define SOUNDIO_OS_WINDOWS
|
||||||
|
|
||||||
|
#if !defined(NOMINMAX)
|
||||||
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if !defined(VC_EXTRALEAN)
|
||||||
|
#define VC_EXTRALEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(UNICODE)
|
||||||
|
#define UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// require Windows 7 or later
|
||||||
|
#if WINVER < 0x0601
|
||||||
|
#undef WINVER
|
||||||
|
#define WINVER 0x0601
|
||||||
|
#endif
|
||||||
|
#if _WIN32_WINNT < 0x0601
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0601
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__MACH__)
|
||||||
|
#define SOUNDIO_OS_KQUEUE
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MACH__
|
#if defined(__MACH__)
|
||||||
#include <mach/clock.h>
|
#include <mach/clock.h>
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct SoundIoOsThread {
|
struct SoundIoOsThread {
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
HANDLE handle;
|
||||||
|
DWORD id;
|
||||||
|
#else
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
bool attr_init;
|
bool attr_init;
|
||||||
|
|
||||||
pthread_t id;
|
pthread_t id;
|
||||||
bool running;
|
bool running;
|
||||||
|
#endif
|
||||||
void *arg;
|
void *arg;
|
||||||
void (*run)(void *arg);
|
void (*run)(void *arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SoundIoOsMutex {
|
struct SoundIoOsMutex {
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
CRITICAL_SECTION id;
|
||||||
|
#else
|
||||||
pthread_mutex_t id;
|
pthread_mutex_t id;
|
||||||
bool id_init;
|
bool id_init;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_KQUEUE)
|
||||||
static int kq_id;
|
static int kq_id;
|
||||||
static atomic_uintptr_t next_notify_ident;
|
static atomic_uintptr_t next_notify_ident;
|
||||||
struct SoundIoOsCond {
|
struct SoundIoOsCond {
|
||||||
int notify_ident;
|
int notify_ident;
|
||||||
};
|
};
|
||||||
|
#elif defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
struct SoundIoOsCond {
|
||||||
|
CONDITION_VARIABLE id;
|
||||||
|
CRITICAL_SECTION default_cs_id;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
struct SoundIoOsCond {
|
struct SoundIoOsCond {
|
||||||
pthread_cond_t id;
|
pthread_cond_t id;
|
||||||
|
@ -69,11 +114,23 @@ struct SoundIoOsCond {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static atomic_bool initialized = ATOMIC_VAR_INIT(false);
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
INIT_ONCE win32_init_once = INIT_ONCE_STATIC_INIT;
|
||||||
|
#else
|
||||||
|
atomic_bool initialized = ATOMIC_VAR_INIT(false);
|
||||||
|
pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
static double win32_time_resolution;
|
||||||
|
#endif
|
||||||
|
|
||||||
double soundio_os_get_time(void) {
|
double soundio_os_get_time(void) {
|
||||||
#ifdef __MACH__
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
unsigned __int64 time;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*) &time);
|
||||||
|
return time * win32_time_resolution;
|
||||||
|
#elif defined(__MACH__)
|
||||||
clock_serv_t cclock;
|
clock_serv_t cclock;
|
||||||
mach_timespec_t mts;
|
mach_timespec_t mts;
|
||||||
|
|
||||||
|
@ -95,10 +152,32 @@ double soundio_os_get_time(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
static DWORD WINAPI run_win32_thread(LPVOID userdata) {
|
||||||
|
struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata;
|
||||||
|
thread->run(thread->arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void win32_panic(const char *str) {
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
LPSTR messageBuffer = nullptr;
|
||||||
|
size_t size = FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||||
|
soundio_panic(str, messageBuffer);
|
||||||
|
LocalFree(messageBuffer);
|
||||||
|
}
|
||||||
|
#else
|
||||||
static void assert_no_err(int err) {
|
static void assert_no_err(int err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *run_pthread(void *userdata) {
|
||||||
|
struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata;
|
||||||
|
thread->run(thread->arg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
static void emit_rtprio_warning(void) {
|
static void emit_rtprio_warning(void) {
|
||||||
static bool seen = false;
|
static bool seen = false;
|
||||||
if (seen)
|
if (seen)
|
||||||
|
@ -108,12 +187,7 @@ static void emit_rtprio_warning(void) {
|
||||||
fprintf(stderr, "See https://github.com/andrewrk/genesis/wiki/"
|
fprintf(stderr, "See https://github.com/andrewrk/genesis/wiki/"
|
||||||
"warning:-unable-to-set-high-priority-thread:-Operation-not-permitted\n");
|
"warning:-unable-to-set-high-priority-thread:-Operation-not-permitted\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
static void *run_thread(void *userdata) {
|
|
||||||
struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata;
|
|
||||||
thread->run(thread->arg);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int soundio_os_thread_create(
|
int soundio_os_thread_create(
|
||||||
void (*run)(void *arg), void *arg,
|
void (*run)(void *arg), void *arg,
|
||||||
|
@ -130,6 +204,16 @@ int soundio_os_thread_create(
|
||||||
thread->run = run;
|
thread->run = run;
|
||||||
thread->arg = arg;
|
thread->arg = arg;
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
thread->handle = CreateThread(NULL, 0, run_win32_thread, thread, 0, &thread->id);
|
||||||
|
if (!thread->handle) {
|
||||||
|
soundio_os_thread_destroy(thread);
|
||||||
|
return SoundIoErrorSystemResources;
|
||||||
|
}
|
||||||
|
if (!SetThreadPriority(thread->handle, THREAD_PRIORITY_TIME_CRITICAL)) {
|
||||||
|
win32_panic("unable to set high priority thread: %s"); // TODO don't panic
|
||||||
|
}
|
||||||
|
#else
|
||||||
int err;
|
int err;
|
||||||
if ((err = pthread_attr_init(&thread->attr))) {
|
if ((err = pthread_attr_init(&thread->attr))) {
|
||||||
soundio_os_thread_destroy(thread);
|
soundio_os_thread_destroy(thread);
|
||||||
|
@ -156,10 +240,10 @@ int soundio_os_thread_create(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = pthread_create(&thread->id, &thread->attr, run_thread, thread))) {
|
if ((err = pthread_create(&thread->id, &thread->attr, run_pthread, thread))) {
|
||||||
if (err == EPERM) {
|
if (err == EPERM) {
|
||||||
emit_rtprio_warning();
|
emit_rtprio_warning();
|
||||||
err = pthread_create(&thread->id, NULL, run_thread, thread);
|
err = pthread_create(&thread->id, NULL, run_pthread, thread);
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
soundio_os_thread_destroy(thread);
|
soundio_os_thread_destroy(thread);
|
||||||
|
@ -167,6 +251,7 @@ int soundio_os_thread_create(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread->running = true;
|
thread->running = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
*out_thread = thread;
|
*out_thread = thread;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -176,6 +261,15 @@ void soundio_os_thread_destroy(struct SoundIoOsThread *thread) {
|
||||||
if (!thread)
|
if (!thread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
if (thread->handle) {
|
||||||
|
DWORD err = WaitForSingleObject(thread->handle, INFINITE);
|
||||||
|
assert(err != WAIT_FAILED);
|
||||||
|
BOOL ok = CloseHandle(thread->handle);
|
||||||
|
assert(ok);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
if (thread->running) {
|
if (thread->running) {
|
||||||
assert_no_err(pthread_join(thread->id, NULL));
|
assert_no_err(pthread_join(thread->id, NULL));
|
||||||
}
|
}
|
||||||
|
@ -183,6 +277,7 @@ void soundio_os_thread_destroy(struct SoundIoOsThread *thread) {
|
||||||
if (thread->attr_init) {
|
if (thread->attr_init) {
|
||||||
assert_no_err(pthread_attr_destroy(&thread->attr));
|
assert_no_err(pthread_attr_destroy(&thread->attr));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
destroy(thread);
|
destroy(thread);
|
||||||
}
|
}
|
||||||
|
@ -196,11 +291,15 @@ struct SoundIoOsMutex *soundio_os_mutex_create(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
InitializeCriticalSection(&mutex->id);
|
||||||
|
#else
|
||||||
if ((err = pthread_mutex_init(&mutex->id, NULL))) {
|
if ((err = pthread_mutex_init(&mutex->id, NULL))) {
|
||||||
soundio_os_mutex_destroy(mutex);
|
soundio_os_mutex_destroy(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
mutex->id_init = true;
|
mutex->id_init = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
return mutex;
|
return mutex;
|
||||||
}
|
}
|
||||||
|
@ -209,19 +308,31 @@ void soundio_os_mutex_destroy(struct SoundIoOsMutex *mutex) {
|
||||||
if (!mutex)
|
if (!mutex)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
DeleteCriticalSection(&mutex->id);
|
||||||
|
#else
|
||||||
if (mutex->id_init) {
|
if (mutex->id_init) {
|
||||||
assert_no_err(pthread_mutex_destroy(&mutex->id));
|
assert_no_err(pthread_mutex_destroy(&mutex->id));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
destroy(mutex);
|
destroy(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundio_os_mutex_lock(struct SoundIoOsMutex *mutex) {
|
void soundio_os_mutex_lock(struct SoundIoOsMutex *mutex) {
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
EnterCriticalSection(&mutex->id);
|
||||||
|
#else
|
||||||
assert_no_err(pthread_mutex_lock(&mutex->id));
|
assert_no_err(pthread_mutex_lock(&mutex->id));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex) {
|
void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex) {
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
LeaveCriticalSection(&mutex->id);
|
||||||
|
#else
|
||||||
assert_no_err(pthread_mutex_unlock(&mutex->id));
|
assert_no_err(pthread_mutex_unlock(&mutex->id));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SoundIoOsCond * soundio_os_cond_create(void) {
|
struct SoundIoOsCond * soundio_os_cond_create(void) {
|
||||||
|
@ -232,7 +343,10 @@ struct SoundIoOsCond * soundio_os_cond_create(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
InitializeConditionVariable(&cond->id);
|
||||||
|
InitializeCriticalSection(&cond->default_cs_id);
|
||||||
|
#elif defined(SOUNDIO_OS_KQUEUE)
|
||||||
cond->notify_ident = next_notify_ident.fetch_add(1);
|
cond->notify_ident = next_notify_ident.fetch_add(1);
|
||||||
#else
|
#else
|
||||||
if (pthread_condattr_init(&cond->attr)) {
|
if (pthread_condattr_init(&cond->attr)) {
|
||||||
|
@ -266,7 +380,10 @@ void soundio_os_cond_destroy(struct SoundIoOsCond *cond) {
|
||||||
if (!cond)
|
if (!cond)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
DeleteCriticalSection(&cond->default_cs_id);
|
||||||
|
#elif defined(SOUNDIO_OS_KQUEUE)
|
||||||
|
// nothing to do
|
||||||
#else
|
#else
|
||||||
if (cond->id_init) {
|
if (cond->id_init) {
|
||||||
assert_no_err(pthread_cond_destroy(&cond->id));
|
assert_no_err(pthread_cond_destroy(&cond->id));
|
||||||
|
@ -286,7 +403,15 @@ void soundio_os_cond_destroy(struct SoundIoOsCond *cond) {
|
||||||
void soundio_os_cond_signal(struct SoundIoOsCond *cond,
|
void soundio_os_cond_signal(struct SoundIoOsCond *cond,
|
||||||
struct SoundIoOsMutex *locked_mutex)
|
struct SoundIoOsMutex *locked_mutex)
|
||||||
{
|
{
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
if (locked_mutex) {
|
||||||
|
WakeConditionVariable(&cond->id);
|
||||||
|
} else {
|
||||||
|
EnterCriticalSection(&cond->default_cs_id);
|
||||||
|
WakeConditionVariable(&cond->id);
|
||||||
|
LeaveCriticalSection(&cond->default_cs_id);
|
||||||
|
}
|
||||||
|
#elif defined(SOUNDIO_OS_KQUEUE)
|
||||||
struct kevent kev;
|
struct kevent kev;
|
||||||
struct timespec timeout = { 0, 0 };
|
struct timespec timeout = { 0, 0 };
|
||||||
|
|
||||||
|
@ -314,7 +439,9 @@ void soundio_os_cond_signal(struct SoundIoOsCond *cond,
|
||||||
void soundio_os_cond_timed_wait(struct SoundIoOsCond *cond,
|
void soundio_os_cond_timed_wait(struct SoundIoOsCond *cond,
|
||||||
struct SoundIoOsMutex *locked_mutex, double seconds)
|
struct SoundIoOsMutex *locked_mutex, double seconds)
|
||||||
{
|
{
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
// TODO
|
||||||
|
#elif defined(SOUNDIO_OS_KQUEUE)
|
||||||
struct kevent kev;
|
struct kevent kev;
|
||||||
struct kevent out_kev;
|
struct kevent out_kev;
|
||||||
|
|
||||||
|
@ -358,7 +485,9 @@ void soundio_os_cond_timed_wait(struct SoundIoOsCond *cond,
|
||||||
void soundio_os_cond_wait(struct SoundIoOsCond *cond,
|
void soundio_os_cond_wait(struct SoundIoOsCond *cond,
|
||||||
struct SoundIoOsMutex *locked_mutex)
|
struct SoundIoOsMutex *locked_mutex)
|
||||||
{
|
{
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
// TODO
|
||||||
|
#elif defined(SOUNDIO_OS_KQUEUE)
|
||||||
struct kevent kev;
|
struct kevent kev;
|
||||||
struct kevent out_kev;
|
struct kevent out_kev;
|
||||||
|
|
||||||
|
@ -391,15 +520,35 @@ void soundio_os_cond_wait(struct SoundIoOsCond *cond,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void internal_init(void) {
|
static void internal_init(void) {
|
||||||
#ifdef SOUNDIO_OS_KQUEUE
|
#if defined(SOUNDIO_OS_KQUEUE)
|
||||||
kq_id = kqueue();
|
kq_id = kqueue();
|
||||||
if (kq_id == -1)
|
if (kq_id == -1)
|
||||||
soundio_panic("unable to create kqueue: %s", strerror(errno));
|
soundio_panic("unable to create kqueue: %s", strerror(errno));
|
||||||
next_notify_ident.store(1);
|
next_notify_ident.store(1);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
unsigned __int64 frequency;
|
||||||
|
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) {
|
||||||
|
win32_time_resolution = 1.0 / (double) frequency;
|
||||||
|
} else {
|
||||||
|
win32_panic("unable to initialize high precision timer: %s");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
static BOOL CALLBACK win32_init_once_cb(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext) {
|
||||||
|
internal_init();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void soundio_os_init(void) {
|
void soundio_os_init(void) {
|
||||||
|
#if defined(SOUNDIO_OS_WINDOWS)
|
||||||
|
PVOID lpContext;
|
||||||
|
if (!InitOnceExecuteOnce(&win32_init_once, win32_init_once_cb, NULL, &lpContext))
|
||||||
|
win32_panic("unable to initialize: %s");
|
||||||
|
#else
|
||||||
if (initialized.load())
|
if (initialized.load())
|
||||||
return;
|
return;
|
||||||
assert_no_err(pthread_mutex_lock(&init_mutex));
|
assert_no_err(pthread_mutex_lock(&init_mutex));
|
||||||
|
@ -410,4 +559,5 @@ void soundio_os_init(void) {
|
||||||
initialized.store(true);
|
initialized.store(true);
|
||||||
internal_init();
|
internal_init();
|
||||||
assert_no_err(pthread_mutex_unlock(&init_mutex));
|
assert_no_err(pthread_mutex_unlock(&init_mutex));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ void soundio_os_mutex_lock(struct SoundIoOsMutex *mutex);
|
||||||
void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex);
|
void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex);
|
||||||
|
|
||||||
struct SoundIoOsCond;
|
struct SoundIoOsCond;
|
||||||
struct SoundIoOsCond * soundio_os_cond_create(void);
|
struct SoundIoOsCond *soundio_os_cond_create(void);
|
||||||
void soundio_os_cond_destroy(struct SoundIoOsCond *cond);
|
void soundio_os_cond_destroy(struct SoundIoOsCond *cond);
|
||||||
|
|
||||||
// locked_mutex is optional. On systems that use mutexes for conditions, if you
|
// locked_mutex is optional. On systems that use mutexes for conditions, if you
|
||||||
|
|
Loading…
Reference in a new issue