Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * error.c: Error handling for libvlc |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2009 Rémi Denis-Courmont |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with this program; if not, write to the Free Software Foundation, |
18 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
19 | | *****************************************************************************/ |
20 | | |
21 | | #ifdef HAVE_CONFIG_H |
22 | | # include "config.h" |
23 | | #endif |
24 | | |
25 | | #include "libvlc_internal.h" |
26 | | |
27 | | #include <stdarg.h> |
28 | | #include <stdio.h> |
29 | | #include <assert.h> |
30 | | #include <vlc/libvlc.h> |
31 | | |
32 | | |
33 | | static const char oom[] = "Out of memory"; |
34 | | /* TODO: use only one thread-specific key for whole libvlc */ |
35 | | static vlc_threadvar_t context; |
36 | | |
37 | | static char *get_error (void) |
38 | 0 | { |
39 | 0 | return vlc_threadvar_get (context); |
40 | 0 | } |
41 | | |
42 | | static void free_msg (void *msg) |
43 | 0 | { |
44 | 0 | if (msg != oom) |
45 | 0 | free (msg); |
46 | 0 | } |
47 | | |
48 | | static void free_error (void) |
49 | 0 | { |
50 | 0 | free_msg (get_error ()); |
51 | 0 | } |
52 | | |
53 | | static vlc_mutex_t lock = VLC_STATIC_MUTEX; |
54 | | static uintptr_t refs = 0; |
55 | | |
56 | | void libvlc_threads_init (void) |
57 | 84 | { |
58 | 84 | vlc_mutex_lock (&lock); |
59 | 84 | if (refs++ == 0) |
60 | 84 | vlc_threadvar_create (&context, free_msg); |
61 | 84 | vlc_mutex_unlock (&lock); |
62 | 84 | } |
63 | | |
64 | | void libvlc_threads_deinit (void) |
65 | 0 | { |
66 | 0 | vlc_mutex_lock (&lock); |
67 | 0 | assert (refs > 0); |
68 | 0 | if (--refs == 0) |
69 | 0 | { |
70 | 0 | free_error (); |
71 | 0 | vlc_threadvar_delete (&context); |
72 | 0 | } |
73 | 0 | vlc_mutex_unlock (&lock); |
74 | 0 | } |
75 | | |
76 | | /** |
77 | | * Gets a human-readable error message for the last LibVLC error in the calling |
78 | | * thread. The resulting string is valid until another error occurs (at least |
79 | | * until the next LibVLC call). |
80 | | * |
81 | | * @return NULL if there was no error, a nul-terminated string otherwise. |
82 | | */ |
83 | | const char *libvlc_errmsg (void) |
84 | 0 | { |
85 | 0 | return get_error (); |
86 | 0 | } |
87 | | |
88 | | /** |
89 | | * Clears the LibVLC error status for the current thread. This is optional. |
90 | | * By default, the error status is automatically overridden when a new error |
91 | | * occurs, and destroyed when the thread exits. |
92 | | */ |
93 | | void libvlc_clearerr (void) |
94 | 0 | { |
95 | 0 | free_error (); |
96 | 0 | int ret = vlc_threadvar_set (context, NULL); |
97 | 0 | if(unlikely(ret != 0)) |
98 | 0 | abort(); |
99 | 0 | } |
100 | | |
101 | | /** |
102 | | * Sets the LibVLC error status and message for the current thread. |
103 | | * Any previous error is overridden. |
104 | | * \param fmt the format string |
105 | | * \param ap the arguments |
106 | | * \return a nul terminated string in any case |
107 | | */ |
108 | | static const char *libvlc_vprinterr (const char *fmt, va_list ap) |
109 | 0 | { |
110 | 0 | char *msg; |
111 | |
|
112 | 0 | assert (fmt != NULL); |
113 | 0 | if (vasprintf (&msg, fmt, ap) == -1) |
114 | 0 | msg = (char *)oom; |
115 | |
|
116 | 0 | free_error (); |
117 | 0 | int ret = vlc_threadvar_set (context, msg); |
118 | 0 | if(unlikely(ret != 0)) |
119 | 0 | abort(); |
120 | 0 | return msg; |
121 | 0 | } |
122 | | |
123 | | /** |
124 | | * Sets the LibVLC error status and message for the current thread. |
125 | | * Any previous error is overridden. |
126 | | * @return a nul terminated string (always) |
127 | | */ |
128 | | const char *libvlc_printerr (const char *fmt, ...) |
129 | 0 | { |
130 | 0 | va_list ap; |
131 | 0 | const char *msg; |
132 | |
|
133 | 0 | va_start (ap, fmt); |
134 | 0 | msg = libvlc_vprinterr (fmt, ap); |
135 | | va_end (ap); |
136 | 0 | return msg; |
137 | 0 | } |
138 | | |