threads: Add Windows threads implementation
Added Windows threads implementation based on CriticalSection. Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
83b43443e5
Коммит
04cc7b769a
@ -35,6 +35,13 @@
|
||||
#define SSH_MUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
#elif (defined _WIN32) || (defined _WIN64)
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#define SSH_MUTEX CRITICAL_SECTION *
|
||||
#define SSH_MUTEX_STATIC_INIT NULL
|
||||
|
||||
#else
|
||||
|
||||
# define SSH_MUTEX void *
|
||||
|
@ -173,6 +173,12 @@ if (CMAKE_USE_PTHREADS_INIT)
|
||||
threads/noop.c
|
||||
threads/pthread.c
|
||||
)
|
||||
elseif (CMAKE_USE_WIN32_THREADS_INIT)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
threads/noop.c
|
||||
threads/winlocks.c
|
||||
)
|
||||
else()
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
|
@ -47,7 +47,7 @@ static struct ssh_threads_callbacks_struct ssh_threads_noop =
|
||||
|
||||
/* Threads interface implementation */
|
||||
|
||||
#if !(HAVE_PTHREAD)
|
||||
#if !(HAVE_PTHREAD) && !(defined _WIN32 || defined _WIN64)
|
||||
void ssh_mutex_lock(SSH_MUTEX *mutex)
|
||||
{
|
||||
(void) mutex;
|
||||
|
123
src/threads/winlocks.c
Обычный файл
123
src/threads/winlocks.c
Обычный файл
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 <libssh/callbacks.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#include <errno.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
|
||||
};
|
||||
|
||||
/* 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;
|
||||
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user