/* * This file is part of the SSH Library * * Copyright (c) 2018 by Anderson Toshiyuki Sasaki * * The SSH Library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at your * option) any later version. * * The SSH Library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the SSH Library; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ #include "config.h" #include "libssh/threads.h" #include #include #include #include #include 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 }; /* Threads interface implementation */ 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; }