aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/threads.h7
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/threads/noop.c2
-rw-r--r--src/threads/winlocks.c123
4 files changed, 137 insertions, 1 deletions
diff --git a/include/libssh/threads.h b/include/libssh/threads.h
index 750793b2..e8ccf7be 100644
--- a/include/libssh/threads.h
+++ b/include/libssh/threads.h
@@ -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 *
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c37ce4d3..6cf44158 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -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}
diff --git a/src/threads/noop.c b/src/threads/noop.c
index aad4934e..63aca1e7 100644
--- a/src/threads/noop.c
+++ b/src/threads/noop.c
@@ -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;
diff --git a/src/threads/winlocks.c b/src/threads/winlocks.c
new file mode 100644
index 00000000..a1799531
--- /dev/null
+++ b/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;
+}