/src/strongswan/src/libstrongswan/threading/thread_value.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2009-2012 Tobias Brunner |
3 | | * |
4 | | * Copyright (C) secunet Security Networks AG |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU General Public License as published by the |
8 | | * Free Software Foundation; either version 2 of the License, or (at your |
9 | | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, but |
12 | | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
13 | | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | | * for more details. |
15 | | */ |
16 | | |
17 | | #define _GNU_SOURCE |
18 | | #include <pthread.h> |
19 | | |
20 | | #include <library.h> |
21 | | |
22 | | #include "thread_value.h" |
23 | | |
24 | | typedef struct private_thread_value_t private_thread_value_t; |
25 | | |
26 | | struct private_thread_value_t { |
27 | | /** |
28 | | * Public interface. |
29 | | */ |
30 | | thread_value_t public; |
31 | | |
32 | | /** |
33 | | * Key to access thread-specific values. |
34 | | */ |
35 | | pthread_key_t key; |
36 | | |
37 | | /** |
38 | | * Destructor to cleanup the value of the thread destroying this object |
39 | | */ |
40 | | thread_cleanup_t destructor; |
41 | | |
42 | | }; |
43 | | |
44 | | METHOD(thread_value_t, set, void, |
45 | | private_thread_value_t *this, void *val) |
46 | 15.2k | { |
47 | 15.2k | pthread_setspecific(this->key, val); |
48 | 15.2k | } |
49 | | |
50 | | METHOD(thread_value_t, get, void*, |
51 | | private_thread_value_t *this) |
52 | 9.61k | { |
53 | 9.61k | return pthread_getspecific(this->key); |
54 | 9.61k | } |
55 | | |
56 | | METHOD(thread_value_t, destroy, void, |
57 | | private_thread_value_t *this) |
58 | 23.5k | { |
59 | 23.5k | void *val; |
60 | | |
61 | | /* the destructor is not called automatically for the thread calling |
62 | | * pthread_key_delete() */ |
63 | 23.5k | if (this->destructor) |
64 | 11.7k | { |
65 | 11.7k | val = pthread_getspecific(this->key); |
66 | 11.7k | if (val) |
67 | 0 | { |
68 | 0 | this->destructor(val); |
69 | 0 | } |
70 | 11.7k | } |
71 | 23.5k | pthread_key_delete(this->key); |
72 | 23.5k | free(this); |
73 | 23.5k | } |
74 | | |
75 | | /** |
76 | | * Described in header. |
77 | | */ |
78 | | thread_value_t *thread_value_create(thread_cleanup_t destructor) |
79 | 23.5k | { |
80 | 23.5k | private_thread_value_t *this; |
81 | | |
82 | 23.5k | INIT(this, |
83 | 23.5k | .public = { |
84 | 23.5k | .set = _set, |
85 | 23.5k | .get = _get, |
86 | 23.5k | .destroy = _destroy, |
87 | 23.5k | }, |
88 | 23.5k | .destructor = destructor, |
89 | 23.5k | ); |
90 | | |
91 | 23.5k | pthread_key_create(&this->key, destructor); |
92 | 23.5k | return &this->public; |
93 | 23.5k | } |
94 | | |