aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnderson Toshiyuki Sasaki <ansasaki@redhat.com>2018-07-02 14:01:46 +0200
committerAndreas Schneider <asn@cryptomilk.org>2018-08-03 16:43:03 +0200
commit04cc7b769a359ca2afdcfc0b70b5e8a17849b556 (patch)
tree67253fced38cd8d1abed2a3aff54a3d638dea3c7 /src
parent83b43443e51b5db06184750fb874e1e8d7ece95a (diff)
downloadlibssh-04cc7b769a359ca2afdcfc0b70b5e8a17849b556.tar.gz
libssh-04cc7b769a359ca2afdcfc0b70b5e8a17849b556.tar.xz
libssh-04cc7b769a359ca2afdcfc0b70b5e8a17849b556.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/threads/noop.c2
-rw-r--r--src/threads/winlocks.c123
3 files changed, 130 insertions, 1 deletions
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;
+}