Mercurial > hg > octave-nkf
diff liboctave/oct-shlib.h @ 9958:80432f0ee895
improve octave_shlib for safer shared libs treatment
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 10 Dec 2009 09:14:47 +0100 |
parents | eb63fbe60fab |
children | 14ed68363284 |
line wrap: on
line diff
--- a/liboctave/oct-shlib.h +++ b/liboctave/oct-shlib.h @@ -1,6 +1,7 @@ /* Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007, 2008 John W. Eaton +Copyright (C) 2009 VZLU Prague This file is part of Octave. @@ -24,43 +25,103 @@ #define octave_shlib_h 1 #include <string> +#include <map> #include "oct-time.h" -// This just provides a way to avoid infinite recursion when building -// octave_shlib objects. - -class -OCTAVE_API -octave_xshlib -{ -public: - - octave_xshlib (void) { } -}; - class OCTAVE_API octave_shlib { -public: +public: // FIXME: make this class private? typedef std::string (*name_mangler) (const std::string&); - typedef void (*close_hook) (const std::string&); - octave_shlib (void) : relative (false), rep (make_shlib ()) { } + class shlib_rep + { + public: + + shlib_rep (void) + : count (1), file (), tm_loaded (time_t ()) { } + + protected: + + shlib_rep (const std::string& f); + + public: + + virtual ~shlib_rep (void) + { + instances.erase (file); + } - octave_shlib (const std::string& f) - : relative (false), rep (make_shlib ()) { open (f); } + virtual bool is_open (void) const + { return false; } + + virtual void *search (const std::string&, name_mangler = 0) + { return 0; } + + bool is_out_of_date (void) const; + + // This method will be overriden conditionally. + static shlib_rep *new_instance (const std::string& f); + + static shlib_rep *get_instance (const std::string& f, bool fake); + + octave_time time_loaded (void) const + { return tm_loaded; } + + std::string file_name (void) const + { return file; } + + void insert_hook_name (const std::string& name) const; + + void erase_hook_name (const std::string& name) const; - virtual ~octave_shlib (void) + size_t num_fcn_names (void) const { return fcn_names.size (); } + + void add_fcn_name (const std::string&); + + bool remove_fcn_name (const std::string&); + + void do_close_hook (close_hook cl_hook); + + public: + + int count; + + protected: + + void fake_reload (void); + + std::string file; + octave_time tm_loaded; + + // Set of hooked function names. + typedef std::map<std::string, size_t>::iterator fcn_names_iterator; + typedef std::map<std::string, size_t>::const_iterator fcn_names_const_iterator; + + std::map<std::string, size_t> fcn_names; + + static std::map<std::string, shlib_rep *> instances; + }; + +private: + + static shlib_rep nil_rep; + +public: + + octave_shlib (void) : rep (&nil_rep) { rep->count++; } + + octave_shlib (const std::string& f, bool fake = true) + : rep (shlib_rep::get_instance (f, fake)) { } + + ~octave_shlib (void) { - if (rep && --rep->count == 0) - { - delete rep; - rep = 0; - } + if (--rep->count == 0) + delete rep; } octave_shlib (const octave_shlib& sl) @@ -86,51 +147,49 @@ bool operator == (const octave_shlib& sl) const { return (rep == sl.rep); } - operator bool () const { return is_open (); } + operator bool () const { return rep->is_open (); } + + void open (const std::string& f) + { *this = octave_shlib (f); } - virtual void open (const std::string& f) { rep->open (f); } + void close (close_hook cl_hook = 0) + { + if (cl_hook) + rep->do_close_hook (cl_hook); - virtual void *search (const std::string& nm, name_mangler mangler = 0) - { return rep->search (nm, mangler); } + *this = octave_shlib (); + } - virtual void close (close_hook cl_hook = 0) - { rep->close (cl_hook); } + void *search (const std::string& nm, name_mangler mangler = 0) const + { + void *f = rep->search (nm, mangler); + if (f) + rep->add_fcn_name (nm); + + return f; + } - virtual bool remove (const std::string& fcn_name) - { return rep->remove (fcn_name); } + void add (const std::string& name) + { rep->add_fcn_name (name); } - virtual bool is_out_of_date (void) const + bool remove (const std::string& name) + { return rep->remove_fcn_name (name); } + + size_t number_of_functions_loaded (void) const + { return rep->num_fcn_names (); } + + bool is_out_of_date (void) const { return rep->is_out_of_date (); } - void mark_relative (void) { relative = true; } - - bool is_relative (void) const { return relative; } - - virtual size_t number_of_functions_loaded (void) const - { return rep->number_of_functions_loaded (); } - - virtual std::string file_name (void) const + std::string file_name (void) const { return rep->file_name (); } - virtual octave_time time_loaded (void) const + octave_time time_loaded (void) const { return rep->time_loaded (); } -protected: - - octave_shlib (const octave_xshlib&) : rep (0) { } - - virtual bool is_open (void) const { return rep->is_open (); } - - static octave_shlib *make_shlib (void); +private: - // TRUE if this function was found from a relative path element. - bool relative; - - union - { - octave_shlib *rep; - int count; - }; + shlib_rep *rep; }; #endif