#include "stdafx.h" #include "NativeUtils.h" #include #ifndef _MSC_VER #include #include #include #endif #include #include #include #include #include #include OPENMPT_NAMESPACE_BEGIN #ifndef _MSC_VER namespace mpt { class semaphore { private: unsigned int count; unsigned int waiters_count; std::mutex mutex; std::condition_variable count_nonzero; public: semaphore( unsigned int initial_count = 0 ) : count(initial_count) , waiters_count(0) { return; } ~semaphore() { return; } void wait() { std::unique_lock l(mutex); waiters_count++; while ( count == 0 ) { count_nonzero.wait( l ); } waiters_count--; count--; } void post() { std::unique_lock l(mutex); if ( waiters_count > 0 ) { count_nonzero.notify_one(); } count++; } void lock() { wait(); } void unlock() { post(); } }; } // namespace mpt #endif OPENMPT_NAMESPACE_END extern "C" { OPENMPT_WINESUPPORT_API void * OPENMPT_WINESUPPORT_CALL OpenMPT_Alloc( size_t size ) { return calloc( 1, size ); } OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Free( void * mem ) { if ( mem == nullptr ) { return; } free( mem ); return; } OPENMPT_WINESUPPORT_API size_t OPENMPT_WINESUPPORT_CALL OpenMPT_String_Length( const char * str ) { size_t len = 0; if ( !str ) { return len; } len = strlen( str ); return len; } OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_String_Duplicate( const char * src ) { if ( !src ) { return strdup( "" ); } return strdup( src ); } OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_String_Free( char * str ) { OpenMPT_Free( str ); } typedef struct OpenMPT_Semaphore { #ifndef _MSC_VER OPENMPT_NAMESPACE::mpt::semaphore * impl; #else void * dummy; #endif } OpenMPT_Semaphore; OPENMPT_WINESUPPORT_API OpenMPT_Semaphore * OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Construct(void) { #ifndef _MSC_VER OpenMPT_Semaphore * sem = (OpenMPT_Semaphore*)OpenMPT_Alloc( sizeof( OpenMPT_Semaphore ) ); sem->impl = new OPENMPT_NAMESPACE::mpt::semaphore(0); return sem; #else return nullptr; #endif } OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Destruct( OpenMPT_Semaphore * sem ) { #ifndef _MSC_VER delete sem->impl; sem->impl = nullptr; OpenMPT_Free( sem ); #else MPT_UNREFERENCED_PARAMETER(sem); #endif } OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Wait( OpenMPT_Semaphore * sem ) { #ifndef _MSC_VER sem->impl->wait(); #else MPT_UNREFERENCED_PARAMETER(sem); #endif } OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Post( OpenMPT_Semaphore * sem ) { #ifndef _MSC_VER sem->impl->post(); #else MPT_UNREFERENCED_PARAMETER(sem); #endif } } // extern "C"