Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/3317

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/17/3317/1

API CHANGE: remove some of useless rtl/unload.h functionality

Change-Id: If32923e35ef97f42d5203975362e5c76948ff327
---
M sal/inc/rtl/unload.h
M sal/osl/all/compat.cxx
M sal/rtl/unload.cxx
3 files changed, 23 insertions(+), 551 deletions(-)



diff --git a/sal/inc/rtl/unload.h b/sal/inc/rtl/unload.h
index 9de17b4..0bbc414 100644
--- a/sal/inc/rtl/unload.h
+++ b/sal/inc/rtl/unload.h
@@ -27,209 +27,12 @@
 #include "sal/saldllapi.h"
 #include "sal/types.h"
 
-/** @file
-The API enables an effective way of unloading libraries in a centralized way.
-The mechanism ensures that used libraries are not unloaded. This prevents
-crashes if library code is being used after unloading the library.
-The unloading mechanism currently only works with libraries which contain
-UNO services. A library cannot be unloaded if one of the following conditions
-apply
-
-<ul>
-<li>An instance is still referenced </li>
-<li>A module has been loaded without registering it </li>
-<li>The service manager has created a one instance service </li>
-<li>A service instance has been added to an UNO context </li>
-</ul>
-
-<b>Notification Mechanism</b>
-The API provides a notification mechanism. Clients can use it to do clean up,
-such as releasing cached references, in order to allow modules to be unloaded.
-As long as someone holds a reference to an object whose housing module
-supports unloading the module cannot be unloaded.<p>
-
-Because of the inherent danger of crashing the application by using this API
-all instances which control threads should be registered listeners. On
-notification they have to ensure that their threads assume a safe state, that
-is, they run outside of modules which could be unloaded and do not jump
-back into module code as a result of a finished function call. In other words,
-there must not be an address of the module on the thread's stack.
-<p>
-Since current operating systems lack APIs in respect to controlling the
-position of threads within libraries, it would be a major effort to comply with
-that recommendation. The best and most efficient way of handling the unloading
-scenario is to let all threads, except for the main thread, die in case of a
-notification.
-<p>
-Use this API with great care because it might crash the application. See the
-respective documentation (Library Unloading) on the udk.openoffice.org web site.
-*/
-
-
-/**
-A library which supports unloading has to implement and export a function
-called <code>component_canUnload</code>. <p>
-If the function returns <code>sal_True</code> then the module can be safely unloaded.
-That is the case when there are no external references to code within the
-library. In case a module houses UNO components then the function must return
-<code>sal_False</code> after the first factory has been handed out. The function then
-continues to return <code>sal_False</code> as long as there is at least one object (factory
-or service instance)  which originated from the module.<p>
-
-Libraries which not only contain UNO components (or none at all) have to
-provide a means to control whether they can be unloaded or not, e.g. However,
-there is no concept yet. <p>
-
-The argument <code>pTime</code> is an optional out-parameter. If the return value is
-<code>sal_True</code> then <code>pTime</code> reflects a point in time since
-when the module could have
-been unloaded. Since that time the function would have continually returned
-<code>sal_True</code> up to the present. The value of <code>pTime</code> is
-important for the decision
-as to a module will be unloaded. When someone initiates the unloading of
-modules by calling <code>rtl_unloadUnusedModules</code> then the caller can specify a time
-span with the effect that only those modules are unloaded which are unused at
-least for that amount of time. If <code>component_canUnload</code> does not
-fill in <code>pTime</code>
-then the module is unloaded immediately.<p>
-
-<code>component_canUnload</code> is implicitly called by <code>rtl_unloadUnusedModules
-</code>. There is no need to call the function directly.
-*/
-#define COMPONENT_CANUNLOAD         "component_canUnload"
-typedef sal_Bool (SAL_CALL * component_canUnloadFunc)( TimeValue* pTime);
-
-
 /** C-interface for a module reference counting
  */
 #ifdef __cplusplus
 extern "C"
 {
 #endif
-
-/**
-By registering a module, one declares that a module supports the
-unloading mechanism. One registers a module by calling this function.<p>
-
-A module can only be unloaded from memory when it has been registered
-as many times as it has been loaded. The reason is that a library can
-be &quot;loaded&quot; several times by <code>osl_loadModule</code>
-within the same process. The
-function will then return the same module handle because the library will
-effectively only be loaded once. To remove the library from memory it is
-necessary to call <code>osl_unloadModule</code> as often as <code>
-osl_loadModule</code> was called. The
-function <code>rtl_unloadUnusedModules</code> calls <code>osl_unloadModule</code>
-for a module as many
-times as it was registered. If, for example, a module has been registered one
-time less then <code>osl_loadModule</code> has been called and the module can be unloaded
-then it needs a call to <code>rtl_unloadUnusedModules</code> and an explicit call to
-<code>osl_unloadModule</code> to remove the module from memory. <p>
-
-A module must be registered every time it has been loaded otherwise the
-unloading mechanism is not effective.<p>
-
-Before a module is registered, one has to make sure that the module is in a
-state that prevents it from being unloaded. In other words,
-<code>component_canUnload</code> must return <code>sal_False</code>. Assuming that
-<code>component_canUnload</code>
-returns <code>sal_True</code> and it is registered regardless, then a call to
-<code>rtl_unloadUnusedModules</code> causes the module to be unloaded. This unloading can
-be set off by a different thread and the thread which registered the module is
-&quot;unaware&quot; of this. Then when the first thread tries to obtain a factory or
-calls another function in the module, the application will crash, because the
-module has been unloaded before. Therefore one has to ensure that the module
-cannot be unloaded before it is registered. This is simply done by obtaining a
-factory from the module. As long as a factory or some other object, which has
-been created by the factory, is alive, the <code>component_canUnload</code> function will
-return <code>sal_False</code>.<p>
-Loading and registering have to be in this order:<br>
-<ul>
-<li>load a library (<code>osl_loadModule</code>)</li>
-<li>get the <code>component_getFactory</code> function and get a factory</li>
-<li>register the module (rtl_registerModuleForUnloading</li>
-</ul>
-Usually the service manager is used to obtain an instance of a service.
-The service manager registers all modules which support the unloading mechanism.
-When the service manager is used to get service instances than one does not
-have to bother about registering.
-
-@param module a module handle as is obtained by osl_loadModule
-@return sal_True - the module could be registered for unloading, sal_False otherwise
-*/
-SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_registerModuleForUnloading( oslModule module);
-
-/**
-The function revokes the registration of a module. By calling the function for
-a previously registered module one prevents the module from being unloaded by
-this unloading mechanism. However, in order to completely unregister the module
-it is necessary to call the function as often as the module has been registered.
-<p>
-<code>rtl_unloadUnusedModules</code> unregisters the modules which it unloads. Therefore
-there is no need to call this function unless one means to prevent the unloading of a module.
-
-@param module a module handle as is obtained by osl_loadModule
-*/
-SAL_DLLPUBLIC void SAL_CALL rtl_unregisterModuleForUnloading( oslModule module);
-/**
-This function sets off the unloading mechanism. At first it notifies the
-unloading listeners in order to give them a chance to do cleanup and get
-their threads in a safe state. Then all registered modules are asked if they
-can be unloaded. That is, the function calls component_canUnload on every
-registered module. If <code>sal_True</code> is returned then <code>osl_unloadModule</code>
-is called for the belonging module as often as it is registered.
-<p>
-A call to <code>osl_unloadModule</code> does not guarantee that the module is unloaded even
-if its <code>component_canUnload</code> function returns <code>sal_True</code>.
-<p>
-The optional in-parameter <code>libUnused</code> specifies a period of time which a library
-must be unused in order to qualify for being unloaded. By using this argument
-one can counter the multithreading problem as described further above. It is in
-the responsibility of the user of this function to provide a timespan big enough
-to ensure that all threads are out of modules (see <code>component_canUnload</code>).
-<p>
-The service managers which have been created by functions such as
-<code>createRegistryServiceFactory</code> (declared in cppuhelper/servicefactory.hxx) are
-registered listeners and release the references to factories on notification.
-
-
-@param libUnused span of time that a module must be unused to be unloaded. the
-argument is optional.
-*/
-SAL_DLLPUBLIC void SAL_CALL rtl_unloadUnusedModules( TimeValue* libUnused);
-
-/**
-rtl_addUnloadingListener takes an argument of this type.
-
-@param id - The value that has been passed as second argument to rtl_addUnloadingListener
-*/
-typedef void (SAL_CALL *rtl_unloadingListenerFunc)(void* id);
-/**
-The function registered an unloading listener. The callback argument is a
-function which is called  when the unloading procedure has been initiated by a call to
-<code>rtl_unloadUnusedLibraries</code>. The second argument is used to distinguish between 
different
-listener instances and may be <code>NULL</code>. It will be passed as argument when the callback
-function is being called. The return value identifies the registered listener and will
-be used for removing the listener later on. If the same listener is added more then
-once then every registration is treated as if made for a different listener. That is,
-a different cookie is returned and the callback function will be called as many times
-as it has been registered.
-@param callback - a function that is called to notify listeners.
-@param _this  - a value to distinguish different listener instances
-@return identifier which is used in rtl_removeUnloadingListener
-*/
-SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_addUnloadingListener( rtl_unloadingListenerFunc callback, 
void* _this);
-
-/**
-Listeners (the callback functions) must be unregistered before the listener code
-becomes invalid. That is, if a module contains listener code, namely callback
-functions of type <code>rtl_unloadingListenerFunc</code>, then those functions must not be
-registered when <code>component_canUnload</code> returns <code>sal_True</code>.
-
-@param cookie is an identifier as returned by <code>rtl_addUnloadingListener</code> function.
-*/
-SAL_DLLPUBLIC void SAL_CALL rtl_removeUnloadingListener( sal_Int32 cookie );
-
 
 /**
 Pointers to <code>rtl_ModuleCount</code> are passed as arguments to the default factory creator
diff --git a/sal/osl/all/compat.cxx b/sal/osl/all/compat.cxx
index f9c7129..4b64326 100644
--- a/sal/osl/all/compat.cxx
+++ b/sal/osl/all/compat.cxx
@@ -11,6 +11,8 @@
 
 #include <cstdlib>
 
+#include "osl/module.h"
+#include "osl/time.h"
 #include "sal/types.h"
 
 // Stubs for removed functionality, to be killed when we bump sal SONAME
@@ -69,6 +71,27 @@
     std::abort();
 }
 
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL rtl_registerModuleForUnloading(oslModule) {
+    std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_unregisterModuleForUnloading(oslModule) {
+    std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_unloadUnusedModules(TimeValue *) {
+    std::abort();
+}
+
+typedef void (SAL_CALL *rtl_unloadingListenerFunc)(void *id);
+SAL_DLLPUBLIC_EXPORT sal_Int32 SAL_CALL rtl_addUnloadingListener(rtl_unloadingListenerFunc, void 
*) {
+    std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_removeUnloadingListener(sal_Int32) {
+    std::abort();
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/rtl/unload.cxx b/sal/rtl/unload.cxx
index 4d4a414..8bfff77 100644
--- a/sal/rtl/unload.cxx
+++ b/sal/rtl/unload.cxx
@@ -37,72 +37,6 @@
 
 #ifndef DISABLE_DYNLOADING
 
-static void rtl_notifyUnloadingListeners();
-
-static sal_Bool isEqualTimeValue ( const TimeValue* time1,  const TimeValue* time2)
-{
-    if( time1->Seconds == time2->Seconds &&
-        time1->Nanosec == time2->Nanosec)
-        return sal_True;
-    else
-        return sal_False;
-}
-
-static sal_Bool isGreaterTimeValue(  const TimeValue* time1,  const TimeValue* time2)
-{
-    sal_Bool retval= sal_False;
-    if ( time1->Seconds > time2->Seconds)
-        retval= sal_True;
-    else if ( time1->Seconds == time2->Seconds)
-    {
-        if( time1->Nanosec > time2->Nanosec)
-            retval= sal_True;
-    }
-    return retval;
-}
-
-static sal_Bool isGreaterEqualTimeValue( const TimeValue* time1, const TimeValue* time2)
-{
-    if( isEqualTimeValue( time1, time2) )
-        return sal_True;
-    else if( isGreaterTimeValue( time1, time2))
-        return sal_True;
-    else
-        return sal_False;
-}
-
-static void addTimeValue( const TimeValue* value1, const TimeValue* value2, TimeValue* result)
-{
-    sal_uInt64 sum;
-    result->Nanosec=0;
-    result->Seconds=0;
-
-    sum= value1->Nanosec + value2->Nanosec;
-    if( sum >= 1000000000 )
-    {
-        result->Seconds=1;
-        sum -= 1000000000;
-    }
-    result->Nanosec= (sal_uInt32)sum;
-    result->Seconds += value1->Seconds + value2->Seconds;
-}
-
-
-static sal_Bool hasEnoughTimePassed( const TimeValue* unusedSince, const TimeValue* timespan)
-{
-    sal_Bool retval= sal_False;
-    TimeValue currentTime;
-    if( osl_getSystemTime( &currentTime))
-    {
-        TimeValue addedTime;
-        addTimeValue( unusedSince, timespan, &addedTime);
-        if( isGreaterEqualTimeValue( &currentTime, &addedTime))
-            retval= sal_True;
-    }
-
-    return retval;
-}
-
 namespace
 {
     class theUnloadingMutex : public rtl::Static<osl::Mutex, theUnloadingMutex>{};
@@ -147,43 +81,6 @@
 #endif
 }
 
-#ifndef DISABLE_DYNLOADING
-
-struct hashModule
-{
-    size_t operator()( const oslModule& rkey) const
-    {
-        return (size_t)rkey;
-    }
-};
-
-typedef boost::unordered_map<
-    oslModule,
-    std::pair<sal_uInt32, component_canUnloadFunc>,
-    hashModule,
-    std::equal_to<oslModule>,
-    rtl::Allocator<oslModule>
-> ModuleMap;
-
-typedef ModuleMap::iterator Mod_IT;
-
-static ModuleMap& getModuleMap()
-{
-    static ModuleMap * g_pMap= NULL;
-    if (!g_pMap)
-    {
-        MutexGuard guard( getUnloadingMutex() );
-        if (!g_pMap)
-        {
-            static ModuleMap g_aModuleMap;
-            g_pMap= &g_aModuleMap;
-        }
-    }
-    return *g_pMap;
-}
-
-#endif
-
 extern "C" sal_Bool rtl_moduleCount_canUnload( rtl_StandardModuleCount * that, TimeValue * 
libUnused)
 {
 #ifdef DISABLE_DYNLOADING
@@ -202,256 +99,5 @@
     return (that->counter == 0);
 #endif
 }
-
-
-extern "C" sal_Bool SAL_CALL rtl_registerModuleForUnloading( oslModule module)
-{
-#ifdef DISABLE_DYNLOADING
-    (void) module;
-    return sal_False;
-#else
-    MutexGuard guard( getUnloadingMutex());
-    ModuleMap& moduleMap= getModuleMap();
-    sal_Bool ret= sal_True;
-
-    // If the module has been registered before, then find it and increment
-    // its reference cout
-    Mod_IT it= moduleMap.find( module);
-    if( it != moduleMap.end())
-    {
-        //module already registered, increment ref count
-        it->second.first++;
-    }
-    else
-    {
-        // Test if the module supports unloading (exports component_canUnload)
-        rtl::OUString name(RTL_CONSTASCII_USTRINGPARAM( COMPONENT_CANUNLOAD));
-        component_canUnloadFunc pFunc=
-            (component_canUnloadFunc)osl_getFunctionSymbol( module, name.pData);
-        if (pFunc)
-        {
-            //register module for the first time, set ref count to 1
-            moduleMap[module]= std::make_pair((sal_uInt32)1, pFunc);
-        }
-        else
-            ret= sal_False;
-    }
-    return ret;
-#endif
-}
-
-extern "C" void SAL_CALL rtl_unregisterModuleForUnloading( oslModule module)
-{
-#ifdef DISABLE_DYNLOADING
-    (void) module;
-#else
-    MutexGuard guard( getUnloadingMutex());
-
-    ModuleMap& moduleMap= getModuleMap();
-    Mod_IT it= moduleMap.find( module);
-    if( it != moduleMap.end() )
-    {
-        // The module is registered, decrement ref count.
-        it->second.first --;
-
-        // If the refcount == 0 then remove the module from the map
-        if( it->second.first == 0)
-            moduleMap.erase( it);
-    }
-#endif
-}
-
-extern "C" void SAL_CALL rtl_unloadUnusedModules( TimeValue* libUnused)
-{
-#ifdef DISABLE_DYNLOADING
-    (void) libUnused;
-#else
-    MutexGuard guard( getUnloadingMutex());
-
-    typedef std::list< oslModule, rtl::Allocator<oslModule> > list_type;
-    list_type unloadedModulesList;
-
-    ModuleMap& moduleMap= getModuleMap();
-    Mod_IT it_e= moduleMap.end();
-
-    // notify all listeners
-    rtl_notifyUnloadingListeners();
-
-    // prepare default TimeValue if argumetn is NULL
-    TimeValue nullTime={0,0};
-    TimeValue* pLibUnused= libUnused? libUnused : &nullTime;
-
-    Mod_IT it= moduleMap.begin();
-    for (; it != it_e; ++it)
-    {
-        //can the module be unloaded?
-        component_canUnloadFunc func= it->second.second;
-        TimeValue unusedSince= {0, 0};
-
-        if( func( &unusedSince) )
-        {
-            // module can be unloaded if it has not been used at least for the time
-            // specified by the argument libUnused
-            if( hasEnoughTimePassed( &unusedSince, pLibUnused))
-            {
-                // get the reference count and unload the module as many times
-                sal_uInt32 refCount= it->second.first;
-
-                for ( sal_uInt32 i=0; i < refCount; i++)
-                    osl_unloadModule( it->first);
-
-                // mark the module for later removal
-                unloadedModulesList.push_front( it->first);
-            }
-        }
-    }
-
-    // remove all entries containing invalid (unloaded) modules
-    list_type::const_iterator un_it= unloadedModulesList.begin();
-    for (; un_it != unloadedModulesList.end(); ++un_it)
-    {
-        moduleMap.erase( *un_it);
-    }
-#endif
-}
-
-#ifndef DISABLE_DYNLOADING
-
-// ==============================================================================
-// Unloading Listener Administration
-//===============================================================================
-struct hashListener
-{
-    size_t operator()( const sal_Int32& rkey) const
-    {
-        return (size_t)rkey;
-    }
-};
-
-typedef boost::unordered_map<
-    sal_Int32,
-    std::pair<rtl_unloadingListenerFunc, void*>,
-    hashListener,
-    std::equal_to<sal_Int32>,
-    rtl::Allocator<sal_Int32>
-> ListenerMap;
-
-typedef ListenerMap::iterator Lis_IT;
-
-static ListenerMap& getListenerMap()
-{
-    static ListenerMap * g_pListeners= NULL;
-    if (!g_pListeners)
-    {
-        MutexGuard guard( getUnloadingMutex() );
-        if (!g_pListeners)
-        {
-            static ListenerMap g_aListenerMap;
-            g_pListeners= &g_aListenerMap;
-        }
-    }
-    return *g_pListeners;
-}
-
-
-// This queue contains cookies which have been passed out by rtl_addUnloadingListener and
-// which have been regainded by rtl_removeUnloadingListener. When rtl_addUnloadingListener
-// is called then a cookie has to be returned. First we look into the set if there is one
-// available. Otherwise a new cookie will be provided.
-// not a new value is returned.
-
-typedef std::deque<
-    sal_Int32,
-    rtl::Allocator<sal_Int32>
-> queue_type;
-
-static queue_type& getCookieQueue()
-{
-    static queue_type * g_pCookies= NULL;
-    if (!g_pCookies)
-    {
-        MutexGuard guard( getUnloadingMutex() );
-        if (!g_pCookies)
-        {
-            static queue_type g_aCookieQueue;
-            g_pCookies= &g_aCookieQueue;
-        }
-    }
-    return *g_pCookies;
-}
-
-static sal_Int32 getCookie()
-{
-    static sal_Int32 cookieValue= 1;
-
-    sal_Int32 retval;
-    queue_type& regainedCookies= getCookieQueue();
-    if( regainedCookies.empty() )
-        retval= cookieValue++;
-    else
-    {
-        retval= regainedCookies.front();
-        regainedCookies.pop_front();
-    }
-    return retval;
-}
-
-static inline void recycleCookie( sal_Int32 i)
-{
-    getCookieQueue().push_back(i);
-}
-
-
-#endif
-
-// calling the function twice with the same arguments will return tow different cookies.
-// The listener will then notified twice.
-
-extern "C"
-sal_Int32 SAL_CALL rtl_addUnloadingListener( rtl_unloadingListenerFunc callback, void* _this)
-{
-#ifdef DISABLE_DYNLOADING
-    (void) callback;
-    (void) _this;
-    return 0;
-#else
-    MutexGuard guard( getUnloadingMutex());
-
-    sal_Int32 cookie= getCookie();
-    ListenerMap& listenerMap= getListenerMap();
-    listenerMap[ cookie]= std::make_pair( callback, _this);
-    return cookie;
-#endif
-}
-
-
-extern "C"
-void SAL_CALL rtl_removeUnloadingListener( sal_Int32 cookie )
-{
-#ifdef DISABLE_DYNLOADING
-    (void) cookie;
-#else
-    MutexGuard guard( getUnloadingMutex());
-
-    ListenerMap& listenerMap= getListenerMap();
-    size_t removedElements= listenerMap.erase( cookie);
-    if( removedElements )
-        recycleCookie( cookie);
-#endif
-}
-
-#ifndef DISABLE_DYNLOADING
-
-static void rtl_notifyUnloadingListeners()
-{
-    ListenerMap& listenerMap= getListenerMap();
-    for( Lis_IT it= listenerMap.begin(); it != listenerMap.end(); ++it)
-    {
-        rtl_unloadingListenerFunc callbackFunc= it->second.first;
-        callbackFunc( it->second.second);
-    }
-}
-
-#endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

-- 
To view, visit https://gerrit.libreoffice.org/3317
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If32923e35ef97f42d5203975362e5c76948ff327
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Matúš Kukan <matus.kukan@gmail.com>


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.