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