Annotation of embedaddon/strongswan/src/libstrongswan/threading/windows/thread_value.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2013 Martin Willi
! 3: * Copyright (C) 2013 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "thread.h"
! 17:
! 18: #include <threading/thread_value.h>
! 19:
! 20:
! 21: typedef struct private_thread_value_t private_thread_value_t;
! 22:
! 23: /**
! 24: * Unified thread_value_t implementation
! 25: */
! 26: struct private_thread_value_t {
! 27:
! 28: /**
! 29: * Public interface.
! 30: */
! 31: thread_value_t public;
! 32:
! 33: union {
! 34:
! 35: /**
! 36: * Cleanup function
! 37: */
! 38: thread_cleanup_t cleanup;
! 39:
! 40: /**
! 41: * Windows TLS index, if used
! 42: */
! 43: DWORD index;
! 44: };
! 45: };
! 46:
! 47: /**
! 48: * TLS entry
! 49: */
! 50: typedef struct {
! 51: /** TLS value */
! 52: void *value;
! 53: /** cleanup handler function */
! 54: thread_cleanup_t cleanup;
! 55: } entry_t;
! 56:
! 57: /**
! 58: * See windows/thread.h
! 59: */
! 60: void thread_tls_cleanup(void *value)
! 61: {
! 62: entry_t *entry = (entry_t*)value;
! 63:
! 64: if (entry->cleanup)
! 65: {
! 66: entry->cleanup(entry->value);
! 67: }
! 68: free(entry);
! 69: }
! 70:
! 71: METHOD(thread_value_t, tls_set, void,
! 72: private_thread_value_t *this, void *val)
! 73: {
! 74: entry_t *entry;
! 75:
! 76: if (val)
! 77: {
! 78: INIT(entry,
! 79: .cleanup = this->cleanup,
! 80: .value = val,
! 81: );
! 82:
! 83: free(thread_tls_put(this, entry));
! 84: }
! 85: else
! 86: {
! 87: free(thread_tls_remove(this));
! 88: }
! 89: }
! 90:
! 91: METHOD(thread_value_t, tls_get, void*,
! 92: private_thread_value_t *this)
! 93: {
! 94: entry_t *entry;
! 95:
! 96: entry = thread_tls_get(this);
! 97: if (entry)
! 98: {
! 99: return entry->value;
! 100: }
! 101: return NULL;
! 102: }
! 103:
! 104: METHOD(thread_value_t, tls_destroy, void,
! 105: private_thread_value_t *this)
! 106: {
! 107: entry_t *entry;
! 108:
! 109: entry = thread_tls_remove(this);
! 110: if (entry)
! 111: {
! 112: thread_tls_cleanup(entry);
! 113: }
! 114: free(this);
! 115: }
! 116:
! 117: METHOD(thread_value_t, tls_set_index, void,
! 118: private_thread_value_t *this, void *val)
! 119: {
! 120: TlsSetValue(this->index, val);
! 121: }
! 122:
! 123: METHOD(thread_value_t, tls_get_index, void*,
! 124: private_thread_value_t *this)
! 125: {
! 126: return TlsGetValue(this->index);
! 127: }
! 128:
! 129: METHOD(thread_value_t, tls_destroy_index, void,
! 130: private_thread_value_t *this)
! 131: {
! 132: TlsFree(this->index);
! 133: free(this);
! 134: }
! 135:
! 136: /**
! 137: * Described in header.
! 138: */
! 139: thread_value_t *thread_value_create(thread_cleanup_t cleanup)
! 140: {
! 141: private_thread_value_t *this;
! 142: DWORD index = TLS_OUT_OF_INDEXES;
! 143:
! 144: /* we have two implementations: Windows Tls* functions do not support
! 145: * callbacks and has limited instances. We use it nonetheless if possible,
! 146: * especially as leak detective relies on TLS, but we have to mangle
! 147: * leak detective state for TLS storage. */
! 148:
! 149: if (!cleanup)
! 150: {
! 151: index = TlsAlloc();
! 152: }
! 153:
! 154: if (index == TLS_OUT_OF_INDEXES)
! 155: {
! 156: INIT(this,
! 157: .public = {
! 158: .set = _tls_set,
! 159: .get = _tls_get,
! 160: .destroy = _tls_destroy,
! 161: },
! 162: .cleanup = cleanup,
! 163: );
! 164: }
! 165: else
! 166: {
! 167: INIT(this,
! 168: .public = {
! 169: .set = _tls_set_index,
! 170: .get = _tls_get_index,
! 171: .destroy = _tls_destroy_index,
! 172: },
! 173: .index = index,
! 174: );
! 175: }
! 176:
! 177: return &this->public;
! 178: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>