summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgpg-error/w32-lock.c
diff options
context:
space:
mode:
authorRené Schümann <white06tiger@gmail.com>2015-03-20 12:32:29 +0000
committerRené Schümann <white06tiger@gmail.com>2015-03-20 12:32:29 +0000
commit539705d58fc39a28388ff18c695dd406f4ffd1d9 (patch)
tree51db7a37a66c09f41734ba5573d972aae9f30d71 /plugins/MirOTR/Libgpg-error/w32-lock.c
parent90171f125f36488dc08f5cfe0b0d4b78d995f08d (diff)
MirOTR: Libgcrypt and Libgpg-error update
Libgcrypt 1.4.6 => 1.6.3 Libgpg-error 1.9 => 1.18 git-svn-id: http://svn.miranda-ng.org/main/trunk@12449 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirOTR/Libgpg-error/w32-lock.c')
-rw-r--r--plugins/MirOTR/Libgpg-error/w32-lock.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/plugins/MirOTR/Libgpg-error/w32-lock.c b/plugins/MirOTR/Libgpg-error/w32-lock.c
new file mode 100644
index 0000000000..8c086f976d
--- /dev/null
+++ b/plugins/MirOTR/Libgpg-error/w32-lock.c
@@ -0,0 +1,158 @@
+/* w32-lock.c - GPGRT lock functions for Windows
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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 this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_W32_SYSTEM
+# error This module may only be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <gpg-error.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "lock.h"
+#include "w32-lock-obj.h"
+
+
+static _gpgrt_lock_t *
+get_lock_object (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd;
+
+ if (lock->vers != LOCK_ABI_VERSION)
+ abort ();
+
+ return lock;
+}
+
+
+gpg_err_code_t
+_gpgrt_lock_init (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd;
+
+ /* If VERS is zero we assume that no static initialization has been
+ done, so we setup our ABI version right here. The caller might
+ have called us to test whether lock support is at all available. */
+ if (!lock->vers)
+ {
+ if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t))
+ abort ();
+ lock->vers = LOCK_ABI_VERSION;
+ }
+ else /* Run the usual check. */
+ {
+ lock = get_lock_object (lockhd);
+ if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t))
+ abort ();
+ }
+
+ InitializeCriticalSection (&lock->csec);
+ lock->initdone = 1;
+ return 0;
+}
+
+
+gpg_err_code_t
+_gpgrt_lock_lock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ {
+ if (!InterlockedIncrement (&lock->started))
+ {
+ /* The new value of started is 0. Because the initial value
+ if the variable was -1 we known that this thread is the
+ first who needs this lock. Thus we initialize now. All
+ other threads won't get 0 back from InterlockedIncrement
+ and thus fall into the wait loop below. We ignore that
+ STARTED may in theory overflow if this thread starves for
+ too long. */
+ gpgrt_lock_init (lockhd);
+ }
+ else
+ {
+ while (!lock->initdone)
+ Sleep (0);
+ }
+ }
+
+ EnterCriticalSection (&lock->csec);
+ return 0;
+}
+
+
+gpg_err_code_t
+_gpgrt_lock_trylock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ {
+ if (!InterlockedIncrement (&lock->started))
+ {
+ gpgrt_lock_init (lockhd);
+ }
+ else
+ {
+ while (!lock->initdone)
+ Sleep (0);
+ }
+ }
+
+ if (!TryEnterCriticalSection (&lock->csec))
+ return GPG_ERR_EBUSY;
+ return 0;
+}
+
+
+gpg_err_code_t
+_gpgrt_lock_unlock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ return GPG_ERR_INV_LOCK_OBJ;
+ LeaveCriticalSection (&lock->csec);
+ return 0;
+}
+
+
+/* Note: Use this function only if no other thread holds or waits for
+ this lock. */
+gpg_err_code_t
+_gpgrt_lock_destroy (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ return GPG_ERR_INV_LOCK_OBJ;
+ DeleteCriticalSection (&lock->csec);
+ lock->initdone = 0;
+ lock->started = -1;
+ return 0;
+}