Commit 145b1961 authored by Sam Hocevar's avatar Sam Hocevar

* ./src/libvlc.c, ./include/main.h: the root of all objects is now

    p_libvlc, and each p_vlc is a child of p_libvlc. Reasons for this are:

     o the module bank and the message bank only need to be initialized once,
       which gives faster loads when multiple instances of libvlc are used,
     o we allow the possibility of different p_vlc sharing objects, for
       instance the audio output,
     o the CPU detection is only done once.

    This patch is not polished yet, but I cannot do any intensive tests for
    the moment because of a bug somewhere that leaves audio output objects
    lying here and there which needs to be investigated first. The current
    major issue is that the module bank is no longer freed.
parent 75873492
......@@ -17,6 +17,7 @@ Description: a free MPEG, DVD and DivX player
DVDs, or MPEG streams from a network source.
Package: libvlc0-dev
Section: devel
Architecture: any
Depends: vlc (= ${Source-Version}), ${shlibs:Depends}
Description: development files for the VideoLAN Client
......
......@@ -3,7 +3,7 @@
* Declaration and extern access to global program object.
*****************************************************************************
* Copyright (C) 1999, 2000, 2001, 2002 VideoLAN
* $Id: main.h,v 1.45 2002/08/20 18:08:51 sam Exp $
* $Id: main.h,v 1.46 2002/10/03 13:21:54 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -23,14 +23,54 @@
*****************************************************************************/
/*****************************************************************************
* vlc_t, p_vlc (global variable)
* libvlc_t (global variable)
*****************************************************************************
* This structure has an unique instance, declared in main and pointed by the
* only global variable of the program. It should allow access to any variable
* of the program, for user-interface purposes or more easier call of interface
* and common functions (example: the intf_*Msg functions). Please avoid using
* it when you can access the members you need in an other way. In fact, it
* should only be used by interface thread.
* This structure has an unique instance, statically allocated in main and
* never accessed from the outside. It store once-initialized data such as
* the CPU capabilities or the global lock.
*****************************************************************************/
struct libvlc_t
{
VLC_COMMON_MEMBERS
/* Initialization boolean */
vlc_bool_t b_ready;
/* CPU extensions */
u32 i_cpu;
/* Object structure data */
int i_counter; /* object counter */
int i_objects; /* Attached objects count */
vlc_object_t ** pp_objects; /* Array of all objects */
/* The big, evil global lock */
vlc_mutex_t global_lock;
void * p_global_data;
/* Locks */
vlc_mutex_t structure_lock; /* lock for the p_vlc tree */
/* The message bank */
msg_bank_t msg_bank;
/* The module bank */
module_bank_t * p_module_bank;
/* Arch-specific variables */
#if defined( SYS_BEOS )
vlc_object_t * p_appthread;
#elif defined( WIN32 )
SIGNALOBJECTANDWAIT SignalObjectAndWait;
vlc_bool_t b_fast_mutex;
int i_win9x_cv;
#endif
};
/*****************************************************************************
* vlc_t, p_vlc
*****************************************************************************
* This structure is a LibVLC instance.
*****************************************************************************/
struct vlc_t
{
......@@ -38,56 +78,31 @@ struct vlc_t
/* The vlc structure status */
int i_status;
int i_instance; /* p_vlc instance # */
/* Global properties */
int i_argc; /* command line arguments count */
char ** ppsz_argv; /* command line arguments */
char * psz_homedir; /* user's home directory */
u32 i_cpu; /* CPU extensions */
/* Generic settings */
vlc_bool_t b_quiet; /* be quiet ? */
vlc_bool_t b_verbose; /* info messages ? */
vlc_bool_t b_color; /* color messages ? */
mtime_t i_desync; /* relative desync of the audio ouput */
/* CPU extensions (inherited from libvlc_t) */
u32 i_cpu;
/* Fast memcpy plugin used */
module_t * p_memcpy_module;
void* ( *pf_memcpy ) ( void *, const void *, size_t );
void* ( *pf_memset ) ( void *, int, size_t );
/* The module bank */
module_bank_t * p_module_bank;
/* The message bank */
msg_bank_t msg_bank;
/* Shared data - these structures are accessed directly from p_vlc by
* several modules */
input_channel_t * p_channel; /* channel library data */
/* Locks */
vlc_mutex_t config_lock; /* lock for the config file */
vlc_mutex_t structure_lock; /* lock for the p_vlc tree */
/* Object structure data */
int i_counter; /* object counter */
int i_objects; /* Attached objects count */
vlc_object_t ** pp_objects; /* Array of all objects */
/* Pointer to the big, evil global lock */
vlc_mutex_t * p_global_lock;
void ** pp_global_data;
/* System-specific variables */
#if defined( SYS_BEOS )
vlc_object_t * p_appthread;
#elif defined( WIN32 )
SIGNALOBJECTANDWAIT SignalObjectAndWait;
vlc_bool_t b_fast_mutex;
int i_win9x_cv;
#endif
};
......@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc_common.h,v 1.27 2002/09/18 21:21:23 massiot Exp $
* $Id: vlc_common.h,v 1.28 2002/10/03 13:21:54 sam Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -154,6 +154,9 @@ typedef u32 vlc_fourcc_t;
* Classes declaration
*****************************************************************************/
/* Internal types */
typedef struct libvlc_t libvlc_t;
/* Messages */
typedef struct msg_bank_t msg_bank_t;
typedef struct msg_subscription_t msg_subscription_t;
......@@ -273,7 +276,8 @@ typedef struct iso639_lang_t iso639_lang_t;
volatile vlc_bool_t b_dead; /* set by the object */ \
volatile vlc_bool_t b_attached; /* set by the object */ \
\
vlc_t * p_vlc; /* root of all evil */ \
libvlc_t * p_libvlc; /* root of all evil */ \
vlc_t * p_vlc; /* (root of all evil) - 1 */ \
\
volatile int i_refcount; /* usage count */ \
vlc_object_t * p_parent; /* our parent */ \
......
......@@ -2,7 +2,7 @@
* cpu.h: CPU type detection
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlc_cpu.h,v 1.3 2002/07/31 20:56:50 sam Exp $
* $Id: vlc_cpu.h,v 1.4 2002/10/03 13:21:54 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -21,6 +21,5 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define CPUCapabilities(a) __CPUCapabilities(VLC_OBJECT(a))
u32 __CPUCapabilities( vlc_object_t * );
u32 CPUCapabilities( void );
......@@ -2,7 +2,7 @@
* vlc_objects.h: vlc_object_t definition.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlc_objects.h,v 1.10 2002/08/15 12:11:15 sam Exp $
* $Id: vlc_objects.h,v 1.11 2002/10/03 13:21:54 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -23,15 +23,16 @@
/* Object types */
#define VLC_OBJECT_ROOT (-1)
#define VLC_OBJECT_MODULE (-2)
#define VLC_OBJECT_INTF (-3)
#define VLC_OBJECT_PLAYLIST (-4)
#define VLC_OBJECT_ITEM (-5)
#define VLC_OBJECT_INPUT (-6)
#define VLC_OBJECT_DECODER (-7)
#define VLC_OBJECT_VOUT (-8)
#define VLC_OBJECT_AOUT (-9)
#define VLC_OBJECT_SOUT (-10)
#define VLC_OBJECT_VLC (-2)
#define VLC_OBJECT_MODULE (-3)
#define VLC_OBJECT_INTF (-4)
#define VLC_OBJECT_PLAYLIST (-5)
#define VLC_OBJECT_ITEM (-6)
#define VLC_OBJECT_INPUT (-7)
#define VLC_OBJECT_DECODER (-8)
#define VLC_OBJECT_VOUT (-9)
#define VLC_OBJECT_AOUT (-10)
#define VLC_OBJECT_SOUT (-11)
#define VLC_OBJECT_GENERIC (-666)
/* Object search mode */
......
......@@ -2,7 +2,7 @@
* rc.c : remote control stdin/stdout plugin for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: rc.c,v 1.5 2002/09/30 11:05:37 sam Exp $
* $Id: rc.c,v 1.6 2002/10/03 13:21:55 sam Exp $
*
* Authors: Peter Surda <shurdeek@panorama.sth.ac.at>
*
......@@ -181,7 +181,7 @@ static void Run( intf_thread_t *p_intf )
{
p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
FIND_ANYWHERE );
//if( p_input )
if( p_input )
{
p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
FIND_PARENT );
......
......@@ -2,7 +2,7 @@
* gtk_main.c : Gtk+ wrapper for gtk_main
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: gtk_main.c,v 1.6 2002/09/30 11:05:39 sam Exp $
* $Id: gtk_main.c,v 1.7 2002/10/03 13:21:55 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -80,12 +80,12 @@ vlc_module_end();
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
vlc_mutex_lock( &p_this->p_libvlc->global_lock );
if( i_refcount > 0 )
{
i_refcount++;
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
vlc_mutex_unlock( &p_this->p_libvlc->global_lock );
return VLC_SUCCESS;
}
......@@ -105,12 +105,12 @@ static int Open( vlc_object_t *p_this )
{
vlc_object_destroy( p_gtk_main );
i_refcount--;
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
vlc_mutex_unlock( &p_this->p_libvlc->global_lock );
return VLC_ETHREAD;
}
i_refcount++;
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
vlc_mutex_unlock( &p_this->p_libvlc->global_lock );
return VLC_SUCCESS;
}
......@@ -120,13 +120,13 @@ static int Open( vlc_object_t *p_this )
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
vlc_mutex_lock( &p_this->p_libvlc->global_lock );
i_refcount--;
if( i_refcount > 0 )
{
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
vlc_mutex_unlock( &p_this->p_libvlc->global_lock );
return;
}
......@@ -136,7 +136,7 @@ static void Close( vlc_object_t *p_this )
vlc_object_destroy( p_gtk_main );
p_gtk_main = NULL;
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
vlc_mutex_unlock( &p_this->p_libvlc->global_lock );
}
static gint foo(gpointer foo)
......
......@@ -2,7 +2,7 @@
* libvlc.c: main libvlc source
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: libvlc.c,v 1.33 2002/09/29 18:19:53 sam Exp $
* $Id: libvlc.c,v 1.34 2002/10/03 13:21:55 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -77,16 +77,12 @@
#include "libvlc.h"
/*****************************************************************************
* The evil global variables. We handle them with care, don't worry.
* The evil global variable. We handle it with care, don't worry.
*****************************************************************************/
static libvlc_t libvlc;
/* This global lock is used for critical sections - don't abuse it! */
static vlc_mutex_t global_lock;
void * p_global_data;
/* A list of all the currently allocated vlc objects */
static int volatile i_vlc = 0;
static vlc_t ** volatile pp_vlc = NULL;
//#define GLOBAL_VLC NULL
#define GLOBAL_VLC ((vlc_t*)libvlc.pp_children[1])
/*****************************************************************************
* Local prototypes
......@@ -111,13 +107,8 @@ vlc_error_t vlc_create( void )
vlc_t * p_vlc;
vlc_bool_t b_failed = VLC_FALSE;
/* This gives us a rather good protection against concurrent calls, but
* an additional check will be necessary for complete thread safety. */
if( i_vlc )
{
return VLC_EGENERIC;
}
/* This call should be thread-safe, but an additional check will be
* necessary afterwards to check that only one p_vlc is created. */
p_vlc = vlc_create_r();
if( p_vlc == NULL )
......@@ -128,12 +119,14 @@ vlc_error_t vlc_create( void )
/* We have created an object, which ensures us that p_global_lock has
* been properly initialized. We can now atomically check that we are
* the only p_vlc object. */
vlc_mutex_lock( p_vlc->p_global_lock );
if( i_vlc != 1 )
#if 0
vlc_mutex_lock( libvlc.p_global_lock );
if( libvlc.i_children != 1 ) /* FIXME !!! FIXME */
{
b_failed = VLC_TRUE;
}
vlc_mutex_unlock( p_vlc->p_global_lock );
vlc_mutex_unlock( libvlc.p_global_lock );
#endif
/* There can be only one */
if( b_failed )
......@@ -147,11 +140,47 @@ vlc_error_t vlc_create( void )
vlc_t * vlc_create_r( void )
{
static int i_instance = 0;
int i_ret;
vlc_t * p_vlc = NULL;
/* Allocate the main structure */
p_vlc = vlc_object_create( p_vlc, VLC_OBJECT_ROOT );
/* vlc_threads_init *must* be the first internal call! No other call is
* allowed before the thread system has been initialized. */
i_ret = vlc_threads_init( &libvlc );
if( i_ret )
{
return NULL;
}
/* Now that the thread system is initialized, we don't have much, but
* at least we have libvlc.global_lock */
vlc_mutex_lock( &libvlc.global_lock );
if( !libvlc.b_ready )
{
vlc_mutex_init( &libvlc, &libvlc.structure_lock );
libvlc.p_global_data = NULL;
libvlc.b_ready = VLC_TRUE;
/* Guess what CPU we have */
libvlc.i_cpu = CPUCapabilities();
/* Initialize message queue */
msg_Create( &libvlc );
/* Announce who we are */
msg_Dbg( &libvlc, COPYRIGHT_MESSAGE );
msg_Dbg( &libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
/* Initialize the module bank and and load the configuration of the
* main module. We need to do this at this stage to be able to display
* a short help if required by the user. (short help == main module
* options) */
module_InitBank( &libvlc );
module_LoadMain( &libvlc );
}
vlc_mutex_unlock( &libvlc.global_lock );
/* Allocate a vlc object */
p_vlc = vlc_object_create( &libvlc, VLC_OBJECT_VLC );
if( p_vlc == NULL )
{
return NULL;
......@@ -159,27 +188,14 @@ vlc_t * vlc_create_r( void )
p_vlc->psz_object_name = "root";
p_vlc->p_global_lock = &global_lock;
p_vlc->pp_global_data = &p_global_data;
p_vlc->b_verbose = VLC_FALSE;
p_vlc->b_verbose = VLC_TRUE;
p_vlc->b_quiet = VLC_FALSE; /* FIXME: delay message queue output! */
/* Initialize the threads system */
vlc_threads_init( p_vlc );
/* Initialize mutexes */
vlc_mutex_init( p_vlc, &p_vlc->config_lock );
vlc_mutex_init( p_vlc, &p_vlc->structure_lock );
/* Store our newly allocated structure in the global list */
vlc_mutex_lock( p_vlc->p_global_lock );
pp_vlc = realloc( pp_vlc, (i_vlc+1) * sizeof( vlc_t * ) );
pp_vlc[ i_vlc ] = p_vlc;
i_vlc++;
p_vlc->i_instance = i_instance;
i_instance++;
vlc_mutex_unlock( p_vlc->p_global_lock );
vlc_object_attach( p_vlc, &libvlc );
/* Update the handle status */
p_vlc->i_status = VLC_STATUS_CREATED;
......@@ -198,7 +214,7 @@ vlc_t * vlc_create_r( void )
*****************************************************************************/
vlc_error_t vlc_init( int i_argc, char *ppsz_argv[] )
{
return vlc_init_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL, i_argc, ppsz_argv );
return vlc_init_r( GLOBAL_VLC, i_argc, ppsz_argv );
}
vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
......@@ -216,12 +232,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
return VLC_ESTATUS;
}
/* Guess what CPU we have */
p_vlc->i_cpu = CPUCapabilities( p_vlc );
/*
* Support for gettext
*/
/* Support for gettext */
#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
# if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
if( !setlocale( LC_MESSAGES, "" ) )
......@@ -241,11 +252,6 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
textdomain( PACKAGE );
#endif
/*
* Initialize message queue
*/
msg_Create( p_vlc );
/*
* System specific initialization code
*/
......@@ -266,29 +272,16 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
p_vlc->psz_object_name = "vlc";
}
/* Announce who we are */
msg_Dbg( p_vlc, COPYRIGHT_MESSAGE );
msg_Dbg( p_vlc, "libvlc was configured with %s", CONFIGURE_LINE );
/*
* Initialize the module bank and and load the configuration of the main
* module. We need to do this at this stage to be able to display a short
* help if required by the user. (short help == main module options)
*/
module_InitBank( p_vlc );
module_LoadMain( p_vlc );
/* Hack: insert the help module here */
p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
if( p_help_module == NULL )
{
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EGENERIC;
}
p_help_module->psz_object_name = "help";
config_Duplicate( p_help_module, p_help_config );
vlc_object_attach( p_help_module, p_vlc->p_module_bank );
vlc_object_attach( p_help_module, libvlc.p_module_bank );
/* End hack */
if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
......@@ -296,8 +289,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
vlc_object_detach( p_help_module );
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EGENERIC;
}
......@@ -327,8 +319,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
{
config_Free( p_help_module );
vlc_object_destroy( p_help_module );
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EEXIT;
}
......@@ -338,13 +329,13 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
* list of configuration options exported by each module and loads their
* default values.
*/
module_LoadBuiltins( p_vlc );
module_LoadPlugins( p_vlc );
module_LoadBuiltins( &libvlc );
module_LoadPlugins( &libvlc );
msg_Dbg( p_vlc, "module bank initialized, found %i modules",
p_vlc->p_module_bank->i_children );
libvlc.p_module_bank->i_children );
/* Hack: insert the help module here */
vlc_object_attach( p_help_module, p_vlc->p_module_bank );
vlc_object_attach( p_help_module, libvlc.p_module_bank );
/* End hack */
/* Check for help on modules */
......@@ -375,8 +366,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
if( b_exit )
{
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EEXIT;
}
......@@ -398,8 +388,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
"that they are valid.\nPress the RETURN key to continue..." );
getchar();
#endif
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EGENERIC;
}
......@@ -418,6 +407,9 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
/* p_vlc inititalization. FIXME ? */
p_vlc->i_desync = config_GetInt( p_vlc, "desync" ) * (mtime_t)1000;
p_vlc->i_cpu = libvlc.i_cpu;
#if defined( __i386__ )
if( !config_GetInt( p_vlc, "mmx" ) )
p_vlc->i_cpu &= ~CPU_CAPABILITY_MMX;
......@@ -491,8 +483,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
{
module_Unneed( p_vlc, p_vlc->p_memcpy_module );
}
module_EndBank( p_vlc );
msg_Destroy( p_vlc );
//module_EndBank( p_vlc );
return VLC_EGENERIC;
}
......@@ -517,7 +508,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
*****************************************************************************/
vlc_error_t vlc_add_intf( const char *psz_module, vlc_bool_t b_block )
{
return vlc_add_intf_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
return vlc_add_intf_r( GLOBAL_VLC,
psz_module, b_block );
}
......@@ -580,13 +571,11 @@ vlc_error_t vlc_add_intf_r( vlc_t *p_vlc, const char *psz_module,
*****************************************************************************/
vlc_error_t vlc_destroy( void )
{
return vlc_destroy_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_destroy_r( GLOBAL_VLC );
}
vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
{
int i_index;
/* Check that the handle is valid */
if( !p_vlc || (p_vlc->i_status != VLC_STATUS_STOPPED
&& p_vlc->i_status != VLC_STATUS_CREATED) )
......@@ -617,20 +606,15 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
free( p_vlc->psz_homedir );
/*
* Free module bank
* XXX: Free module bank !
*/
module_EndBank( p_vlc );
//module_EndBank( p_vlc );
/*
* System specific cleaning code
*/
system_End( p_vlc );
/*
* Terminate messages interface and program
*/
msg_Destroy( p_vlc );
/* Update the handle status */
p_vlc->i_status = VLC_STATUS_CREATED;
}
......@@ -638,51 +622,16 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
/* Update the handle status, just in case */
p_vlc->i_status = VLC_STATUS_NONE;
/* Remove our structure from the global list */
vlc_mutex_lock( p_vlc->p_global_lock );
for( i_index = 0 ; i_index < i_vlc ; i_index++ )
{
if( pp_vlc[ i_index ] == p_vlc )
{
break;
}
}
if( i_index == i_vlc )
{
fprintf( stderr, "error: trying to unregister %p which is not in "
"the list\n", (void *)p_vlc );
vlc_mutex_unlock( p_vlc->p_global_lock );
vlc_object_destroy( p_vlc );
return VLC_EGENERIC;
}
for( i_index++ ; i_index < i_vlc ; i_index++ )
{
pp_vlc[ i_index - 1 ] = pp_vlc[ i_index ];
}
i_vlc--;
if( i_vlc )
{
pp_vlc = realloc( pp_vlc, i_vlc * sizeof( vlc_t * ) );
}
else
{
free( pp_vlc );
pp_vlc = NULL;
}
vlc_mutex_unlock( p_vlc->p_global_lock );
/* Stop thread system: last one out please shut the door! */
vlc_threads_end( p_vlc );
/* Destroy mutexes */
vlc_mutex_destroy( &p_vlc->structure_lock );
vlc_mutex_destroy( &p_vlc->config_lock );
vlc_object_detach( p_vlc );
vlc_object_destroy( p_vlc );
/* Stop thread system: last one out please shut the door! */
vlc_threads_end( &libvlc );
return VLC_SUCCESS;
}
......@@ -694,7 +643,7 @@ vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_die( void )
{
return vlc_die_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_die_r( GLOBAL_VLC );
}
vlc_error_t vlc_die_r( vlc_t *p_vlc )
......@@ -717,7 +666,7 @@ vlc_error_t vlc_die_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_status_t vlc_status( void )
{
return vlc_status_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_status_r( GLOBAL_VLC );
}
vlc_status_t vlc_status_r( vlc_t *p_vlc )
......@@ -738,7 +687,7 @@ vlc_status_t vlc_status_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_add_target( const char *psz_target, int i_mode, int i_pos )
{
return vlc_add_target_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
return vlc_add_target_r( GLOBAL_VLC,
psz_target, i_mode, i_pos );
}
......@@ -784,7 +733,7 @@ vlc_error_t vlc_add_target_r( vlc_t *p_vlc, const char *psz_target,
*****************************************************************************/
vlc_error_t vlc_set( const char *psz_var, const char *psz_val )
{
return vlc_set_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL, psz_var, psz_val );
return vlc_set_r( GLOBAL_VLC, psz_var, psz_val );
}
vlc_error_t vlc_set_r( vlc_t *p_vlc, const char *psz_var, const char *psz_val )
......@@ -886,7 +835,7 @@ vlc_error_t vlc_set_r( vlc_t *p_vlc, const char *psz_var, const char *psz_val )
*****************************************************************************/
vlc_error_t vlc_play( )
{
return vlc_play_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_play_r( GLOBAL_VLC );
}
vlc_error_t vlc_play_r( vlc_t *p_vlc )
......@@ -931,7 +880,7 @@ vlc_error_t vlc_play_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_stop( )
{
return vlc_stop_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_stop_r( GLOBAL_VLC );
}
vlc_error_t vlc_stop_r( vlc_t *p_vlc )
......@@ -1006,7 +955,7 @@ vlc_error_t vlc_stop_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_pause( )
{
return vlc_pause_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_pause_r( GLOBAL_VLC );
}
vlc_error_t vlc_pause_r( vlc_t *p_vlc )
......@@ -1031,7 +980,7 @@ vlc_error_t vlc_pause_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_fullscreen( )
{
return vlc_fullscreen_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
return vlc_fullscreen_r( GLOBAL_VLC );
}
vlc_error_t vlc_fullscreen_r( vlc_t *p_vlc )
......
......@@ -2,7 +2,7 @@
* cpu.c: CPU detection code
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: cpu.c,v 1.6 2002/08/19 11:37:57 sam Exp $
* $Id: cpu.c,v 1.7 2002/10/03 13:21:55 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -44,7 +44,6 @@
* Local prototypes
*****************************************************************************/
static void SigHandler ( int );
static u32 Capabilities ( vlc_object_t * );
/*****************************************************************************
* Global variables - they're needed for signal handling
......@@ -58,25 +57,9 @@ static char *psz_capability;
/*****************************************************************************
* CPUCapabilities: get the CPU capabilities
*****************************************************************************
* This function is a wrapper around Capabilities().
*****************************************************************************/
u32 __CPUCapabilities( vlc_object_t *p_this )
{
u32 i_capabilities;
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
i_capabilities = Capabilities( p_this );
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
return i_capabilities;
}
/*****************************************************************************
* Capabilities: list the processors MMX support and other capabilities
*****************************************************************************
* This function is called to list extensions the CPU may have.
*****************************************************************************/
static u32 Capabilities( vlc_object_t *p_this )
u32 CPUCapabilities( void )
{
volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
......
......@@ -4,7 +4,7 @@
* modules, especially intf modules. See config.h for output configuration.
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
* $Id: messages.c,v 1.10 2002/08/26 09:12:46 sam Exp $
* $Id: messages.c,v 1.11 2002/10/03 13:21:55 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -63,16 +63,16 @@ static char *ConvertPrintfFormatString ( const char *psz_format );
void __msg_Create( vlc_object_t *p_this )
{
/* Message queue initialization */
vlc_mutex_init( p_this, &p_this->p_vlc->msg_bank.lock );
vlc_mutex_init( p_this, &p_this->p_libvlc->msg_bank.lock );
p_this->p_vlc->msg_bank.b_configured = VLC_FALSE;
p_this->p_vlc->msg_bank.b_overflow = VLC_FALSE;
p_this->p_libvlc->msg_bank.b_configured = VLC_FALSE;
p_this->p_libvlc->msg_bank.b_overflow = VLC_FALSE;
p_this->p_vlc->msg_bank.i_start = 0;
p_this->p_vlc->msg_bank.i_stop = 0;
p_this->p_libvlc->msg_bank.i_start = 0;
p_this->p_libvlc->msg_bank.i_stop = 0;
p_this->p_vlc->msg_bank.i_sub = 0;
p_this->p_vlc->msg_bank.pp_sub = NULL;
p_this->p_libvlc->msg_bank.i_sub = 0;
p_this->p_libvlc->msg_bank.pp_sub = NULL;
}
/*****************************************************************************
......@@ -82,20 +82,20 @@ void __msg_Flush( vlc_object_t *p_this )
{
int i_index;
vlc_mutex_lock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_lock( &p_this->p_libvlc->msg_bank.lock );
p_this->p_vlc->msg_bank.b_configured = VLC_TRUE;
p_this->p_libvlc->msg_bank.b_configured = VLC_TRUE;
for( i_index = p_this->p_vlc->msg_bank.i_start;
i_index != p_this->p_vlc->msg_bank.i_stop;
for( i_index = p_this->p_libvlc->msg_bank.i_start;
i_index != p_this->p_libvlc->msg_bank.i_stop;
i_index = (i_index+1) % VLC_MSG_QSIZE )
{
PrintMsg( p_this, &p_this->p_vlc->msg_bank.msg[i_index] );
PrintMsg( p_this, &p_this->p_libvlc->msg_bank.msg[i_index] );
}
FlushMsg( &p_this->p_vlc->msg_bank );
FlushMsg( &p_this->p_libvlc->msg_bank );
vlc_mutex_unlock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_unlock( &p_this->p_libvlc->msg_bank.lock );
}
/*****************************************************************************
......@@ -107,23 +107,23 @@ void __msg_Flush( vlc_object_t *p_this )
*****************************************************************************/
void __msg_Destroy( vlc_object_t *p_this )
{
if( p_this->p_vlc->msg_bank.i_sub )
if( p_this->p_libvlc->msg_bank.i_sub )
{
msg_Err( p_this, "stale interface subscribers" );
}
/* Flush the queue */
if( !p_this->p_vlc->msg_bank.b_configured )
if( !p_this->p_libvlc->msg_bank.b_configured )
{
msg_Flush( p_this );
}
else
{
FlushMsg( &p_this->p_vlc->msg_bank );
FlushMsg( &p_this->p_libvlc->msg_bank );
}
/* Destroy lock */
vlc_mutex_destroy( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_destroy( &p_this->p_libvlc->msg_bank.lock );
}
/*****************************************************************************
......@@ -131,24 +131,25 @@ void __msg_Destroy( vlc_object_t *p_this )
*****************************************************************************/
msg_subscription_t *__msg_Subscribe( vlc_object_t *p_this )
{
msg_bank_t *p_bank = &p_this->p_libvlc->msg_bank;
msg_subscription_t *p_sub = malloc( sizeof( msg_subscription_t ) );
vlc_mutex_lock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_lock( &p_bank->lock );
/* Add subscription to the list */
p_this->p_vlc->msg_bank.i_sub++;
p_this->p_vlc->msg_bank.pp_sub = realloc( p_this->p_vlc->msg_bank.pp_sub,
p_this->p_vlc->msg_bank.i_sub * sizeof( msg_subscription_t* ) );
p_bank->i_sub++;
p_bank->pp_sub = realloc( p_bank->pp_sub,
p_bank->i_sub * sizeof( msg_subscription_t* ) );
p_this->p_vlc->msg_bank.pp_sub[ p_this->p_vlc->msg_bank.i_sub - 1 ] = p_sub;
p_bank->pp_sub[ p_bank->i_sub - 1 ] = p_sub;
p_sub->i_start = p_this->p_vlc->msg_bank.i_start;
p_sub->pi_stop = &p_this->p_vlc->msg_bank.i_stop;
p_sub->i_start = p_bank->i_start;
p_sub->pi_stop = &p_bank->i_stop;
p_sub->p_msg = p_this->p_vlc->msg_bank.msg;
p_sub->p_lock = &p_this->p_vlc->msg_bank.lock;
p_sub->p_msg = p_bank->msg;
p_sub->p_lock = &p_bank->lock;
vlc_mutex_unlock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_unlock( &p_bank->lock );
return p_sub;
}
......@@ -158,53 +159,54 @@ msg_subscription_t *__msg_Subscribe( vlc_object_t *p_this )
*****************************************************************************/
void __msg_Unsubscribe( vlc_object_t *p_this, msg_subscription_t *p_sub )
{
msg_bank_t *p_bank = &p_this->p_libvlc->msg_bank;
int i_index;
vlc_mutex_lock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_lock( &p_bank->lock );
/* Sanity check */
if( !p_this->p_vlc->msg_bank.i_sub )
if( !p_bank->i_sub )
{
msg_Err( p_this, "no subscriber in the list" );
return;
}
/* Look for the appropriate subscription */
for( i_index = 0; i_index < p_this->p_vlc->msg_bank.i_sub; i_index++ )
for( i_index = 0; i_index < p_bank->i_sub; i_index++ )
{
if( p_this->p_vlc->msg_bank.pp_sub[ i_index ] == p_sub )
if( p_bank->pp_sub[ i_index ] == p_sub )
{
break;
}
}
if( p_this->p_vlc->msg_bank.pp_sub[ i_index ] != p_sub )
if( p_bank->pp_sub[ i_index ] != p_sub )
{
msg_Err( p_this, "subscriber not found" );
vlc_mutex_unlock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_unlock( &p_bank->lock );
return;
}
/* Remove this subscription */
for( ; i_index < (p_this->p_vlc->msg_bank.i_sub - 1); i_index++ )
for( ; i_index < (p_bank->i_sub - 1); i_index++ )
{
p_this->p_vlc->msg_bank.pp_sub[ i_index ] = p_this->p_vlc->msg_bank.pp_sub[ i_index+1 ];
p_bank->pp_sub[ i_index ] = p_bank->pp_sub[ i_index+1 ];
}
p_this->p_vlc->msg_bank.i_sub--;
if( p_this->p_vlc->msg_bank.i_sub )
p_bank->i_sub--;
if( p_bank->i_sub )
{
p_this->p_vlc->msg_bank.pp_sub = realloc( p_this->p_vlc->msg_bank.pp_sub,
p_this->p_vlc->msg_bank.i_sub * sizeof( msg_subscription_t* ) );
p_bank->pp_sub = realloc( p_bank->pp_sub, p_bank->i_sub
* sizeof( msg_subscription_t* ) );
}
else
{
free( p_this->p_vlc->msg_bank.pp_sub );
p_this->p_vlc->msg_bank.pp_sub = NULL;
free( p_bank->pp_sub );
p_bank->pp_sub = NULL;
}
vlc_mutex_unlock( &p_this->p_vlc->msg_bank.lock );
vlc_mutex_unlock( &p_bank->lock );
}
/*****************************************************************************
......@@ -250,15 +252,15 @@ DECLARE_MSG_FN( __msg_Dbg, VLC_MSG_DBG );
static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module,
const char *psz_format, va_list args )
{
msg_bank_t * p_bank = &p_this->p_vlc->msg_bank; /* message bank */
char * psz_str = NULL; /* formatted message string */
msg_item_t * p_item = NULL; /* pointer to message */
msg_item_t item; /* message in case of a full queue */
msg_bank_t * p_bank = &p_this->p_libvlc->msg_bank; /* message bank */
char * psz_str = NULL; /* formatted message string */
msg_item_t * p_item = NULL; /* pointer to message */
msg_item_t item; /* message in case of a full queue */
#ifdef WIN32
char * psz_temp;
char * psz_temp;
#endif
#ifndef HAVE_VASPRINTF
int i_size = strlen(psz_format) + INTF_MAX_MSG_SIZE;
int i_size = strlen(psz_format) + INTF_MAX_MSG_SIZE;
#endif
/*
......@@ -301,7 +303,7 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module,
/* Check there is room in the queue for our message */
if( p_bank->b_overflow )
{
FlushMsg( &p_this->p_vlc->msg_bank );
FlushMsg( p_bank );
if( ((p_bank->i_stop - p_bank->i_start + 1) % VLC_MSG_QSIZE) == 0 )
{
......@@ -316,7 +318,7 @@ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module,
}
else if( ((p_bank->i_stop - p_bank->i_start + 2) % VLC_MSG_QSIZE) == 0 )
{
FlushMsg( &p_this->p_vlc->msg_bank );
FlushMsg( p_bank );
if( ((p_bank->i_stop - p_bank->i_start + 2) % VLC_MSG_QSIZE) == 0 )
{
......@@ -433,12 +435,12 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
char *psz_object = "private";
int i_type = p_item->i_type;
if( p_this->p_vlc->b_quiet || !p_this->p_vlc->msg_bank.b_configured )
if( /*p_this->p_vlc->b_quiet ||*/ !p_this->p_libvlc->msg_bank.b_configured )
{
return;
}
if( !p_this->p_vlc->b_verbose &&
if( /*!p_this->p_vlc->b_verbose && */
( (i_type == VLC_MSG_WARN) || (i_type == VLC_MSG_DBG) ) )
{
return;
......@@ -447,6 +449,7 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
switch( p_item->i_object_type )
{
case VLC_OBJECT_ROOT: psz_object = "root"; break;
case VLC_OBJECT_VLC: psz_object = "vlc"; break;
case VLC_OBJECT_MODULE: psz_object = "module"; break;
case VLC_OBJECT_INTF: psz_object = "interface"; break;
case VLC_OBJECT_PLAYLIST: psz_object = "playlist"; break;
......@@ -459,18 +462,16 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
}
/* Send the message to stderr */
if( p_this->p_vlc->b_color )
if( /*p_this->p_vlc->b_color*/1 )
{
fprintf( stderr, "[" GREEN "%.2x" GRAY ":" GREEN "%.6x" GRAY "] "
"%s %s%s: %s%s" GRAY "\n", p_this->p_vlc->i_instance,
fprintf( stderr, "[" GREEN "%.6x" GRAY "] %s %s%s: %s%s" GRAY "\n",
p_item->i_object_id, p_item->psz_module, psz_object,
ppsz_type[i_type], ppsz_color[i_type],
p_item->psz_msg );
}
else
{
fprintf( stderr, "[%.2x:%.6x] %s %s%s: %s\n",
p_this->p_vlc->i_instance, p_item->i_object_id,
fprintf( stderr, "[%.6x] %s %s%s: %s\n", p_item->i_object_id,
p_item->psz_module, psz_object, ppsz_type[i_type],
p_item->psz_msg );
}
......
......@@ -2,7 +2,7 @@
* modules.c : Builtin and plugin modules management functions
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: modules.c,v 1.93 2002/09/30 11:05:42 sam Exp $
* $Id: modules.c,v 1.94 2002/10/03 13:21:55 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Ethan C. Baldridge <BaldridgeE@cadmus.com>
......@@ -123,8 +123,8 @@ void __module_InitBank( vlc_object_t *p_this )
#endif
/* Everything worked, attach the object */
p_this->p_vlc->p_module_bank = p_bank;
vlc_object_attach( p_bank, p_this->p_vlc );
p_this->p_libvlc->p_module_bank = p_bank;
vlc_object_attach( p_bank, p_this->p_libvlc );
return;
}
......@@ -151,11 +151,11 @@ void __module_EndBank( vlc_object_t *p_this )
{
module_t * p_next;
vlc_object_detach( p_this->p_vlc->p_module_bank );
vlc_object_detach( p_this->p_libvlc->p_module_bank );
while( p_this->p_vlc->p_module_bank->i_children )
while( p_this->p_libvlc->p_module_bank->i_children )
{
p_next = (module_t *)p_this->p_vlc->p_module_bank->pp_children[0];
p_next = (module_t *)p_this->p_libvlc->p_module_bank->pp_children[0];
if( DeleteModule( p_next ) )
{
......@@ -169,7 +169,7 @@ void __module_EndBank( vlc_object_t *p_this )
}
}
vlc_object_destroy( p_this->p_vlc->p_module_bank );
vlc_object_destroy( p_this->p_libvlc->p_module_bank );
return;
}
......@@ -680,7 +680,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
/* We need to fill these since they may be needed by CallEntry() */
p_module->psz_filename = psz_file;
p_module->handle = handle;
p_module->p_symbols = &p_this->p_vlc->p_module_bank->symbols;
p_module->p_symbols = &p_this->p_libvlc->p_module_bank->symbols;
/* Initialize the module: fill p_module->psz_object_name, default config */
if( CallEntry( p_module ) != 0 )
......@@ -701,7 +701,7 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
/* msg_Dbg( p_this, "plugin \"%s\", %s",
p_module->psz_object_name, p_module->psz_longname ); */
vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
vlc_object_attach( p_module, p_this->p_libvlc->p_module_bank );
return 0;
}
......@@ -806,7 +806,7 @@ static int AllocateBuiltinModule( vlc_object_t * p_this,
/* msg_Dbg( p_this, "builtin \"%s\", %s",
p_module->psz_object_name, p_module->psz_longname ); */
vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
vlc_object_attach( p_module, p_this->p_libvlc->p_module_bank );
return 0;
}
......
......@@ -2,7 +2,7 @@
* objects.c: vlc_object_t handling
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: objects.c,v 1.20 2002/08/24 17:04:36 gbazin Exp $
* $Id: objects.c,v 1.21 2002/10/03 13:21:55 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -72,9 +72,13 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
switch( i_type )
{
case VLC_OBJECT_ROOT:
i_size = sizeof(vlc_t);
i_size = sizeof(libvlc_t);
psz_type = "root";
break;
case VLC_OBJECT_VLC:
i_size = sizeof(vlc_t);
psz_type = "vlc";
break;
case VLC_OBJECT_MODULE:
i_size = sizeof(module_t);
psz_type = "module";
......@@ -111,14 +115,21 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
break;
}
p_new = malloc( i_size );
if( !p_new )
if( i_type == VLC_OBJECT_ROOT )
{
return NULL;
p_new = p_this;
}
else
{
p_new = malloc( i_size );
if( !p_new )
{
return NULL;
}
memset( p_new, 0, i_size );
memset( p_new, 0, i_size );
}
p_new->i_object_type = i_type;
p_new->psz_object_type = psz_type;
......@@ -131,38 +142,41 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
p_new->b_dead = VLC_FALSE;
p_new->b_attached = VLC_FALSE;
/* If i_type is root, then p_new is our own p_vlc */
/* If i_type is root, then p_new is our own p_libvlc */
if( i_type == VLC_OBJECT_ROOT )
{
/* We are the first object ... no need to lock. */
p_new->p_vlc = (vlc_t*)p_new;
p_new->p_libvlc = (libvlc_t*)p_new;
p_new->p_vlc = NULL;
p_new->p_vlc->i_counter = 0;
p_new->p_libvlc->i_counter = 0;
p_new->i_object_id = 0;
p_new->p_vlc->i_objects = 1;
p_new->p_vlc->pp_objects = malloc( sizeof(vlc_object_t *) );
p_new->p_vlc->pp_objects[0] = p_new;
p_new->p_libvlc->i_objects = 1;
p_new->p_libvlc->pp_objects = malloc( sizeof(vlc_object_t *) );
p_new->p_libvlc->pp_objects[0] = p_new;
p_new->b_attached = VLC_TRUE;
}
else
{
p_new->p_vlc = p_this->p_vlc;
p_new->p_libvlc = p_this->p_libvlc;
p_new->p_vlc = ( i_type == VLC_OBJECT_VLC ) ? (vlc_t*)p_new
: p_this->p_vlc;
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
p_new->p_vlc->i_counter++;
p_new->i_object_id = p_new->p_vlc->i_counter;
p_new->p_libvlc->i_counter++;
p_new->i_object_id = p_new->p_libvlc->i_counter;
/* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's
* useless to try and recover anything if pp_objects gets smashed. */
p_new->p_vlc->i_objects++;
p_new->p_vlc->pp_objects =
realloc( p_new->p_vlc->pp_objects,
p_new->p_vlc->i_objects * sizeof(vlc_object_t *) );
p_new->p_vlc->pp_objects[ p_new->p_vlc->i_objects - 1 ] = p_new;
p_new->p_libvlc->i_objects++;
p_new->p_libvlc->pp_objects =
realloc( p_new->p_libvlc->pp_objects,
p_new->p_libvlc->i_objects * sizeof(vlc_object_t *) );
p_new->p_libvlc->pp_objects[ p_new->p_libvlc->i_objects - 1 ] = p_new;
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
p_new->p_parent = NULL;
......@@ -232,29 +246,29 @@ void __vlc_object_destroy( vlc_object_t *p_this )
{
int i_index;
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
i_index = FindIndex( p_this, p_this->p_vlc->pp_objects,
p_this->p_vlc->i_objects );
memmove( p_this->p_vlc->pp_objects + i_index,
p_this->p_vlc->pp_objects + i_index + 1,
(p_this->p_vlc->i_objects - i_index - 1)
i_index = FindIndex( p_this, p_this->p_libvlc->pp_objects,
p_this->p_libvlc->i_objects );
memmove( p_this->p_libvlc->pp_objects + i_index,
p_this->p_libvlc->pp_objects + i_index + 1,
(p_this->p_libvlc->i_objects - i_index - 1)
* sizeof( vlc_object_t *) );
p_this->p_vlc->pp_objects =
realloc( p_this->p_vlc->pp_objects,
(p_this->p_vlc->i_objects - 1) * sizeof(vlc_object_t *) );
p_this->p_libvlc->pp_objects =
realloc( p_this->p_libvlc->pp_objects,
(p_this->p_libvlc->i_objects - 1) * sizeof(vlc_object_t *) );
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
else
{
/* We are the root object ... no need to lock. */
free( p_this->p_vlc->pp_objects );
p_this->p_vlc->pp_objects = NULL;
free( p_this->p_libvlc->pp_objects );
p_this->p_libvlc->pp_objects = NULL;
}
p_this->p_vlc->i_objects--;
p_this->p_libvlc->i_objects--;
vlc_mutex_destroy( &p_this->object_lock );
vlc_cond_destroy( &p_this->object_wait );
......@@ -272,13 +286,13 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
{
vlc_object_t *p_found;
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
/* If we are of the requested type ourselves, don't look further */
if( !(i_mode & FIND_STRICT) && p_this->i_object_type == i_type )
{
p_this->i_refcount++;
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
return p_this;
}
......@@ -293,7 +307,7 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
p_found = FindObject( p_this, i_type, i_mode );
}
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
return p_found;
}
......@@ -303,9 +317,9 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
*****************************************************************************/
void __vlc_object_yield( vlc_object_t *p_this )
{
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
p_this->i_refcount++;
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -313,9 +327,9 @@ void __vlc_object_yield( vlc_object_t *p_this )
*****************************************************************************/
void __vlc_object_release( vlc_object_t *p_this )
{
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
p_this->i_refcount--;
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -326,7 +340,7 @@ void __vlc_object_release( vlc_object_t *p_this )
*****************************************************************************/
void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
{
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
/* Attach the parent to its child */
p_this->p_parent = p_parent;
......@@ -343,7 +357,7 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
SetAttachment( p_this, VLC_TRUE );
}
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -353,11 +367,11 @@ void __vlc_object_attach( vlc_object_t *p_this, vlc_object_t *p_parent )
*****************************************************************************/
void __vlc_object_detach( vlc_object_t *p_this )
{
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
if( !p_this->p_parent )
{
msg_Err( p_this, "object is not attached" );
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
return;
}
......@@ -368,7 +382,7 @@ void __vlc_object_detach( vlc_object_t *p_this )
}
DetachObject( p_this );
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -381,15 +395,15 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
{
vlc_list_t *p_list = NewList();
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
/* Look for the objects */
if( (i_mode & 0x000f) == FIND_ANYWHERE )
{
vlc_object_t **pp_current, **pp_end;
pp_current = p_this->p_vlc->pp_objects;
pp_end = pp_current + p_this->p_vlc->i_objects;
pp_current = p_this->p_libvlc->pp_objects;
pp_end = pp_current + p_this->p_libvlc->i_objects;
for( ; pp_current < pp_end ; pp_current++ )
{
......@@ -405,7 +419,7 @@ vlc_list_t * __vlc_list_find( vlc_object_t *p_this, int i_type, int i_mode )
msg_Err( p_this, "unimplemented!" );
}
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
return p_list;
}
......@@ -420,10 +434,10 @@ void __vlc_liststructure( vlc_object_t *p_this )
{
vlc_object_t **pp_current, **pp_end;
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
pp_current = p_this->p_vlc->pp_objects;
pp_end = pp_current + p_this->p_vlc->i_objects;
pp_current = p_this->p_libvlc->pp_objects;
pp_end = pp_current + p_this->p_libvlc->i_objects;
for( ; pp_current < pp_end ; pp_current++ )
{
......@@ -433,13 +447,16 @@ void __vlc_liststructure( vlc_object_t *p_this )
}
else
{
msg_Info( p_this->p_vlc, "o %.6x %s (not attached)",
vlc_object_t *p_me = p_this->p_vlc
? (vlc_object_t *)p_this->p_vlc
: (vlc_object_t *)p_this->p_libvlc;
msg_Info( p_me, "o %.6x %s (not attached)",
(*pp_current)->i_object_id,
(*pp_current)->psz_object_type );
}
}
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -452,10 +469,10 @@ void __vlc_dumpstructure( vlc_object_t *p_this )
{
char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1];
vlc_mutex_lock( &p_this->p_vlc->structure_lock );
vlc_mutex_lock( &p_this->p_libvlc->structure_lock );
psz_foo[0] = '|';
DumpStructure( p_this, 0, psz_foo );
vlc_mutex_unlock( &p_this->p_vlc->structure_lock );
vlc_mutex_unlock( &p_this->p_libvlc->structure_lock );
}
/*****************************************************************************
......@@ -468,10 +485,10 @@ void vlc_list_release( vlc_list_t *p_list )
{
if( p_list->i_count )
{
vlc_t * p_vlc = p_list->pp_objects[0]->p_vlc;
libvlc_t * p_libvlc = p_list->pp_objects[0]->p_libvlc;
vlc_object_t ** pp_current = p_list->pp_objects;
vlc_mutex_lock( &p_vlc->structure_lock );
vlc_mutex_lock( &p_libvlc->structure_lock );
while( pp_current[0] )
{
......@@ -479,7 +496,7 @@ void vlc_list_release( vlc_list_t *p_list )
pp_current++;
}
vlc_mutex_unlock( &p_vlc->structure_lock );
vlc_mutex_unlock( &p_libvlc->structure_lock );
}
free( p_list );
......@@ -632,6 +649,7 @@ static void SetAttachment( vlc_object_t *p_this, vlc_bool_t b_attached )
static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
{
char psz_children[20], psz_refcount[20], psz_thread[20], psz_name[50];
vlc_object_t *p_me;
psz_name[0] = '\0';
if( p_this->psz_object_name )
......@@ -670,7 +688,9 @@ static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
psz_thread[19] = '\0';
}
msg_Info( p_this->p_vlc, "%so %.6x %s%s%s%s%s", psz_prefix,
p_me = p_this->p_vlc ? (vlc_object_t *)p_this->p_vlc
: (vlc_object_t *)p_this->p_libvlc;
msg_Info( p_me, "%so %.6x %s%s%s%s%s", psz_prefix,
p_this->i_object_id, p_this->psz_object_type,
psz_name, psz_thread, psz_refcount, psz_children );
}
......
......@@ -2,7 +2,7 @@
* threads.c : threads implementation for the VideoLAN client
*****************************************************************************
* Copyright (C) 1999, 2000, 2001, 2002 VideoLAN
* $Id: threads.c,v 1.17 2002/09/29 18:16:04 sam Exp $
* $Id: threads.c,v 1.18 2002/10/03 13:21:55 sam Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -31,60 +31,17 @@
#define VLC_THREADS_READY 3
/*****************************************************************************
* Prototype for GPROF wrapper
*****************************************************************************/
#ifdef GPROF
/* Wrapper function for profiling */
static void * vlc_thread_wrapper ( void *p_wrapper );
# ifdef WIN32
# define ITIMER_REAL 1
# define ITIMER_PROF 2
struct itimerval
{
struct timeval it_value;
struct timeval it_interval;
};
int setitimer(int kind, const struct itimerval* itnew, struct itimerval* itold);
# endif /* WIN32 */
typedef struct wrapper_t
{
/* Data lock access */
vlc_mutex_t lock;
vlc_cond_t wait;
/* Data used to spawn the real thread */
vlc_thread_func_t func;
void *p_data;
/* Profiling timer passed to the thread */
struct itimerval itimer;
} wrapper_t;
#endif /* GPROF */
/*****************************************************************************
* Global mutexes for lazy initialization of the threads system
* Global mutex for lazy initialization of the threads system
*****************************************************************************/
static volatile int i_initializations = 0;
#if defined( PTH_INIT_IN_PTH_H )
/* Unimplemented */
#elif defined( ST_INIT_IN_ST_H )
/* Unimplemented */
#elif defined( WIN32 )
/* Unimplemented */
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;
#elif defined( HAVE_CTHREADS_H )
/* Unimplemented */
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* Unimplemented */
#endif
/*****************************************************************************
......@@ -97,98 +54,102 @@ static volatile int i_initializations = 0;
int __vlc_threads_init( vlc_object_t *p_this )
{
static volatile int i_status = VLC_THREADS_UNINITIALIZED;
int i_ret = 0;
libvlc_t *p_libvlc = (libvlc_t *)p_this;
int i_ret = VLC_SUCCESS;
/* If we have lazy mutex initialization, use it. Otherwise, we just
* hope nothing wrong happens. */
#if defined( PTH_INIT_IN_PTH_H )
/* Unimplemented */
#elif defined( ST_INIT_IN_ST_H )
/* Unimplemented */
#elif defined( WIN32 )
HINSTANCE hInstLib;
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
pthread_mutex_lock( &once_mutex );
#elif defined( HAVE_CTHREADS_H )
/* Unimplemented */
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* Unimplemented */
#endif
if( i_status == VLC_THREADS_UNINITIALIZED )
{
i_status = VLC_THREADS_PENDING;
/* We should be safe now. Do all the initialization stuff we want. */
vlc_object_create( p_libvlc, VLC_OBJECT_ROOT );
p_libvlc->b_ready = VLC_FALSE;
#if defined( PTH_INIT_IN_PTH_H )
i_ret = pth_init();
#elif defined( ST_INIT_IN_ST_H )
i_ret = st_init();
#elif defined( WIN32 )
/* dynamically get the address of SignalObjectAndWait */
/* Dynamically get the address of SignalObjectAndWait */
if( GetVersion() < 0x80000000 )
{
/* We are running on NT/2K/XP, we can use SignalObjectAndWait */
hInstLib = LoadLibrary( "kernel32" );
if( hInstLib )
{
p_this->p_vlc->SignalObjectAndWait =
p_libvlc->SignalObjectAndWait =
(SIGNALOBJECTANDWAIT)GetProcAddress( hInstLib,
"SignalObjectAndWait" );
}
}
else
{
p_this->p_vlc->SignalObjectAndWait = NULL;
p_libvlc->SignalObjectAndWait = NULL;
}
p_this->p_vlc->b_fast_mutex = 0;
p_this->p_vlc->i_win9x_cv = 0;
p_libvlc->b_fast_mutex = 0;
p_libvlc->i_win9x_cv = 0;
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
/* Unimplemented */
#elif defined( HAVE_CTHREADS_H )
/* Unimplemented */
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* Unimplemented */
#endif
vlc_mutex_init( p_libvlc, &p_libvlc->global_lock );
if( i_ret )
{
i_status = VLC_THREADS_ERROR;
}
else
{
vlc_mutex_init( p_this, p_this->p_vlc->p_global_lock );
i_initializations++;
i_status = VLC_THREADS_READY;
}
}
else
{
i_ret = ( i_status == VLC_THREADS_READY );
/* Just increment the initialization count */
i_initializations++;
}
i_initializations++;
/* If we have lazy mutex initialization support, unlock the mutex;
* otherwize, do a naive wait loop. */
#if defined( PTH_INIT_IN_PTH_H )
/* Unimplemented */
while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( ST_INIT_IN_ST_H )
/* Unimplemented */
while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( WIN32 )
/* Unimplemented */
while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
pthread_mutex_unlock( &once_mutex );
return i_ret;
#elif defined( HAVE_CTHREADS_H )
/* Unimplemented */
while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* Unimplemented */
while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#endif
/* Wait until the other thread has initialized the thread library */
while( i_status == VLC_THREADS_PENDING )
if( i_status != VLC_THREADS_READY )
{
msleep( THREAD_SLEEP );
return VLC_ETHREAD;
}
return i_status == VLC_THREADS_READY;
return i_ret;
}
/*****************************************************************************
......@@ -205,33 +166,66 @@ int __vlc_threads_end( vlc_object_t *p_this )
{
return pth_kill();
}
return 0;
#elif defined( ST_INIT_IN_ST_H )
i_initializations--;
return 0;
#elif defined( WIN32 )
i_initializations--;
return 0;
#elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
pthread_mutex_lock( &once_mutex );
i_initializations--;
pthread_mutex_unlock( &once_mutex );
return 0;
#elif defined( HAVE_CTHREADS_H )
i_initializations--;
return 0;
#elif defined( HAVE_KERNEL_SCHEDULER_H )
i_initializations--;
return 0;
#endif
return VLC_SUCCESS;
}
/*****************************************************************************
* Prototype for GPROF wrapper
*****************************************************************************/
#ifdef GPROF
/* Wrapper function for profiling */
static void * vlc_thread_wrapper ( void *p_wrapper );
# ifdef WIN32
# define ITIMER_REAL 1
# define ITIMER_PROF 2
struct itimerval
{
struct timeval it_value;
struct timeval it_interval;
};
int setitimer(int kind, const struct itimerval* itnew, struct itimerval* itold);
# endif /* WIN32 */
typedef struct wrapper_t
{
/* Data lock access */
vlc_mutex_t lock;
vlc_cond_t wait;
/* Data used to spawn the real thread */
vlc_thread_func_t func;
void *p_data;
/* Profiling timer passed to the thread */
struct itimerval itimer;
} wrapper_t;
#endif /* GPROF */
/*****************************************************************************
* vlc_mutex_init: initialize a mutex
*****************************************************************************/
......
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