Change requested in DynLibManager::load() function

What it says on the tin: a place to discuss proposed new features.
Post Reply
knox_1234
Gnoblar
Posts: 13
Joined: Tue Aug 07, 2007 6:13 am

Change requested in DynLibManager::load() function

Post by knox_1234 »

Hi, in the DynLibManager::load() function, if the library that we are trying to load doesn't exist, then it results in memory leaks. Can the function be modified like this?



Code: Select all

DynLib* DynLibManager::load( const String& filename)
{
      DynLibList::iterator i = mLibList.find(filename);
      if (i != mLibList.end())
      {
         return i->second;
      }
      else
      {
         // modified .... Otherwise, we were having memory leaks if a particular module was not loaded...
         DynLib   *pLib = NULL ;

         try
         {
            pLib = new DynLib(filename);
            pLib->load();       
         }
         catch(Ogre::Exception& e)
         {
            if(pLib)
               delete pLib ;
            pLib = NULL ;
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, e.getDescription(), "DynLibManager::load") ;
         }

           mLibList[filename] = pLib;
           return pLib;
      }
} 
[/code]
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 51

Post by madmarx »

(well done :-) )

I just want to say you can try to submit it as a patch, if you want, or ask someone else to do it for you, so that is becomes part of the official DynLibManager (if accepted).
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

Seems like a reasonable fix. The best thing to do with things like this are submit them as patches to sourceforge. Otherwise they might get lost in the forums as posts pile up. However, since this is an easy one I'll look into right now.

[EDIT] In your version there if the library load fails it will insert a NULL object into the library manager's list, causing problems later on. I don't think we want to delete the misloaded library immediately there. Instead, we should report the error but continue to manage the library as if it were loaded. The DynLibManager's normal operations will clean it up for us later.
User avatar
syd
Gnome
Posts: 362
Joined: Thu May 01, 2008 1:55 am
Location: Paris, France

Post by syd »

In your version there if the library load fails it will insert a NULL object into the library manager's list, causing problems later on. I don't think we want to delete the misloaded library immediately there. Instead, we should report the error but continue to manage the library as if it were loaded. The DynLibManager's normal operations will clean it up for us later.
indeed, right now, knowing DynLib::load throws an exception when it fails, Root::loadPlugin (the caller) won't store the DynLib pointer in the mPluginLibs container.
Now if the exception is caught in DynLibManager::load, Root::loadPlugin will store a null pointer, then tries to start it.
but the idea is good.

a possible workaround:

Code: Select all


DynLib* DynLibManager::load( const String& filename)
{
      DynLibList::iterator i = mLibList.find(filename);
      if (i != mLibList.end())
      {
         return i->second;
      }
      else
      {
         // modified .... Otherwise, we were having memory leaks if a particular module was not loaded...
         DynLib   *pLib = NULL ;

         try
         {
            pLib = new DynLib(filename);
            pLib->load();       
         }
         catch(Ogre::Exception& e)
         {
            if(pLib)
               delete pLib ;
            pLib = NULL ;
//send exception to Root::loadPlugin
            throw e;
         }

           mLibList[filename] = pLib;
           return pLib;
      }
}


	void Root::loadPlugin(const String& pluginName)
	{
		// Load plugin library
        DynLib* lib = NULL ;
                try
               {
                DynLibManager::getSingleton().load( pluginName );
               } catch(Ogre::Exception& e)
               {

              LogManager::getSingleton().logMessage("Warning: plugin " + pluginName + " couldn't be loaded: plugin ignored");
               return;
                      
               } 
		// Store for later unload
		mPluginLibs.push_back(lib);

		// Call startup function
		DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin");

		if (!pFunc)
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName,
				"Root::loadPlugin");

		// This must call installPlugin
		pFunc();

	}
i hope this compiles :)

Edit:

after another though on this, I'm thinking it may be better not changing anything :P
since the application may depend on the plugin, even if this create a tiny memory leek, it would be less confusing to find the problem from a big error window then hidden in the log...
Post Reply