Hash :
c3b7ace9
Author :
Date :
2021-11-14T16:43:53
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "git2_util.h"
#if !defined(GIT_THREADS)
#define TLSDATA_MAX 16
typedef struct {
void *value;
void (GIT_SYSTEM_CALL *destroy_fn)(void *);
} tlsdata_value;
static tlsdata_value tlsdata_values[TLSDATA_MAX];
static int tlsdata_cnt = 0;
int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *))
{
if (tlsdata_cnt >= TLSDATA_MAX)
return -1;
tlsdata_values[tlsdata_cnt].value = NULL;
tlsdata_values[tlsdata_cnt].destroy_fn = destroy_fn;
*key = tlsdata_cnt;
tlsdata_cnt++;
return 0;
}
int git_tlsdata_set(git_tlsdata_key key, void *value)
{
if (key < 0 || key > tlsdata_cnt)
return -1;
tlsdata_values[key].value = value;
return 0;
}
void *git_tlsdata_get(git_tlsdata_key key)
{
if (key < 0 || key > tlsdata_cnt)
return NULL;
return tlsdata_values[key].value;
}
int git_tlsdata_dispose(git_tlsdata_key key)
{
void *value;
void (*destroy_fn)(void *) = NULL;
if (key < 0 || key > tlsdata_cnt)
return -1;
value = tlsdata_values[key].value;
destroy_fn = tlsdata_values[key].destroy_fn;
tlsdata_values[key].value = NULL;
tlsdata_values[key].destroy_fn = NULL;
if (value && destroy_fn)
destroy_fn(value);
return 0;
}
#elif defined(GIT_WIN32)
int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *))
{
DWORD fls_index = FlsAlloc(destroy_fn);
if (fls_index == FLS_OUT_OF_INDEXES)
return -1;
*key = fls_index;
return 0;
}
int git_tlsdata_set(git_tlsdata_key key, void *value)
{
if (!FlsSetValue(key, value))
return -1;
return 0;
}
void *git_tlsdata_get(git_tlsdata_key key)
{
return FlsGetValue(key);
}
int git_tlsdata_dispose(git_tlsdata_key key)
{
if (!FlsFree(key))
return -1;
return 0;
}
#elif defined(_POSIX_THREADS)
int git_tlsdata_init(git_tlsdata_key *key, void (GIT_SYSTEM_CALL *destroy_fn)(void *))
{
if (pthread_key_create(key, destroy_fn) != 0)
return -1;
return 0;
}
int git_tlsdata_set(git_tlsdata_key key, void *value)
{
if (pthread_setspecific(key, value) != 0)
return -1;
return 0;
}
void *git_tlsdata_get(git_tlsdata_key key)
{
return pthread_getspecific(key);
}
int git_tlsdata_dispose(git_tlsdata_key key)
{
if (pthread_key_delete(key) != 0)
return -1;
return 0;
}
#else
# error unknown threading model
#endif