]> git.sesse.net Git - vlc/blob - src/misc/modules.c
* Fixed a variable overflow bug in the audio output.
[vlc] / src / misc / modules.c
1 /*****************************************************************************
2  * modules.c : Builtin and plugin modules management functions
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: modules.c,v 1.84 2002/08/12 22:12:51 massiot Exp $
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Ethan C. Baldridge <BaldridgeE@cadmus.com>
9  *          Hans-Peter Jansen <hpj@urpla.net>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /* Some faulty libcs have a broken struct dirent when _FILE_OFFSET_BITS
27  * is set to 64. Don't try to be cleverer. */
28 #ifdef _FILE_OFFSET_BITS
29 #undef _FILE_OFFSET_BITS
30 #endif
31
32 #include <stdlib.h>                                      /* free(), strtol() */
33 #include <stdio.h>                                              /* sprintf() */
34 #include <string.h>                                              /* strdup() */
35
36 #include <vlc/vlc.h>
37
38 #include <dirent.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #ifdef HAVE_UNISTD_H
42 #   include <unistd.h>
43 #endif
44
45 #if defined(HAVE_DLFCN_H)                                /* Linux, BSD, Hurd */
46 #   include <dlfcn.h>                        /* dlopen(), dlsym(), dlclose() */
47 #   define HAVE_DYNAMIC_PLUGINS
48 #elif defined(HAVE_IMAGE_H)                                          /* BeOS */
49 #   include <image.h>
50 #   define HAVE_DYNAMIC_PLUGINS
51 #elif defined(WIN32)
52 #   define HAVE_DYNAMIC_PLUGINS
53 #else
54 #   undef HAVE_DYNAMIC_PLUGINS
55 #endif
56
57
58 #include "netutils.h"
59
60 #include "interface.h"
61 #include "vlc_playlist.h"
62 #include "intf_eject.h"
63
64 #include "stream_control.h"
65 #include "input_ext-intf.h"
66 #include "input_ext-dec.h"
67 #include "input_ext-plugins.h"
68
69 #include "video.h"
70 #include "video_output.h"
71
72 #include "audio_output.h"
73
74 #include "stream_output.h"
75
76 #include "iso_lang.h"
77
78 #ifdef HAVE_DYNAMIC_PLUGINS
79 #   include "modules_plugin.h"
80 #endif
81
82 #if !defined( _MSC_VER )
83 #    include "modules_builtin.h"
84 #else
85 #    include "modules_builtin_msvc.h"
86 #endif
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91 #ifdef HAVE_DYNAMIC_PLUGINS
92 static void AllocateAllPlugins   ( vlc_object_t * );
93 static void AllocatePluginDir    ( vlc_object_t *, const char *, int );
94 static int  AllocatePluginFile   ( vlc_object_t *, char * );
95 #endif
96 static int  AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
97 static int  DeleteModule ( module_t * );
98 static int  LockModule   ( module_t * );
99 static int  UnlockModule ( module_t * );
100 #ifdef HAVE_DYNAMIC_PLUGINS
101 static int  HideModule   ( module_t * );
102 static void DupModule    ( module_t * );
103 static void UndupModule  ( module_t * );
104 static int  CallEntry    ( module_t * );
105 #endif
106
107 /*****************************************************************************
108  * module_InitBank: create the module bank.
109  *****************************************************************************
110  * This function creates a module bank structure which will be filled later
111  * on with all the modules found.
112  *****************************************************************************/
113 void __module_InitBank( vlc_object_t *p_this )
114 {
115     module_bank_t *p_bank;
116
117     p_bank = vlc_object_create( p_this, sizeof(module_bank_t) );
118     p_bank->psz_object_name = "module bank";
119
120     p_bank->first = NULL;
121     p_bank->i_count = 0;
122     vlc_mutex_init( p_this, &p_bank->lock );
123
124     /*
125      * Store the symbols to be exported
126      */
127 #ifdef HAVE_DYNAMIC_PLUGINS
128     STORE_SYMBOLS( &p_bank->symbols );
129 #endif
130
131     /* Everything worked, attach the object */
132     p_this->p_vlc->p_module_bank = p_bank;
133     vlc_object_attach( p_bank, p_this->p_vlc );
134
135     return;
136 }
137
138 /*****************************************************************************
139  * module_ResetBank: reset the module bank.
140  *****************************************************************************
141  * This function resets the module bank by unloading all unused plugin
142  * modules.
143  *****************************************************************************/
144 void __module_ResetBank( vlc_object_t *p_this )
145 {
146     msg_Err( p_this, "FIXME: module_ResetBank unimplemented" );
147     return;
148 }
149
150 /*****************************************************************************
151  * module_EndBank: empty the module bank.
152  *****************************************************************************
153  * This function unloads all unused plugin modules and empties the module
154  * bank in case of success.
155  *****************************************************************************/
156 void __module_EndBank( vlc_object_t *p_this )
157 {
158     module_t * p_next;
159
160     vlc_object_detach( p_this->p_vlc->p_module_bank );
161
162     while( p_this->p_vlc->p_module_bank->first != NULL )
163     {
164         if( DeleteModule( p_this->p_vlc->p_module_bank->first ) )
165         {
166             /* Module deletion failed */
167             msg_Err( p_this, "module \"%s\" can't be removed, trying harder",
168                      p_this->p_vlc->p_module_bank->first->psz_object_name );
169
170             /* We just free the module by hand. Niahahahahaha. */
171             p_next = p_this->p_vlc->p_module_bank->first->next;
172             free( p_this->p_vlc->p_module_bank->first );
173             p_this->p_vlc->p_module_bank->first = p_next;
174         }
175     }
176
177     /* Destroy the lock */
178     vlc_mutex_destroy( &p_this->p_vlc->p_module_bank->lock );
179
180     vlc_object_destroy( p_this->p_vlc->p_module_bank );
181
182     return;
183 }
184
185 /*****************************************************************************
186  * module_LoadMain: load the main program info into the module bank.
187  *****************************************************************************
188  * This function fills the module bank structure with the main module infos.
189  * This is very useful as it will allow us to consider the main program just
190  * as another module, and for instance the configuration options of main will
191  * be available in the module bank structure just as for every other module.
192  *****************************************************************************/
193 void __module_LoadMain( vlc_object_t *p_this )
194 {
195     AllocateBuiltinModule( p_this, vlc_entry__main );
196 }
197
198 /*****************************************************************************
199  * module_LoadBuiltins: load all modules which we built with.
200  *****************************************************************************
201  * This function fills the module bank structure with the builtin modules.
202  *****************************************************************************/
203 void __module_LoadBuiltins( vlc_object_t * p_this )
204 {
205     msg_Dbg( p_this, "checking builtin modules" );
206     ALLOCATE_ALL_BUILTINS();
207 }
208
209 /*****************************************************************************
210  * module_LoadPlugins: load all plugin modules we can find.
211  *****************************************************************************
212  * This function fills the module bank structure with the plugin modules.
213  *****************************************************************************/
214 void __module_LoadPlugins( vlc_object_t * p_this )
215 {
216 #ifdef HAVE_DYNAMIC_PLUGINS
217     msg_Dbg( p_this, "checking plugin modules" );
218     AllocateAllPlugins( p_this );
219 #endif
220 }
221
222 /*****************************************************************************
223  * module_ManageBank: manage the module bank.
224  *****************************************************************************
225  * This function parses the module bank and hides modules that have been
226  * unused for a while.
227  *****************************************************************************/
228 void __module_ManageBank( vlc_object_t *p_this )
229 {
230 #ifdef HAVE_DYNAMIC_PLUGINS
231     module_t * p_module;
232
233     /* We take the global lock */
234     vlc_mutex_lock( &p_this->p_vlc->p_module_bank->lock );
235
236     /* Parse the module list to see if any modules need to be unloaded */
237     for( p_module = p_this->p_vlc->p_module_bank->first ;
238          p_module != NULL ;
239          p_module = p_module->next )
240     {
241         /* If the module is unused and if it is a plugin module... */
242         if( p_module->i_usage == 0 && !p_module->b_builtin )
243         {
244             if( p_module->i_unused_delay < MODULE_HIDE_DELAY )
245             {
246                 p_module->i_unused_delay++;
247             }
248             else
249             {
250                 msg_Dbg( p_this, "hiding unused plugin module \"%s\"",
251                                  p_module->psz_object_name );
252                 HideModule( p_module );
253
254                 /* Break here, so that we only hide one module at a time */
255                 break;
256             }
257         }
258     }
259
260     /* We release the global lock */
261     vlc_mutex_unlock( &p_this->p_vlc->p_module_bank->lock );
262 #endif /* HAVE_DYNAMIC_PLUGINS */
263
264     return;
265 }
266
267 /*****************************************************************************
268  * module_Need: return the best module function, given a capability list.
269  *****************************************************************************
270  * This function returns the module that best fits the asked capabilities.
271  *****************************************************************************/
272 module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
273                           const char *psz_name )
274 {
275     typedef struct module_list_t module_list_t;
276
277     struct module_list_t
278     {
279         module_t *p_module;
280         int i_score;
281         module_list_t *p_next;
282     };
283
284     module_list_t *p_list, *p_first, *p_tmp;
285
286     int i_index = 0;
287     vlc_bool_t b_intf = VLC_FALSE;
288
289     module_t *p_module;
290
291     int   i_shortcuts = 0;
292     char *psz_shortcuts = NULL, *psz_var = NULL;
293
294     msg_Dbg( p_this, "looking for %s module", psz_capability );
295
296     /* Deal with variables */
297     if( psz_name && psz_name[0] == '$' )
298     {
299         psz_var = config_GetPsz( p_this, psz_name + 1 );
300         psz_name = psz_var;
301     }
302
303     /* Count how many different shortcuts were asked for */
304     if( psz_name && *psz_name )
305     {
306         char *psz_parser;
307
308         /* If the user wants none, give him none. */
309         if( !strcmp( psz_name, "none" ) )
310         {
311             if( psz_var ) free( psz_var );
312             return NULL;
313         }
314
315         i_shortcuts++;
316         psz_shortcuts = strdup( psz_name );
317
318         for( psz_parser = psz_shortcuts; *psz_parser; psz_parser++ )
319         {
320             if( *psz_parser == ',' )
321             {
322                  *psz_parser = '\0';
323                  i_shortcuts++;
324             }
325         }
326     }
327
328     /* We take the global lock */
329     vlc_mutex_lock( &p_this->p_vlc->p_module_bank->lock );
330
331     /* Sort the modules and test them */
332     p_list = malloc( p_this->p_vlc->p_module_bank->i_count
333                       * sizeof( module_list_t ) );
334     p_first = NULL;
335
336     /* Parse the module list for capabilities and probe each of them */
337     for( p_module = p_this->p_vlc->p_module_bank->first ;
338          p_module != NULL ;
339          p_module = p_module->next )
340     {
341         module_t * p_submodule = NULL;
342         int i_shortcut_bonus = 0, i_submodule;
343
344         /* Test that this module can do what we need */
345         if( strcmp( p_module->psz_capability, psz_capability ) )
346         {
347             for( i_submodule = 0;
348                  i_submodule < p_module->i_children;
349                  i_submodule++ )
350             {
351                 if( !strcmp( ((module_t*)p_module->pp_children[ i_submodule ])
352                                            ->psz_capability, psz_capability ) )
353                 {
354                     p_submodule =
355                             (module_t*)p_module->pp_children[ i_submodule ];
356                     p_submodule->next = p_module->next;
357                     break;
358                 }
359             }
360
361             if( p_submodule == NULL )
362             {
363                 continue;
364             }
365
366             p_module = p_submodule;
367         }
368
369         /* Test if we have the required CPU */
370         if( (p_module->i_cpu & p_this->p_vlc->i_cpu) != p_module->i_cpu )
371         {
372             continue;
373         }
374
375         /* If we required a shortcut, check this plugin provides it. */
376         if( i_shortcuts )
377         {
378             vlc_bool_t b_trash = VLC_TRUE;
379             int i_dummy, i_short = i_shortcuts;
380             char *psz_name = psz_shortcuts;
381
382             while( i_short )
383             {
384                 for( i_dummy = 0;
385                      b_trash && p_module->pp_shortcuts[i_dummy];
386                      i_dummy++ )
387                 {
388                     b_trash = ( strcmp(psz_name, "any") || !p_module->i_score )
389                         && strcmp( psz_name, p_module->pp_shortcuts[i_dummy] );
390                 }
391
392                 if( !b_trash )
393                 {
394                     i_shortcut_bonus = i_short * 10000;
395                     break;
396                 }
397
398                 /* Go to the next shortcut... This is so lame! */
399                 while( *psz_name )
400                 {
401                     psz_name++;
402                 }
403                 psz_name++;
404                 i_short--;
405             }
406
407             if( b_trash )
408             {
409                 continue;
410             }
411         }
412         /* If we didn't require a shortcut, trash zero-scored plugins */
413         else if( !p_module->i_score )
414         {
415             continue;
416         }
417
418         /* Special case: test if we requested a particular intf plugin */
419         if( p_module->psz_program
420              && !strcmp( p_module->psz_program,
421                          p_this->p_vlc->psz_object_name ) )
422         {
423             if( !b_intf ) 
424             {
425                 /* Remove previous non-matching plugins */
426                 i_index = 0;
427                 b_intf = VLC_TRUE;
428             }
429         }
430         else if( b_intf )
431         {
432             /* This one doesn't match */
433             continue;
434         }
435
436         /* Store this new module */
437         p_list[ i_index ].p_module = p_module;
438         p_list[ i_index ].i_score = p_module->i_score + i_shortcut_bonus;
439
440         /* Add it to the modules-to-probe list */
441         if( i_index == 0 )
442         {
443             p_list[ 0 ].p_next = NULL;
444             p_first = p_list;
445         }
446         else
447         {
448             /* Ok, so at school you learned that quicksort is quick, and
449              * bubble sort sucks raw eggs. But that's when dealing with
450              * thousands of items. Here we have barely 50. */
451             module_list_t *p_newlist = p_first;
452
453             if( p_first->i_score < p_list[ i_index ].i_score )
454             {
455                 p_list[ i_index ].p_next = p_first;
456                 p_first = &p_list[ i_index ];
457             }
458             else
459             {
460                 while( p_newlist->p_next != NULL &&
461                     p_newlist->p_next->i_score >= p_list[ i_index ].i_score )
462                 {
463                     p_newlist = p_newlist->p_next;
464                 }
465
466                 p_list[ i_index ].p_next = p_newlist->p_next;
467                 p_newlist->p_next = &p_list[ i_index ];
468             }
469         }
470
471         i_index++;
472     }
473
474     msg_Dbg( p_this, "probing %i candidate%s",
475                      i_index, i_index == 1 ? "" : "s" );
476
477     /* Lock all selected modules */
478     p_tmp = p_first;
479     while( p_tmp != NULL )
480     {
481         LockModule( p_tmp->p_module );
482         p_tmp = p_tmp->p_next;
483     }
484
485     /* We can release the global lock, module refcounts were incremented */
486     vlc_mutex_unlock( &p_this->p_vlc->p_module_bank->lock );
487
488     /* Parse the linked list and use the first successful module */
489     p_tmp = p_first;
490     while( p_tmp != NULL )
491     {
492         if( p_tmp->p_module->pf_activate
493              && p_tmp->p_module->pf_activate( p_this ) == VLC_SUCCESS )
494         {
495             break;
496         }
497
498         UnlockModule( p_tmp->p_module );
499         p_tmp = p_tmp->p_next;
500     }
501
502     /* Store the locked module value */
503     if( p_tmp != NULL )
504     {
505         p_module = p_tmp->p_module;
506         p_tmp = p_tmp->p_next;
507     }
508     else
509     {
510         p_module = NULL;
511     }
512
513     /* Unlock the remaining modules */
514     while( p_tmp != NULL )
515     {
516         UnlockModule( p_tmp->p_module );
517         p_tmp = p_tmp->p_next;
518     }
519
520     free( p_list );
521
522     if( p_module != NULL )
523     {
524         msg_Info( p_module, "using %s module \"%s\"",
525                   psz_capability, p_module->psz_object_name );
526     }
527     else if( p_first == NULL )
528     {
529         msg_Err( p_this, "no %s module matched \"%s\"",
530                  psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
531     }
532     else if( psz_name != NULL && *psz_name )
533     {
534         msg_Err( p_this, "no %s module matching \"%s\" could be loaded",
535                  psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
536     }
537
538     if( psz_shortcuts )
539     {
540         free( psz_shortcuts );
541     }
542
543     if( psz_var )
544     {
545         free( psz_var );
546     }
547
548     /* Don't forget that the module is still locked */
549     return p_module;
550 }
551
552 /*****************************************************************************
553  * module_Unneed: decrease the usage count of a module.
554  *****************************************************************************
555  * This function must be called by the thread that called module_Need, to
556  * decrease the reference count and allow for hiding of modules.
557  *****************************************************************************/
558 void __module_Unneed( vlc_object_t * p_this, module_t * p_module )
559 {
560     /* Use the close method */
561     if( p_module->pf_deactivate )
562     {
563         p_module->pf_deactivate( p_this );
564     }
565
566     /* We take the global lock */
567     vlc_mutex_lock( &p_module->p_vlc->p_module_bank->lock );
568
569     /* Just unlock the module - we can't do anything if it fails,
570      * so there is no need to check the return value. */
571     UnlockModule( p_module );
572
573     msg_Info( p_module, "unlocking module \"%s\"", p_module->psz_object_name );
574
575     /* We release the global lock */
576     vlc_mutex_unlock( &p_module->p_vlc->p_module_bank->lock );
577
578     return;
579 }
580
581 /*****************************************************************************
582  * Following functions are local.
583  *****************************************************************************/
584
585 /*****************************************************************************
586  * AllocateAllPlugins: load all plugin modules we can find.
587  *****************************************************************************/
588 #ifdef HAVE_DYNAMIC_PLUGINS
589 static void AllocateAllPlugins( vlc_object_t *p_this )
590 {
591     /* Yes, there are two NULLs because we replace one with "plugin-path". */
592     char *          path[] = { "modules", PLUGIN_PATH, NULL, NULL };
593
594     char **         ppsz_path = path;
595     char *          psz_fullpath;
596 #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
597     char *          psz_vlcpath = system_GetProgramPath();
598     int             i_vlclen = strlen( psz_vlcpath );
599     vlc_bool_t      b_notinroot;
600 #endif
601
602     /* If the user provided a plugin path, we add it to the list */
603     path[ sizeof(path)/sizeof(char*) - 2 ] = config_GetPsz( p_this,
604                                                             "plugin-path" );
605
606     for( ; *ppsz_path != NULL ; ppsz_path++ )
607     {
608 #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
609         /* Store strlen(*ppsz_path) for later use. */
610         int i_dirlen = strlen( *ppsz_path );
611
612         b_notinroot = VLC_FALSE;
613         /* Under BeOS, we need to add beos_GetProgramPath() to access
614          * files under the current directory */
615         if( ( i_dirlen > 1 ) && strncmp( *ppsz_path, "/", 1 ) )
616         {
617             i_dirlen += i_vlclen + 2;
618             b_notinroot = VLC_TRUE;
619
620             psz_fullpath = malloc( i_dirlen );
621             if( psz_fullpath == NULL )
622             {
623                 continue;
624             }
625             sprintf( psz_fullpath, "%s/%s", psz_vlcpath, *ppsz_path );
626         }
627         else
628 #endif
629         {
630             psz_fullpath = *ppsz_path;
631         }
632
633         msg_Dbg( p_this, "recursively browsing `%s'", psz_fullpath );
634
635         /* Don't go deeper than 5 subdirectories */
636         AllocatePluginDir( p_this, psz_fullpath, 5 );
637
638 #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
639         if( b_notinroot )
640         {
641             free( psz_fullpath );
642         }
643 #endif
644     }
645 }
646
647 /*****************************************************************************
648  * AllocatePluginDir: recursively parse a directory to look for plugins
649  *****************************************************************************/
650 static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
651                                int i_maxdepth )
652 {
653 #define PLUGIN_EXT ".so"
654     int    i_dirlen;
655     DIR *  dir;
656     char * psz_file;
657
658     struct dirent * file;
659
660     if( i_maxdepth < 0 )
661     {
662         return;
663     }
664
665     dir = opendir( psz_dir );
666
667     if( !dir )
668     {
669         return;
670     }
671
672     i_dirlen = strlen( psz_dir );
673
674     /* Parse the directory and try to load all files it contains. */
675     while( (file = readdir( dir )) )
676     {
677         struct stat statbuf;
678         int i_len = strlen( file->d_name );
679
680         /* Skip ".", ".." and anything starting with "." */
681         if( !*file->d_name || *file->d_name == '.' )
682         {
683             continue;
684         }
685
686         psz_file = malloc( i_dirlen + 1 /* / */ + i_len + 1 /* \0 */ );
687         sprintf( psz_file, "%s/%s", psz_dir, file->d_name );
688
689         if( !stat( psz_file, &statbuf ) && statbuf.st_mode & S_IFDIR )
690         {
691             AllocatePluginDir( p_this, psz_file, i_maxdepth - 1 );
692         }
693         else if( i_len > strlen( PLUGIN_EXT )
694                   /* We only load files ending with ".so" */
695                   && !strncmp( file->d_name + i_len - strlen( PLUGIN_EXT ),
696                                PLUGIN_EXT, strlen( PLUGIN_EXT ) ) )
697         {
698             AllocatePluginFile( p_this, psz_file );
699         }
700
701         free( psz_file );
702     }
703
704     /* Close the directory */
705     closedir( dir );
706 }
707
708 /*****************************************************************************
709  * AllocatePluginFile: load a module into memory and initialize it.
710  *****************************************************************************
711  * This function loads a dynamically loadable module and allocates a structure
712  * for its information data. The module can then be handled by module_Need,
713  * module_Unneed and HideModule. It can be removed by DeleteModule.
714  *****************************************************************************/
715 static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
716 {
717     module_t * p_module;
718     module_handle_t handle;
719
720     /* Try to dynamically load the module. */
721     if( module_load( psz_file, &handle ) )
722     {
723         char psz_buffer[256];
724
725         /* The plugin module couldn't be opened */
726         msg_Warn( p_this, "cannot open `%s' (%s)",
727                   psz_file, module_error( psz_buffer ) );
728         return -1;
729     }
730
731     /* Now that we have successfully loaded the module, we can
732      * allocate a structure for it */ 
733     p_module = vlc_object_create( p_this, VLC_OBJECT_MODULE );
734     if( p_module == NULL )
735     {
736         msg_Err( p_this, "out of memory" );
737         module_unload( handle );
738         return -1;
739     }
740
741     /* We need to fill these since they may be needed by CallEntry() */
742     p_module->psz_filename = psz_file;
743     p_module->handle = handle;
744     p_module->p_symbols = &p_this->p_vlc->p_module_bank->symbols;
745
746     /* Initialize the module: fill p_module->psz_object_name, default config */
747     if( CallEntry( p_module ) != 0 )
748     {
749         /* We couldn't call module_init() */
750         vlc_object_destroy( p_module );
751         module_unload( handle );
752         return -1;
753     }
754
755     DupModule( p_module );
756     p_module->psz_filename = strdup( p_module->psz_filename );
757     p_module->psz_longname = strdup( p_module->psz_longname );
758
759     /* Everything worked fine ! The module is ready to be added to the list. */
760     p_module->i_usage = 0;
761     p_module->i_unused_delay = 0;
762
763     p_module->b_builtin = VLC_FALSE;
764
765     /* Link module into the linked list */
766     if( p_this->p_vlc->p_module_bank->first != NULL )
767     {
768         p_this->p_vlc->p_module_bank->first->prev = p_module;
769     }
770     p_module->next = p_this->p_vlc->p_module_bank->first;
771     p_module->prev = NULL;
772     p_this->p_vlc->p_module_bank->first = p_module;
773     p_this->p_vlc->p_module_bank->i_count++;
774
775     /* msg_Dbg( p_this, "plugin \"%s\", %s",
776                 p_module->psz_object_name, p_module->psz_longname ); */
777
778     vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
779
780     return 0;
781 }
782
783 /*****************************************************************************
784  * DupModule: make a plugin module standalone.
785  *****************************************************************************
786  * This function duplicates all strings in the module, so that the dynamic
787  * object can be unloaded. It acts recursively on submodules.
788  *****************************************************************************/
789 static void DupModule( module_t *p_module )
790 {
791     char **pp_shortcut;
792     int i_submodule;
793
794     for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ )
795     {
796         *pp_shortcut = strdup( *pp_shortcut );
797     }
798
799     /* We strdup() these entries so that they are still valid when the
800      * module is unloaded. */
801     p_module->psz_object_name = strdup( p_module->psz_object_name );
802     p_module->psz_capability = strdup( p_module->psz_capability );
803
804     if( p_module->psz_program != NULL )
805     {
806         p_module->psz_program = strdup( p_module->psz_program );
807     }
808
809     for( i_submodule = 0; i_submodule < p_module->i_children; i_submodule++ )
810     {
811         DupModule( (module_t*)p_module->pp_children[ i_submodule ] );
812     }
813 }
814
815 /*****************************************************************************
816  * UndupModule: free a duplicated module.
817  *****************************************************************************
818  * This function frees the allocations done in DupModule().
819  *****************************************************************************/
820 static void UndupModule( module_t *p_module )
821 {
822     char **pp_shortcut;
823     int i_submodule;
824
825     for( i_submodule = 0; i_submodule < p_module->i_children; i_submodule++ )
826     {
827         UndupModule( (module_t*)p_module->pp_children[ i_submodule ] );
828     }
829
830     for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ )
831     {
832         free( *pp_shortcut );
833     }
834
835     free( p_module->psz_object_name );
836     free( p_module->psz_capability );
837
838     if( p_module->psz_program != NULL )
839     {
840         free( p_module->psz_program );
841     }
842 }
843
844 #endif /* HAVE_DYNAMIC_PLUGINS */
845
846 /*****************************************************************************
847  * AllocateBuiltinModule: initialize a builtin module.
848  *****************************************************************************
849  * This function registers a builtin module and allocates a structure
850  * for its information data. The module can then be handled by module_Need,
851  * module_Unneed and HideModule. It can be removed by DeleteModule.
852  *****************************************************************************/
853 static int AllocateBuiltinModule( vlc_object_t * p_this,
854                                   int ( *pf_entry ) ( module_t * ) )
855 {
856     module_t * p_module;
857
858     /* Now that we have successfully loaded the module, we can
859      * allocate a structure for it */ 
860     p_module = vlc_object_create( p_this, VLC_OBJECT_MODULE );
861     if( p_module == NULL )
862     {
863         msg_Err( p_this, "out of memory" );
864         return -1;
865     }
866
867     /* Initialize the module : fill p_module->psz_object_name, etc. */
868     if( pf_entry( p_module ) != 0 )
869     {
870         /* With a well-written module we shouldn't have to print an
871          * additional error message here, but just make sure. */
872         msg_Err( p_this, "failed calling entry point in builtin module" );
873         vlc_object_destroy( p_module );
874         return -1;
875     }
876
877     /* Everything worked fine ! The module is ready to be added to the list. */
878     p_module->i_usage = 0;
879     p_module->i_unused_delay = 0;
880
881     p_module->b_builtin = VLC_TRUE;
882
883     /* Link module into the linked list */
884     if( p_this->p_vlc->p_module_bank->first != NULL )
885     {
886         p_this->p_vlc->p_module_bank->first->prev = p_module;
887     }
888     p_module->next = p_this->p_vlc->p_module_bank->first;
889     p_module->prev = NULL;
890     p_this->p_vlc->p_module_bank->first = p_module;
891     p_this->p_vlc->p_module_bank->i_count++;
892
893     /* msg_Dbg( p_this, "builtin \"%s\", %s",
894                 p_module->psz_object_name, p_module->psz_longname ); */
895
896     vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
897
898     return 0;
899 }
900
901 /*****************************************************************************
902  * DeleteModule: delete a module and its structure.
903  *****************************************************************************
904  * This function can only be called if i_usage <= 0.
905  *****************************************************************************/
906 static int DeleteModule( module_t * p_module )
907 {
908     /* If the module is not in use but is still in memory, we first have
909      * to hide it and remove it from memory before we can free the
910      * data structure. */
911     if( p_module->b_builtin )
912     {
913         if( p_module->i_usage != 0 )
914         {
915             msg_Err( p_module, "trying to free builtin module \"%s\" with "
916                      "usage %i", p_module->psz_object_name, p_module->i_usage );
917             return -1;
918         }
919     }
920 #ifdef HAVE_DYNAMIC_PLUGINS
921     else
922     {
923         if( p_module->i_usage >= 1 )
924         {
925             msg_Err( p_module, "trying to free module \"%s\" which is "
926                                "still in use", p_module->psz_object_name );
927             return -1;
928         }
929
930         /* Two possibilities here: i_usage == -1 and the module is already
931          * unloaded, we can continue, or i_usage == 0, and we have to hide
932          * the module before going on. */
933         if( p_module->i_usage == 0 )
934         {
935             if( HideModule( p_module ) != 0 )
936             {
937                 return -1;
938             }
939         }
940     }
941 #endif
942
943     vlc_object_detach( p_module );
944
945     /* Unlink the module from the linked list. */
946     if( p_module->prev != NULL )
947     {
948         p_module->prev->next = p_module->next;
949     }
950     else
951     {
952         p_module->p_vlc->p_module_bank->first = p_module->next;
953     }
954
955     if( p_module->next != NULL )
956     {
957         p_module->next->prev = p_module->prev;
958     }
959
960     p_module->p_vlc->p_module_bank->i_count--;
961
962     /* We free the structures that we strdup()ed in Allocate*Module(). */
963 #ifdef HAVE_DYNAMIC_PLUGINS
964     if( !p_module->b_builtin )
965     {
966         UndupModule( p_module );
967         free( p_module->psz_filename );
968         free( p_module->psz_longname );
969     }
970 #endif
971
972     /* Free and detach the object's children */
973     while( p_module->i_children )
974     {
975         vlc_object_t *p_this = p_module->pp_children[0];
976         vlc_object_detach( p_this );
977         vlc_object_destroy( p_this );
978     }
979
980     config_Free( p_module );
981     vlc_object_destroy( p_module );
982
983     return 0;
984 }
985
986 /*****************************************************************************
987  * LockModule: increase the usage count of a module and load it if needed.
988  *****************************************************************************
989  * This function has to be called before a thread starts using a module. If
990  * the module is already loaded, we just increase its usage count. If it isn't
991  * loaded, we have to dynamically open it and initialize it.
992  * If you successfully call LockModule() at any moment, be careful to call
993  * UnlockModule() when you don't need it anymore.
994  *****************************************************************************/
995 static int LockModule( module_t * p_module )
996 {
997     if( p_module->i_usage >= 0 )
998     {
999         /* This module is already loaded and activated, we can return */
1000         p_module->i_usage++;
1001         return 0;
1002     }
1003
1004     if( p_module->b_builtin )
1005     {
1006         /* A builtin module should always have a refcount >= 0 ! */
1007         msg_Err( p_module, "builtin module \"%s\" has refcount %i",
1008                            p_module->psz_object_name, p_module->i_usage );
1009         return -1;
1010     }
1011
1012 #ifdef HAVE_DYNAMIC_PLUGINS
1013     if( p_module->i_usage != -1 )
1014     {
1015         /* This shouldn't happen. Ever. We have serious problems here. */
1016         msg_Err( p_module, "plugin module \"%s\" has refcount %i",
1017                            p_module->psz_object_name, p_module->i_usage );
1018         return -1;
1019     }
1020
1021     /* i_usage == -1, which means that the module isn't in memory */
1022     if( module_load( p_module->psz_filename, &p_module->handle ) )
1023     {
1024         char psz_buffer[256];
1025
1026         /* The plugin module couldn't be opened */
1027         msg_Err( p_module, "cannot open `%s' (%s)",
1028                  p_module->psz_filename, module_error(psz_buffer) );
1029         return -1;
1030     }
1031
1032     /* FIXME: what to do if the guy modified the plugin while it was
1033      * unloaded ? It makes XMMS crash nastily, perhaps we should try
1034      * to be a bit more clever here. */
1035
1036     /* Everything worked fine ! The module is ready to be used */
1037     p_module->i_usage = 1;
1038 #endif /* HAVE_DYNAMIC_PLUGINS */
1039
1040     return 0;
1041 }
1042
1043 /*****************************************************************************
1044  * UnlockModule: decrease the usage count of a module.
1045  *****************************************************************************
1046  * We decrease the usage count of a module so that we know when a module
1047  * becomes unused and can be hidden.
1048  *****************************************************************************/
1049 static int UnlockModule( module_t * p_module )
1050 {
1051     if( p_module->i_usage <= 0 )
1052     {
1053         /* This shouldn't happen. Ever. We have serious problems here. */
1054         msg_Err( p_module, "trying to call module_Unneed() on \"%s\" "
1055                            "which is not in use", p_module->psz_object_name );
1056         return -1;
1057     }
1058
1059     /* This module is still in use, we can return */
1060     p_module->i_usage--;
1061     p_module->i_unused_delay = 0;
1062
1063     return 0;
1064 }
1065
1066 #ifdef HAVE_DYNAMIC_PLUGINS
1067 /*****************************************************************************
1068  * HideModule: remove a module from memory but keep its structure.
1069  *****************************************************************************
1070  * This function can only be called if i_usage == 0. It will make a call
1071  * to the module's inner module_deactivate() symbol, and then unload it
1072  * from memory. A call to module_Need() will automagically load it again.
1073  *****************************************************************************/
1074 static int HideModule( module_t * p_module )
1075 {
1076     if( p_module->b_builtin )
1077     {
1078         /* A builtin module should never be hidden. */
1079         msg_Err( p_module, "trying to hide builtin module \"%s\"",
1080                            p_module->psz_object_name );
1081         return -1;
1082     }
1083
1084     if( p_module->i_usage >= 1 )
1085     {
1086         msg_Err( p_module, "trying to hide module \"%s\" which is still "
1087                            "in use", p_module->psz_object_name );
1088         return -1;
1089     }
1090
1091     if( p_module->i_usage <= -1 )
1092     {
1093         msg_Err( p_module, "trying to hide module \"%s\" which is already "
1094                            "hidden", p_module->psz_object_name );
1095         return -1;
1096     }
1097
1098     /* Everything worked fine, we can safely unload the module. */
1099     module_unload( p_module->handle );
1100     p_module->i_usage = -1;
1101
1102     return 0;
1103 }
1104
1105 /*****************************************************************************
1106  * CallEntry: call an entry point.
1107  *****************************************************************************
1108  * This function calls a symbol given its name and a module structure. The
1109  * symbol MUST refer to a function returning int and taking a module_t* as
1110  * an argument.
1111  *****************************************************************************/
1112 static int CallEntry( module_t * p_module )
1113 {
1114     static char *psz_name = "vlc_entry" MODULE_SUFFIX;
1115     int (* pf_symbol) ( module_t * p_module );
1116
1117     /* Try to resolve the symbol */
1118     pf_symbol = (int (*)(module_t *)) module_getsymbol( p_module->handle, 
1119                                                         psz_name );
1120
1121     if( pf_symbol == NULL )
1122     {
1123         char psz_buffer[256];
1124
1125         /* We couldn't load the symbol */
1126         msg_Warn( p_module, "cannot find symbol \"%s\" in file `%s' (%s)",
1127                             psz_name, p_module->psz_filename,
1128                             module_error( psz_buffer ) );
1129         return -1;
1130     }
1131
1132     /* We can now try to call the symbol */
1133     if( pf_symbol( p_module ) != 0 )
1134     {
1135         /* With a well-written module we shouldn't have to print an
1136          * additional error message here, but just make sure. */
1137         msg_Err( p_module, "failed calling symbol \"%s\" in file `%s'",
1138                            psz_name, p_module->psz_filename );
1139         return -1;
1140     }
1141
1142     /* Everything worked fine, we can return */
1143     return 0;
1144 }
1145 #endif /* HAVE_DYNAMIC_PLUGINS */
1146