NativeUtils.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #include "stdafx.h"
  2. #include "NativeUtils.h"
  3. #include <string>
  4. #ifndef _MSC_VER
  5. #include <condition_variable>
  6. #include <mutex>
  7. #include <thread>
  8. #endif
  9. #include <cstdint>
  10. #include <cstdlib>
  11. #include <cstring>
  12. #include <stdint.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. OPENMPT_NAMESPACE_BEGIN
  16. #ifndef _MSC_VER
  17. namespace mpt {
  18. class semaphore {
  19. private:
  20. unsigned int count;
  21. unsigned int waiters_count;
  22. std::mutex mutex;
  23. std::condition_variable count_nonzero;
  24. public:
  25. semaphore( unsigned int initial_count = 0 )
  26. : count(initial_count)
  27. , waiters_count(0)
  28. {
  29. return;
  30. }
  31. ~semaphore() {
  32. return;
  33. }
  34. void wait() {
  35. std::unique_lock<std::mutex> l(mutex);
  36. waiters_count++;
  37. while ( count == 0 ) {
  38. count_nonzero.wait( l );
  39. }
  40. waiters_count--;
  41. count--;
  42. }
  43. void post() {
  44. std::unique_lock<std::mutex> l(mutex);
  45. if ( waiters_count > 0 ) {
  46. count_nonzero.notify_one();
  47. }
  48. count++;
  49. }
  50. void lock() {
  51. wait();
  52. }
  53. void unlock() {
  54. post();
  55. }
  56. };
  57. } // namespace mpt
  58. #endif
  59. OPENMPT_NAMESPACE_END
  60. extern "C" {
  61. OPENMPT_WINESUPPORT_API void * OPENMPT_WINESUPPORT_CALL OpenMPT_Alloc( size_t size ) {
  62. return calloc( 1, size );
  63. }
  64. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Free( void * mem ) {
  65. if ( mem == nullptr ) {
  66. return;
  67. }
  68. free( mem );
  69. return;
  70. }
  71. OPENMPT_WINESUPPORT_API size_t OPENMPT_WINESUPPORT_CALL OpenMPT_String_Length( const char * str ) {
  72. size_t len = 0;
  73. if ( !str ) {
  74. return len;
  75. }
  76. len = strlen( str );
  77. return len;
  78. }
  79. OPENMPT_WINESUPPORT_API char * OPENMPT_WINESUPPORT_CALL OpenMPT_String_Duplicate( const char * src ) {
  80. if ( !src ) {
  81. return strdup( "" );
  82. }
  83. return strdup( src );
  84. }
  85. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_String_Free( char * str ) {
  86. OpenMPT_Free( str );
  87. }
  88. typedef struct OpenMPT_Semaphore {
  89. #ifndef _MSC_VER
  90. OPENMPT_NAMESPACE::mpt::semaphore * impl;
  91. #else
  92. void * dummy;
  93. #endif
  94. } OpenMPT_Semaphore;
  95. OPENMPT_WINESUPPORT_API OpenMPT_Semaphore * OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Construct(void) {
  96. #ifndef _MSC_VER
  97. OpenMPT_Semaphore * sem = (OpenMPT_Semaphore*)OpenMPT_Alloc( sizeof( OpenMPT_Semaphore ) );
  98. sem->impl = new OPENMPT_NAMESPACE::mpt::semaphore(0);
  99. return sem;
  100. #else
  101. return nullptr;
  102. #endif
  103. }
  104. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Destruct( OpenMPT_Semaphore * sem ) {
  105. #ifndef _MSC_VER
  106. delete sem->impl;
  107. sem->impl = nullptr;
  108. OpenMPT_Free( sem );
  109. #else
  110. MPT_UNREFERENCED_PARAMETER(sem);
  111. #endif
  112. }
  113. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Wait( OpenMPT_Semaphore * sem ) {
  114. #ifndef _MSC_VER
  115. sem->impl->wait();
  116. #else
  117. MPT_UNREFERENCED_PARAMETER(sem);
  118. #endif
  119. }
  120. OPENMPT_WINESUPPORT_API void OPENMPT_WINESUPPORT_CALL OpenMPT_Semaphore_Post( OpenMPT_Semaphore * sem ) {
  121. #ifndef _MSC_VER
  122. sem->impl->post();
  123. #else
  124. MPT_UNREFERENCED_PARAMETER(sem);
  125. #endif
  126. }
  127. } // extern "C"