1 /*****
2 *
3 * Copyright (C) 2005-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoann.v@prelude-ids.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <signal.h>
30
31 #include "glthread/tls.h"
32 #include "glthread/lock.h"
33
34 #include "prelude.h"
35 #include "prelude-inttypes.h"
36 #include "prelude-thread.h"
37 #include "prelude-log.h"
38
39
40 gl_once_define(static, init_once);
41 static gl_tls_key_t thread_error_key;
42
43
44
thread_error_key_destroy(void * value)45 static void thread_error_key_destroy(void *value)
46 {
47 free(value);
48 }
49
50
thread_init(void)51 static void thread_init(void)
52 {
53 gl_tls_key_init(thread_error_key, thread_error_key_destroy);
54 }
55
56
57 /*
58 *
59 */
prelude_thread_init(void * nil)60 int prelude_thread_init(void *nil)
61 {
62 int ret;
63
64 ret = glthread_once(&init_once, thread_init);
65 if ( ret < 0 )
66 return prelude_error_from_errno(ret);
67
68 return 0;
69 }
70
71
72
73 /*
74 *
75 */
_prelude_thread_deinit(void)76 void _prelude_thread_deinit(void)
77 {
78 char *previous;
79
80 previous = gl_tls_get(thread_error_key);
81 if ( previous )
82 free(previous);
83
84 gl_tls_key_destroy(thread_error_key);
85 }
86
87
88
_prelude_thread_set_error(const char * error)89 int _prelude_thread_set_error(const char *error)
90 {
91 char *previous;
92
93 /*
94 * Make sure prelude_thread_init() has been called before using
95 * thread local storage.
96 */
97 prelude_thread_init(NULL);
98
99 previous = gl_tls_get(thread_error_key);
100 if ( previous )
101 free(previous);
102
103 gl_tls_set(thread_error_key, strdup(error));
104
105 return 0;
106 }
107
108
109
_prelude_thread_get_error(void)110 const char *_prelude_thread_get_error(void)
111 {
112 return gl_tls_get(thread_error_key);
113 }
114
115