20#include <winpr/config.h> 
   22#include <winpr/synch.h> 
   23#include <winpr/debug.h> 
   24#include <winpr/wlog.h> 
   25#include <winpr/string.h> 
   33#include "../handle/handle.h" 
   36#define TAG WINPR_TAG("sync.mutex") 
   38static BOOL MutexCloseHandle(HANDLE handle);
 
   40static BOOL MutexIsHandled(HANDLE handle)
 
   42  return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_MUTEX, FALSE);
 
   45static int MutexGetFd(HANDLE handle)
 
   47  WINPR_MUTEX* mux = (WINPR_MUTEX*)handle;
 
   49  if (!MutexIsHandled(handle))
 
   57BOOL MutexCloseHandle(HANDLE handle)
 
   59  WINPR_MUTEX* mutex = (WINPR_MUTEX*)handle;
 
   62  if (!MutexIsHandled(handle))
 
   65  if ((rc = pthread_mutex_destroy(&mutex->mutex)))
 
   67    char ebuffer[256] = { 0 };
 
   68    WLog_ERR(TAG, 
"pthread_mutex_destroy failed with %s [%d]",
 
   69             winpr_strerror(rc, ebuffer, 
sizeof(ebuffer)), rc);
 
   70#if defined(WITH_DEBUG_MUTEX) 
   73      void* stack = winpr_backtrace(20);
 
   77        msg = winpr_backtrace_symbols(stack, &used);
 
   81        for (
size_t i = 0; i < used; i++)
 
   82          WLog_ERR(TAG, 
"%2" PRIdz 
": %s", i, msg[i]);
 
   86      winpr_backtrace_free(stack);
 
  122HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
 
  124  HANDLE handle = NULL;
 
  129    name = ConvertWCharToUtf8Alloc(lpName, NULL);
 
  134  handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
 
  139HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
 
  141  HANDLE handle = NULL;
 
  142  WINPR_MUTEX* mutex = NULL;
 
  143  mutex = (WINPR_MUTEX*)calloc(1, 
sizeof(WINPR_MUTEX));
 
  145  if (lpMutexAttributes)
 
  146    WLog_WARN(TAG, 
"[%s] does not support lpMutexAttributes", lpName);
 
  150    pthread_mutexattr_t attr;
 
  151    pthread_mutexattr_init(&attr);
 
  152    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 
  153    pthread_mutex_init(&mutex->mutex, &attr);
 
  154    WINPR_HANDLE_SET_TYPE_AND_MODE(mutex, HANDLE_TYPE_MUTEX, WINPR_FD_READ);
 
  155    mutex->common.ops = &ops;
 
  156    handle = (HANDLE)mutex;
 
  159      pthread_mutex_lock(&mutex->mutex);
 
  162      mutex->name = strdup(lpName); 
 
  168HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
 
  169                      DWORD dwDesiredAccess)
 
  171  BOOL initial = FALSE;
 
  174  if (dwDesiredAccess != 0)
 
  175    WLog_WARN(TAG, 
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
 
  178  if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
 
  181  return CreateMutexA(lpMutexAttributes, initial, lpName);
 
  184HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
 
  185                      DWORD dwDesiredAccess)
 
  187  BOOL initial = FALSE;
 
  190  if (dwDesiredAccess != 0)
 
  191    WLog_WARN(TAG, 
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
 
  194  if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
 
  197  return CreateMutexW(lpMutexAttributes, initial, lpName);
 
  200HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
 
  203  WINPR_UNUSED(dwDesiredAccess);
 
  204  WINPR_UNUSED(bInheritHandle);
 
  205  WINPR_UNUSED(lpName);
 
  206  WLog_ERR(TAG, 
"TODO: Implement");
 
  210HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
 
  213  WINPR_UNUSED(dwDesiredAccess);
 
  214  WINPR_UNUSED(bInheritHandle);
 
  215  WINPR_UNUSED(lpName);
 
  216  WLog_ERR(TAG, 
"TODO: Implement");
 
  220BOOL ReleaseMutex(HANDLE hMutex)
 
  225  if (!winpr_Handle_GetInfo(hMutex, &Type, &Object))
 
  228  if (Type == HANDLE_TYPE_MUTEX)
 
  230    WINPR_MUTEX* mutex = (WINPR_MUTEX*)Object;
 
  231    int rc = pthread_mutex_unlock(&mutex->mutex);
 
  235      char ebuffer[256] = { 0 };
 
  236      WLog_ERR(TAG, 
"pthread_mutex_unlock failed with %s [%d]",
 
  237               winpr_strerror(rc, ebuffer, 
sizeof(ebuffer)), rc);