Coverage Report

Created: 2026-06-09 09:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/lib/error.c
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