/[m4]/m4/m4/module.c
ViewVC logotype

Diff of /m4/m4/module.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by gary, Thu Sep 20 03:48:05 2001 UTC revision 1.13 by gary, Sun Sep 30 14:43:38 2001 UTC
# Line 59  Line 59 
59   * names to the expansion text.  Any macros defined in `m4_macro_table'   * names to the expansion text.  Any macros defined in `m4_macro_table'
60   * are installed into the M4 symbol table with m4_macro_table_install().   * are installed into the M4 symbol table with m4_macro_table_install().
61   *   *
62   * Each time a module is loaded, the module function   * Each time a module is loaded, the module function
63   * "void m4_init_module (lt_dlhandle handle, struct obstack *obs)" is   * "void m4_init_module (lt_dlhandle handle, struct obstack *obs)" is
64   * called, if defined.  Any value stored in OBS by this function becomes   * called, if defined.  Any value stored in OBS by this function becomes
65   * the expansion of the macro which called it.  Before M4 exits, all   * the expansion of the macro which called it.  Before M4 exits, all
66   * modules are unloaded and the function   * modules are unloaded and the function
67   * "void m4_finish_module (lt_dlhandle handle, struct obstack *obs)" is   * "void m4_finish_module (lt_dlhandle handle, struct obstack *obs)" is
68   * called, if defined.  It is safe to load the same module several times:   * called, if defined.  It is safe to load the same module several times:
69   * the init and finish functions will also be called multiple times in   * the init and finish functions will also be called multiple times in
70   * this case.   * this case.
71   *   *
72   * To unload a module, use m4_module_unload(). which uses   * To unload a module, use m4_module_unload(). which uses
# Line 83  Line 83 
83  #define M4_FINISH_SYMBOL        "m4_finish_module"  #define M4_FINISH_SYMBOL        "m4_finish_module"
84    
85  static const char*  m4_module_dlerror   (void);  static const char*  m4_module_dlerror   (void);
 static int          m4_module_remove    (lt_dlhandle handle,  
                                          struct obstack *obs);  
86    
87  static lt_dlcaller_id m4_caller_id = 0;  static lt_dlcaller_id m4_caller_id = 0;
88    
# Line 169  void Line 167  void
167  m4_module_init (void)  m4_module_init (void)
168  {  {
169    int errors = 0;    int errors = 0;
170      
171    /* Do this only once!  If we already have a caller_id, then the    /* Do this only once!  If we already have a caller_id, then the
172       module system has already been initialised.  */       module system has already been initialised.  */
173    if (m4_caller_id)    if (m4_caller_id)
# Line 179  m4_module_init (void) Line 177  m4_module_init (void)
177        return;        return;
178      }      }
179    
 #if !WITH_DMALLOC  
180    /* initialise libltdl's memory management. */    /* initialise libltdl's memory management. */
181    lt_dlmalloc = xmalloc;    lt_dlmalloc = xmalloc;
182    lt_dlfree   = (void (*)(void*)) xfree;    lt_dlfree   = (void (*)(void*)) xfree;
 #endif  
