/[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.13 by gary, Sun Sep 30 14:43:38 2001 UTC revision 1.14 by gary, Sun Sep 30 22:26:57 2001 UTC
# 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);
86    static int          m4_module_remove    (lt_dlhandle handle,
87                                             struct obstack *obs);
88    
89  static lt_dlcaller_id m4_caller_id = 0;  static lt_dlcaller_id m4_caller_id = 0;
90    
# Line 177  m4_module_init (void) Line 179  m4_module_init (void)
179        return;        return;
180      }      }
181    
182    #if !WITH_DMALLOC
183    /* initialise libltdl's memory management. */    /* initialise libltdl's memory management. */
184    lt_dlmalloc = xmalloc;    lt_dlmalloc = xmalloc;
185    lt_dlfree   = (void (*)(void*)) xfree;    lt_dlfree   = (void (*)(void*)) xfree;
186    #endif
187    
188    errors      = lt_dlinit ();    errors      = lt_dlinit ();
189    
# Line 323  void Line 327  void
327  m4_module_close (lt_dlhandle handle, struct obstack *obs)  m4_module_close (lt_dlhandle handle, struct obstack *obs)
328  {  {
329    m4_module_finish_func *finish_func    = 0;    m4_module_finish_func *finish_func    = 0;
330    const char            *name           = 0;    char                  *name           = 0;
331    int                    errors         = 0;    int                    errors         = 0;
332      
333    assert (handle);    assert (handle);
334    name = m4_module_name (handle);    name = xstrdup (m4_module_name (handle));
335    
336    /* Run any finishing function for the opened module. */    /* Run any finishing function for the opened module. */
337    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 343  m4_module_close (lt_dlhandle handle, str Line 347  m4_module_close (lt_dlhandle handle, str
347                
348    if (!lt_dlisresident (handle))    if (!lt_dlisresident (handle))
349      {      {
350        {        const lt_dlinfo  *info    = lt_dlgetinfo (handle);
         const lt_dlinfo  *info  = lt_dlgetinfo (handle);  
351    
352          /* When we are about to unload the module for the final        /* When we are about to unload the module for the final
353             time, be sure to release any client data memory.  */           time, be sure to release any client data memory.  */
354          if (info && (info->ref_count == 1))        if (info && (info->ref_count == 1))
355            {          {
356              m4_module_data *stale            m4_module_data *stale
357                = lt_dlcaller_set_data (m4_caller_id, handle, 0);              = lt_dlcaller_set_data (m4_caller_id, handle, 0);
358              xfree (stale);            XFREE (stale);
359            }          }
       }  
360    
361        errors = lt_dlclose (handle);        errors = lt_dlclose (handle);
362        if (!errors)        if (!errors)
# Line 364  m4_module_close (lt_dlhandle handle, str Line 366  m4_module_close (lt_dlhandle handle, str
366  #endif /* DEBUG_MODULES */  #endif /* DEBUG_MODULES */
367          }          }
368      }      }
369    #ifdef DEBUG_MODULES
370      else
371        M4_DEBUG_MESSAGE1("module %s: resident module not closed", name);
372    #endif /* DEBUG_MODULES */
373    
374    if (errors)    if (errors)
375      {      {
# Line 371  m4_module_close (lt_dlhandle handle, str Line 377  m4_module_close (lt_dlhandle handle, str
377                  _("ERROR: cannot close module `%s': %s"),                  _("ERROR: cannot close module `%s': %s"),
378                  name, m4_module_dlerror ()));                  name, m4_module_dlerror ()));
379      }      }
380      
381      xfree (name);
382  }  }
383    
384  void  void
# Line 384  m4_module_close_all (struct obstack *obs Line 392  m4_module_close_all (struct obstack *obs
392           closed, even to find the address of the next handle.  */           closed, even to find the address of the next handle.  */
393        lt_dlhandle pending = handle;        lt_dlhandle pending = handle;
394        handle = lt_dlhandle_next (handle);        handle = lt_dlhandle_next (handle);
395    #ifdef DEBUG_MODULES
396          M4_DEBUG_MESSAGE1("module %s: attempting module close",
397                            m4_module_name (pending));
398    #endif /* DEBUG_MODULES */
399        m4_module_close (pending, obs);        m4_module_close (pending, obs);
400      }      }
401    
# Line 438  m4_module_load (const char *name, struct Line 450  m4_module_load (const char *name, struct
450    return handle;    return handle;
451  }  }
452    
453    int
454    m4_module_remove (lt_dlhandle handle, struct obstack *obs)
455    {
456      const lt_dlinfo *info         = 0;
457      int              errors       = 0;
458    
459      assert (handle);
460    
461      info = lt_dlgetinfo (handle);
462    
463      /* Only do the actual close when the number of calls to close this
464         module is equal to the number of times it was opened. */
465    #ifdef DEBUG_MODULES
466      if (info->ref_count > 1)
467        {
468          M4_DEBUG_MESSAGE2("module %s: now has %d references.",
469                            m4_module_name (handle), info->ref_count -1);
470        }
471    #endif /* DEBUG_MODULES */
472    
473      if (info->ref_count == 1)
474        {
475          /* Remove the table references only when ref_count is *exactly*
476             equal to 1.  If m4_module_close is called again on a
477             resident module after the references have already been
478             removed, we needn't try to remove them again!  */
479          m4_symtab_remove_module_references (handle);
480    
481    #ifdef DEBUG_MODULES
482          M4_DEBUG_MESSAGE1("module %s: symbols unloaded",
483                            m4_module_name (handle));
484    #endif /* DEBUG_MODULES */
485        }
486    
487      if (!errors)
488        m4_module_close (handle, obs);
489    
490      return errors;
491    }
492    
493  /* Unload a module.  */  /* Unload a module.  */
494  void  void
495  m4_module_unload (const char *name, struct obstack *obs)  m4_module_unload (const char *name, struct obstack *obs)
# Line 460  m4_module_unload (const char *name, stru Line 512  m4_module_unload (const char *name, stru
512        ++errors;        ++errors;
513      }      }
514    else    else
515        errors = m4_module_remove (handle, obs);
516    
517      if (errors)
518      {      {
519        const lt_dlinfo *info = lt_dlgetinfo (handle);        M4ERROR ((EXIT_FAILURE, 0,
520                    _("ERROR: cannot unload module `%s': %s"),
521                    name, m4_module_dlerror ()));
522        }
523    }
524    
525    void
526    m4_module_unload_all (void)
527    {
528      lt_dlhandle   handle  = lt_dlhandle_next (0);
529      int           errors  = 0;
530    
531      while (handle && !errors)
532        {
533          lt_dlhandle      pending  = handle;
534          const lt_dlinfo *info     = lt_dlgetinfo (pending);
535    
536        /* Only do the actual close when the number of calls to close this        /* We are *really* shutting down here, so freeing the module
537           module is equal to the number of times it was opened. */           data is required.  */
538        if (info->ref_count > 1)        if (info)
539          {          {
540  #ifdef DEBUG_MODULES            m4_module_data *stale
541            M4_DEBUG_MESSAGE2("module %s: now has %d references.",              = lt_dlcaller_set_data (m4_caller_id, handle, 0);
542                              name, info->ref_count -1);            XFREE (stale);
 #endif /* DEBUG_MODULES */  
543          }          }
544    
545        if (info->ref_count == 1)        /* If we are about to unload the final reference, move on to the
546          {           next handle before we unload the current one.  */
547            /* Remove the table references only when ref_count is *exactly*        if (info->ref_count <= 1)
548               equal to 1.  If m4_module_close is called again on a          handle = lt_dlhandle_next (pending);
              resident module after the references have already been  
              removed, we needn't try to remove them again!  */  
           m4_symtab_remove_module_references (handle);  
549    
550  #ifdef DEBUG_MODULES        errors = m4_module_remove (pending, 0);
           M4_DEBUG_MESSAGE1("module %s: symbols unloaded", name);  
 #endif /* DEBUG_MODULES */  
         }  
551      }      }
552    
553    if (!errors)    if (!errors)
554      m4_module_close (handle, obs);      errors = lt_dlexit();
555    
556    if (errors)    if (errors)
557      {      {
558        M4ERROR ((EXIT_FAILURE, 0,        M4ERROR ((EXIT_FAILURE, 0,
559                  _("ERROR: cannot unload module `%s': %s"),                  _("ERROR: cannot unload all modules: %s"),
560                  name, m4_module_dlerror ()));                  m4_module_dlerror ()));
561      }      }
562  }  }

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

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