celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Alexander Broekhuis (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CELIX-218) Memory leaks in service_registry.c
Date Tue, 10 Feb 2015 07:37:38 GMT

    [ https://issues.apache.org/jira/browse/CELIX-218?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14313751#comment-14313751
] 

Alexander Broekhuis commented on CELIX-218:
-------------------------------------------

I'm not sure if this should be added to the serviceRegistry_destroy. In a normal/successful
flow all bundles are stopped, and the bundleActivator_stop should remove any registered service/hook.
Also Services/ServiceReferences are "unget" (eg via a ServiceTracker_stop). For example, look
at the call hierarchy of "serviceRegistry_flushUsageCount" for the cleanup in the registry.
So if program execution was successful and you still see some entries in these lists, there
might be a problem with stopping one or more bundles. If Celix crashed (for whatever reason)
valgrind results are misleading, and don't tell anything meaningful.

What where the conditions of the testrun? I'd like to see what's going on, and make sure the
framework does a proper cleanup when a bundle is stopped.


> Memory leaks in service_registry.c
> ----------------------------------
>
>                 Key: CELIX-218
>                 URL: https://issues.apache.org/jira/browse/CELIX-218
>             Project: Celix
>          Issue Type: Bug
>            Reporter: Daniel Parker
>
> serviceRegistry_destroy() should destroy each of the items within the registry->inUseMap,
registry->listenerHooks, registry->serviceRegistrations, and registry->serviceReferences
lists before it destroys the lists themselves.
> Suggested code to use (checked with valgrind):
>     // destroy all entries from registry->inUseMap, then registry->inUseMap itself
>     if (registry->inUseMap != NULL)
>     {
>        celixThreadMutex_lock(&registry->mutex);
>        hash_map_iter = hashMapIterator_create(registry->inUseMap);
>        while (hashMapIterator_hasNext(hash_map_iter) )
>        {
>           array_list_ptr = hashMapIterator_nextValue(hash_map_iter);
>           array_list_iter = arrayListIterator_create(array_list_ptr);
>           while (arrayListIterator_hasNext(array_list_iter) )
>           {
>              free(arrayListIterator_next(array_list_iter) );
>           }
>           arrayListIterator_destroy(array_list_iter);
>           arrayList_destroy(array_list_ptr);
>        }
>        hashMapIterator_destroy(hash_map_iter);
>        hashMap_destroy(registry->inUseMap, false, false);
>        registry->inUseMap = NULL;
>        celixThreadMutex_unlock(&registry->mutex);
>     }
>     // destroy all entries from registry->listenerHooks, then registry->listenerHooks
itself
>     if (registry->listenerHooks != NULL)
>     {
>        celixThreadMutex_lock(&registry->mutex);
>        array_list_iter = arrayListIterator_create(registry->listenerHooks);
>        while (arrayListIterator_hasNext(array_list_iter) )
>        {
>           service_registration_pt registration_ptr = arrayListIterator_next(array_list_iter);
>           serviceRegistration_destroy(registration_ptr);
>        }
>        arrayListIterator_destroy(array_list_iter);
>        arrayList_destroy(registry->listenerHooks);
>        registry->listenerHooks = NULL;
>        celixThreadMutex_unlock(&registry->mutex);
>     }
>     // destroy all entries from registry->serviceRegistrations, then registry->serviceRegistrations
itself
>     // note that each of the registrations in the array lists have already been destroyed
with registry->listenerHooks
>     if (registry->serviceRegistrations != NULL)
>     {
>        celixThreadMutex_lock(&registry->mutex);
>        hash_map_iter = hashMapIterator_create(registry->serviceRegistrations);
>        while (hashMapIterator_hasNext(hash_map_iter) )
>        {
>           arrayList_destroy(hashMapIterator_nextValue(hash_map_iter) );
>        }
>        hashMapIterator_destroy(hash_map_iter);
>        hashMap_destroy(registry->serviceRegistrations, false, false);
>        registry->serviceRegistrations = NULL;
>        celixThreadMutex_unlock(&registry->mutex);
>     }
>     // destroy all entries from registry->serviceReferences, then registry->serviceReferences
itself
>     if (registry->serviceReferences != NULL)
>     {
>        celixThreadMutex_lock(&registry->referencesMapMutex);
>        hash_map_iter = hashMapIterator_create(registry->serviceReferences);
>        while (hashMapIterator_hasNext(hash_map_iter) )
>        {
>           array_list_ptr = hashMapIterator_nextValue(hash_map_iter);
>           array_list_iter = arrayListIterator_create(array_list_ptr);
>           while (arrayListIterator_hasNext(array_list_iter) )
>           {
>              service_reference_pt service_ptr = arrayListIterator_next(array_list_iter);
>              serviceReference_destroy(&service_ptr);
>           }
>           arrayListIterator_destroy(array_list_iter);
>           arrayList_destroy(array_list_ptr);
>        }
>        hashMapIterator_destroy(hash_map_iter);
>        hashMap_destroy(registry->serviceReferences, false, false);
>        registry->serviceReferences = NULL;
>        celixThreadMutex_unlock(&registry->referencesMapMutex);
>     }



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message