183    
184    errors      = lt_dlinit ();    errors      = lt_dlinit ();
185    
# Line 205  m4_module_init (void) Line 201  m4_module_init (void)
201            ++errors;            ++errors;
202          }          }
203      }      }
204      
205    if (!errors)    if (!errors)
206      errors = lt_dlsetsearchpath (MODULE_PATH);      errors = lt_dlsetsearchpath (MODULE_PATH);
207    
# Line 294  m4_module_open (const char *name, struct Line 290  m4_module_open (const char *name, struct
290    if (handle)    if (handle)
291      {      {
292        const lt_dlinfo  *info    = lt_dlgetinfo (handle);        const lt_dlinfo  *info    = lt_dlgetinfo (handle);
293          
294        if (info && (info->ref_count == 1))        if (info && (info->ref_count == 1))
295          {          {
296            m4_module_data *data  = XMALLOC (m4_module_data, 1);            m4_module_data *data  = XMALLOC (m4_module_data, 1);
# Line 308  m4_module_open (const char *name, struct Line 304  m4_module_open (const char *name, struct
304            if (stale)            if (stale)
305              {              {
306                xfree (stale);                xfree (stale);
307              
308                M4ERROR ((warning_status, 0,                M4ERROR ((warning_status, 0,
309                          _("Warning: overiding stale caller data in module `%s'"),                          _("Warning: overiding stale caller data in module `%s'"),
310                          name));                          name));
# Line 327  void Line 323  void
323  m4_module_close (lt_dlhandle handle, struct obstack *obs)  m4_module_close (lt_dlhandle handle, struct obstack *obs)
324  {  {
325    m4_module_finish_func *finish_func    = 0;    m4_module_finish_func *finish_func    = 0;
326    char                  *name           = 0;    const char            *name           = 0;
327    int                    errors         = 0;    int                    errors         = 0;
328      
329    assert (handle);    assert (handle);
330    name = xstrdup (m4_module_name (handle));    name = m4_module_name (handle);
331    
332    /* Run any finishing function for the opened module. */    /* Run any finishing function for the opened module. */
333    finish_func = (m4_module_finish_func *) lt_dlsym (handle, M4_FINISH_SYMBOL);    finish_func = (m4_module_finish_func *) lt_dlsym (handle, M4_FINISH_SYMBOL);
# Line 344  m4_module_close (lt_dlhandle handle, str Line 340  m4_module_close (lt_dlhandle handle, str
340        M4_DEBUG_MESSAGE1("module %s: finish hook called", name);        M4_DEBUG_MESSAGE1("module %s: finish hook called", name);
341  #endif /* DEBUG_MODULES */  #endif /* DEBUG_MODULES */
342      }      }
343          
344    if (!lt_dlisresident (handle))    if (!lt_dlisresident (handle))
345      {      {
346        const lt_dlinfo  *info    = lt_dlgetinfo (handle);        {
347            const lt_dlinfo  *info  = lt_dlgetinfo (handle);
348    
349        /* When we are about to unload the module for the final          /* When we are about to unload the module for the final
350           time, be sure to release any client data memory.  */             time, be sure to release any client data memory.  */
351        if (info && (info->ref_count == 1))          if (info && (info->ref_count == 1))
352          {            {
353            m4_module_data *stale              m4_module_data *stale
354              = lt_dlcaller_set_data (m4_caller_id, handle, 0);                = lt_dlcaller_set_data (m4_caller_id, handle, 0);
355            XFREE (stale);              xfree (stale);
356          }            }
357          }
358    
359        errors = lt_dlclose (handle);        errors = lt_dlclose (handle);
360        if (!errors)        if (!errors)
# Line 366  m4_module_close (lt_dlhandle handle, str Line 364  m4_module_close (lt_dlhandle handle, str
364  #endif /* DEBUG_MODULES */  #endif /* DEBUG_MODULES */
365          }          }
366      }      }
 #ifdef DEBUG_MODULES  
   else  
     M4_DEBUG_MESSAGE1("module %s: resident module not closed", name);  
 #endif /* DEBUG_MODULES */  
367    
368    if (errors)    if (errors)
369      {      {
# Line 377  m4_module_close (lt_dlhandle handle, str Line 371  m4_module_close (lt_dlhandle handle, str
371                  _("ERROR: cannot close module `%s': %s"),                  _("ERROR: cannot close module `%s': %s"),
372                  name, m4_module_dlerror ()));                  name, m4_module_dlerror ()));
373      }      }
   
   xfree (name);  
374  }  }
375    
376  void  void
# Line 392  m4_module_close_all (struct obstack *obs Line 384  m4_module_close_all (struct obstack *obs
384           closed, even to find the address of the next handle.  */           closed, even to find the address of the next handle.  */
385        lt_dlhandle pending = handle;        lt_dlhandle pending = handle;
386        handle = lt_dlhandle_next (handle);        handle = lt_dlhandle_next (handle);
 #ifdef DEBUG_MODULES  
       M4_DEBUG_MESSAGE1("module %s: attempting module close",  
                         m4_module_name (pending));  
 #endif /* DEBUG_MODULES */  
387        m4_module_close (pending, obs);        m4_module_close (pending, obs);
388      }      }
389    
# Line 450  m4_module_load (const char *name, struct Line 438  m4_module_load (const char *name, struct
438    return handle;    return handle;
439  }  }
440    
 int  
 m4_module_remove (lt_dlhandle handle, struct obstack *obs)  
 {  
   const lt_dlinfo *info         = 0;  
   int              errors       = 0;  
   
   assert (handle);  
   
   info = lt_dlgetinfo (handle);  
   
   /* Only do the actual close when the number of calls to close this  
      module is equal to the number of times it was opened. */  
 #ifdef DEBUG_MODULES  
   if (info->ref_count > 1)  
     {  
       M4_DEBUG_MESSAGE2("module %s: now has %d references.",  
                         m4_module_name (handle), info->ref_count -1);  
     }  
 #endif /* DEBUG_MODULES */  
   
   if (info->ref_count == 1)  
     {  
       /* Remove the table references only when ref_count is *exactly*  
          equal to 1.  If m4_module_close is called again on a  
          resident module after the references have already been  
          removed, we needn't try to remove them again!  */  
       m4_symtab_remove_module_references (handle);  
   
 #ifdef DEBUG_MODULES  
       M4_DEBUG_MESSAGE1("module %s: symbols unloaded",  
                         m4_module_name (handle));  
 #endif /* DEBUG_MODULES */  
     }  
   
   if (!errors)  
     m4_module_close (handle, obs);  
   
   return errors;  
 }  
   
441  /* Unload a module.  */  /* Unload a module.  */
442  void  void
443  m4_module_unload (const char *name, struct obstack *obs)  m4_module_unload (const char *name, struct obstack *obs)
# Line 512  m4_module_unload (const char *name, stru Line 460  m4_module_unload (const char *name, stru
460        ++errors;        ++errors;
461      }      }
462    else    else
     errors = m4_module_remove (handle, obs);  
   
   if (errors)  
     {  
       M4ERROR ((EXIT_FAILURE, 0,  
                 _("ERROR: cannot unload module `%s': %s"),  
                 name, m4_module_dlerror ()));  
     }  
 }  
   
 void  
 m4_module_unload_all (void)  
 {  
   lt_dlhandle   handle  = lt_dlhandle_next (0);  
   int           errors  = 0;  
   
   while (handle && !errors)  
463      {      {
464        lt_dlhandle      pending  = handle;        const lt_dlinfo *info = lt_dlgetinfo (handle);
       const lt_dlinfo *info     = lt_dlgetinfo (pending);  
465    
466        /* We are *really* shutting down here, so freeing the module        /* Only do the actual close when the number of calls to close this
467           data is required.  */           module is equal to the number of times it was opened. */
468        if (info)        if (info->ref_count > 1)
469          {          {
470            m4_module_data *stale  #ifdef DEBUG_MODULES
471              = lt_dlcaller_set_data (m4_caller_id, handle, 0);            M4_DEBUG_MESSAGE2("module %s: now has %d references.",
472            XFREE (stale);                              name, info->ref_count -1);
473    #endif /* DEBUG_MODULES */
474          }          }
475    
476        /* If we are about to unload the final reference, move on to the        if (info->ref_count == 1)
477           next handle before we unload the current one.  */          {
478        if (info->ref_count <= 1)            /* Remove the table references only when ref_count is *exactly*
479          handle = lt_dlhandle_next (pending);               equal to 1.  If m4_module_close is called again on a
480                 resident module after the references have already been
481                 removed, we needn't try to remove them again!  */
482              m4_symtab_remove_module_references (handle);
483    
484        errors = m4_module_remove (pending, 0);  #ifdef DEBUG_MODULES
485              M4_DEBUG_MESSAGE1("module %s: symbols unloaded", name);
486    #endif /* DEBUG_MODULES */
487            }
488      }      }
489    
490    if (!errors)    if (!errors)
491      errors = lt_dlexit();      m4_module_close (handle, obs);
492    
493    if (errors)    if (errors)
494      {      {
495        M4ERROR ((EXIT_FAILURE, 0,        M4ERROR ((EXIT_FAILURE, 0,
496                  _("ERROR: cannot unload all modules: %s"),                  _("ERROR: cannot unload module `%s': %s"),
497                  m4_module_dlerror ()));                  name, m4_module_dlerror ()));
498      }      }
499  }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26