#include "config.h"
#include "libssh/threads.h"
#include <libssh/callbacks.h>
#include <windows.h>
#include <winbase.h>
#include <errno.h>
#include <stdlib.h>
static int ssh_winlock_mutex_init (void **priv)
{
CRITICAL_SECTION *lock = malloc(sizeof(CRITICAL_SECTION));
if (lock == NULL) {
return ENOMEM;
}
InitializeCriticalSection(lock);
*priv = lock;
return 0;
}
static int ssh_winlock_mutex_destroy (void **lock)
{
DeleteCriticalSection((CRITICAL_SECTION *) *lock);
free(*lock);
return 0;
}
static int ssh_winlock_mutex_lock (void **lock)
{
EnterCriticalSection((CRITICAL_SECTION *) *lock);
return 0;
}
static int ssh_winlock_mutex_unlock (void **lock)
{
LeaveCriticalSection((CRITICAL_SECTION *) *lock);
return 0;
}
static unsigned long ssh_winlock_thread_id (void)
{
return GetCurrentThreadId();
}
static struct ssh_threads_callbacks_struct ssh_threads_winlock =
{
.type = "threads_winlock",
.mutex_init = ssh_winlock_mutex_init,
.mutex_destroy = ssh_winlock_mutex_destroy,
.mutex_lock = ssh_winlock_mutex_lock,
.mutex_unlock = ssh_winlock_mutex_unlock,
.thread_id = ssh_winlock_thread_id
};
void ssh_mutex_lock(SSH_MUTEX *mutex)
{
void *rc;
CRITICAL_SECTION *mutex_tmp = NULL;
if (*mutex == NULL) {
mutex_tmp = malloc(sizeof(CRITICAL_SECTION));
if (mutex_tmp == NULL) {
exit(ENOMEM);
}
InitializeCriticalSection(mutex_tmp);
rc = InterlockedCompareExchangePointer((PVOID*)mutex,
(PVOID)mutex_tmp,
NULL);
if (rc != NULL) {
DeleteCriticalSection(mutex_tmp);
free(mutex_tmp);
exit(ENOMEM);
}
}
EnterCriticalSection(*mutex);
}
void ssh_mutex_unlock(SSH_MUTEX *mutex)
{
LeaveCriticalSection(*mutex);
}
struct ssh_threads_callbacks_struct *ssh_threads_get_winlock(void)
{
return &ssh_threads_winlock;
}
struct ssh_threads_callbacks_struct *ssh_threads_get_default(void)
{
return &ssh_threads_winlock;
}