Commit e996cbef authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

LibVLC: per-thread error message API

parent 3fb6bc11
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
extern "C" { extern "C" {
# endif # endif
#include <stdarg.h>
#include <vlc/libvlc_structures.h> #include <vlc/libvlc_structures.h>
/***************************************************************************** /*****************************************************************************
...@@ -117,6 +118,49 @@ libvlc_exception_get_message( const libvlc_exception_t *p_exception ); ...@@ -117,6 +118,49 @@ libvlc_exception_get_message( const libvlc_exception_t *p_exception );
/**@} */ /**@} */
/*****************************************************************************
* Error handling
*****************************************************************************/
/** \defgroup libvlc_error libvlc_error
* \ingroup libvlc_core
* LibVLC error handling
* @{
*/
/**
* A human-readable error message for the last LibVLC error in the calling
* thread. The resulting string is valid until another error occurs (at least
* until the next LibVLC call).
*
* @warning
* This will be NULL if there was no error.
*/
const char *libvlc_errmsg (void);
/**
* Clears the LibVLC error status for the current thread. This is optional.
* By default, the error status is automatically overriden when a new error
* occurs, and destroyed when the thread exits.
*/
void libvlc_clearerr (void);
/**
* Sets the LibVLC error status and message for the current thread.
* Any previous error is overriden.
* @return a nul terminated string in any case
*/
const char *libvlc_vprinterr (const char *fmt, va_list ap);
/**
* Sets the LibVLC error status and message for the current thread.
* Any previous error is overriden.
* @return a nul terminated string in any case
*/
const char *libvlc_printerr (const char *fmt, ...);
/**@} */
/***************************************************************************** /*****************************************************************************
* Core handling * Core handling
*****************************************************************************/ *****************************************************************************/
......
...@@ -460,6 +460,7 @@ SOURCES_libvlc_control = \ ...@@ -460,6 +460,7 @@ SOURCES_libvlc_control = \
control/media_list_view_internal.h \ control/media_list_view_internal.h \
control/media_player_internal.h \ control/media_player_internal.h \
control/core.c \ control/core.c \
control/error.c \
control/log.c \ control/log.c \
control/playlist.c \ control/playlist.c \
control/vlm.c \ control/vlm.c \
......
...@@ -111,11 +111,22 @@ libvlc_instance_t * libvlc_new( int argc, const char *const *argv, ...@@ -111,11 +111,22 @@ libvlc_instance_t * libvlc_new( int argc, const char *const *argv,
{ {
libvlc_instance_t *p_new; libvlc_instance_t *p_new;
int i_ret; int i_ret;
libvlc_init_threads ();
libvlc_int_t *p_libvlc_int = libvlc_InternalCreate(); libvlc_int_t *p_libvlc_int = libvlc_InternalCreate();
if( !p_libvlc_int ) RAISENULL( "VLC initialization failed" ); if( !p_libvlc_int )
{
libvlc_deinit_threads ();
RAISENULL( "VLC initialization failed" );
}
p_new = malloc( sizeof( libvlc_instance_t ) ); p_new = malloc( sizeof( libvlc_instance_t ) );
if( !p_new ) RAISENULL( "Out of memory" ); if( !p_new )
{
libvlc_deinit_threads ();
RAISENULL( "Out of memory" );
}
const char *my_argv[argc + 2]; const char *my_argv[argc + 2];
...@@ -132,6 +143,8 @@ libvlc_instance_t * libvlc_new( int argc, const char *const *argv, ...@@ -132,6 +143,8 @@ libvlc_instance_t * libvlc_new( int argc, const char *const *argv,
{ {
libvlc_InternalDestroy( p_libvlc_int ); libvlc_InternalDestroy( p_libvlc_int );
free( p_new ); free( p_new );
libvlc_deinit_threads ();
if( i_ret == VLC_EEXITSUCCESS ) if( i_ret == VLC_EEXITSUCCESS )
return NULL; return NULL;
else else
...@@ -181,6 +194,7 @@ void libvlc_release( libvlc_instance_t *p_instance ) ...@@ -181,6 +194,7 @@ void libvlc_release( libvlc_instance_t *p_instance )
libvlc_InternalCleanup( p_instance->p_libvlc_int ); libvlc_InternalCleanup( p_instance->p_libvlc_int );
libvlc_InternalDestroy( p_instance->p_libvlc_int ); libvlc_InternalDestroy( p_instance->p_libvlc_int );
free( p_instance ); free( p_instance );
libvlc_deinit_threads ();
} }
} }
......
/*****************************************************************************
* error.c: Error handling for libvlc
*****************************************************************************
* Copyright (C) 2009 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "libvlc_internal.h"
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <vlc/libvlc.h>
static const char oom[] = "Out of memory";
/* TODO: use only one thread-specific key for whole libvlc */
static vlc_threadvar_t context;
static void libvlc_setup_threads (bool init)
{
static vlc_mutex_t lock = VLC_STATIC_MUTEX;
static uintptr_t refs = 0;
vlc_mutex_lock (&lock);
if (init)
{
if (refs++ == 0)
vlc_threadvar_create (&context, free);
}
else
{
assert (refs > 0);
if (--refs == 0)
vlc_threadvar_delete (&context);
}
vlc_mutex_unlock (&lock);
}
void libvlc_init_threads (void)
{
libvlc_setup_threads (true);
}
void libvlc_deinit_threads (void)
{
libvlc_setup_threads (false);
}
static char *get_error (void)
{
return vlc_threadvar_get (context);
}
static void free_error (void)
{
char *msg = get_error ();
if (msg != oom)
free (msg);
}
/**
* Gets a human-readable error message for the last LibVLC error in the calling
* thread. The resulting string is valid until another error occurs (at least
* until the next LibVLC call).
*
* @return NULL if there was no error, a nul-terminated string otherwise.
*/
const char *libvlc_errmsg (void)
{
return get_error ();
}
/**
* Clears the LibVLC error status for the current thread. This is optional.
* By default, the error status is automatically overriden when a new error
* occurs, and destroyed when the thread exits.
*/
void libvlc_clearerr (void)
{
free_error ();
vlc_threadvar_set (context, NULL);
}
/**
* Sets the LibVLC error status and message for the current thread.
* Any previous error is overriden.
* @return a nul terminated string (always)
*/
const char *libvlc_vprinterr (const char *fmt, va_list ap)
{
char *msg;
assert (fmt != NULL);
if (vasprintf (&msg, fmt, ap) == -1)
msg = (char *)oom;
free_error ();
vlc_threadvar_set (context, msg);
return msg;
}
/**
* Sets the LibVLC error status and message for the current thread.
* Any previous error is overriden.
* @return a nul terminated string (always)
*/
const char *libvlc_printerr (const char *fmt, ...)
{
va_list ap;
const char *msg;
va_start (ap, fmt);
msg = libvlc_vprinterr (fmt, ap);
va_end (ap);
return msg;
}
...@@ -83,6 +83,10 @@ struct libvlc_instance_t ...@@ -83,6 +83,10 @@ struct libvlc_instance_t
* Other internal functions * Other internal functions
***************************************************************************/ ***************************************************************************/
/* Thread context */
void libvlc_init_threads (void);
void libvlc_deinit_threads (void);
/* Events */ /* Events */
libvlc_event_manager_t * libvlc_event_manager_new( libvlc_event_manager_t * libvlc_event_manager_new(
void * p_obj, libvlc_instance_t * p_libvlc_inst, void * p_obj, libvlc_instance_t * p_libvlc_inst,
......
libvlc_errmsg
libvlc_clearerr
libvlc_printerr
libvlc_vprinterr
libvlc_add_intf libvlc_add_intf
libvlc_audio_output_device_count libvlc_audio_output_device_count
libvlc_audio_output_device_id libvlc_audio_output_device_id
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment