Author: abroekhuis
Date: Mon Aug 18 08:52:48 2014
New Revision: 1618562

URL: http://svn.apache.org/r1618562
Log:
CELIX-137: Applied patch

Modified:
    
celix/trunk/remote_services/topology_manager/private/include/topology_manager.h
    celix/trunk/remote_services/topology_manager/private/src/activator.c
    celix/trunk/remote_services/topology_manager/private/src/topology_manager.c

Modified: 
celix/trunk/remote_services/topology_manager/private/include/topology_manager.h
URL: 
http://svn.apache.org/viewvc/celix/trunk/remote_services/topology_manager/private/include/topology_manager.h?rev=1618562&r1=1618561&r2=1618562&view=diff
==============================================================================
--- 
celix/trunk/remote_services/topology_manager/private/include/topology_manager.h 
(original)
+++ 
celix/trunk/remote_services/topology_manager/private/include/topology_manager.h 
Mon Aug 18 08:52:48 2014
@@ -33,7 +33,7 @@
 
 typedef struct topology_manager *topology_manager_pt;
 
-celix_status_t topologyManager_create(bundle_context_pt context, apr_pool_t 
*pool, topology_manager_pt *manager);
+celix_status_t topologyManager_create(bundle_context_pt context, 
topology_manager_pt *manager);
 celix_status_t topologyManager_destroy(topology_manager_pt manager);
 
 celix_status_t topologyManager_rsaAdding(void *handle, service_reference_pt 
reference, void **service);
@@ -43,12 +43,11 @@ celix_status_t topologyManager_rsaRemove
 
 celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt 
event);
 
-celix_status_t topologyManager_endpointAdded(void *handle, 
endpoint_description_pt endpoint, char *machtedFilter);
-celix_status_t topologyManager_endpointRemoved(void *handle, 
endpoint_description_pt endpoint, char *machtedFilter);
+celix_status_t topologyManager_addImportedService(void *handle, 
endpoint_description_pt endpoint, char *matchedFilter);
+celix_status_t topologyManager_removeImportedService(void *handle, 
endpoint_description_pt endpoint, char *matchedFilter);
 
-celix_status_t topologyManager_importService(topology_manager_pt manager, 
endpoint_description_pt endpoint);
-celix_status_t topologyManager_exportService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId);
-celix_status_t topologyManager_removeService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId);
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId);
+celix_status_t topologyManager_removeExportedService(topology_manager_pt 
manager, service_reference_pt reference, char *serviceId);
 
 celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt 
listeners);
 celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt 
listeners);

Modified: celix/trunk/remote_services/topology_manager/private/src/activator.c
URL: 
http://svn.apache.org/viewvc/celix/trunk/remote_services/topology_manager/private/src/activator.c?rev=1618562&r1=1618561&r2=1618562&view=diff
==============================================================================
--- celix/trunk/remote_services/topology_manager/private/src/activator.c 
(original)
+++ celix/trunk/remote_services/topology_manager/private/src/activator.c Mon 
Aug 18 08:52:48 2014
@@ -27,8 +27,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <apr_strings.h>
-
 #include "constants.h"
 #include "bundle_activator.h"
 #include "service_tracker.h"
@@ -40,7 +38,6 @@
 #include "listener_hook_service.h"
 
 struct activator {
-       apr_pool_t *pool;
        bundle_context_pt context;
 
        topology_manager_pt manager;
@@ -57,35 +54,27 @@ static celix_status_t bundleActivator_cr
 
 celix_status_t bundleActivator_create(bundle_context_pt context, void 
**userData) {
        celix_status_t status = CELIX_SUCCESS;
-       apr_pool_t *parentPool = NULL;
-       apr_pool_t *pool = NULL;
        struct activator *activator = NULL;
 
-       bundleContext_getMemoryPool(context, &parentPool);
-       if (apr_pool_create(&pool, parentPool) != APR_SUCCESS) {
-               status = CELIX_BUNDLE_EXCEPTION;
-       } else {
-               activator = apr_palloc(pool, sizeof(*activator));
-               if (!activator) {
-                       status = CELIX_ENOMEM;
-               } else {
-                       activator->pool = pool;
-                       activator->context = context;
-                       activator->endpointListenerService = NULL;
-                       activator->hook = NULL;
-                       activator->manager = NULL;
-                       activator->remoteServiceAdminTracker = NULL;
-                       activator->serviceListener = NULL;
+       activator = malloc(sizeof(struct activator));
+       if (!activator) {
+               return CELIX_ENOMEM;
+       }
+
+       activator->context = context;
+       activator->endpointListenerService = NULL;
+       activator->hook = NULL;
+       activator->manager = NULL;
+       activator->remoteServiceAdminTracker = NULL;
+       activator->serviceListener = NULL;
 
-                       status = topologyManager_create(context, pool, 
&activator->manager);
+       status = topologyManager_create(context, &activator->manager);
+       if (status == CELIX_SUCCESS) {
+               status = bundleActivator_createRSATracker(activator, 
&activator->remoteServiceAdminTracker);
+               if (status == CELIX_SUCCESS) {
+                       status = 
bundleActivator_createServiceListener(activator, &activator->serviceListener);
                        if (status == CELIX_SUCCESS) {
-                               status = 
bundleActivator_createRSATracker(activator, 
&activator->remoteServiceAdminTracker);
-                               if (status == CELIX_SUCCESS) {
-                                       status = 
bundleActivator_createServiceListener(activator, &activator->serviceListener);
-                                       if (status == CELIX_SUCCESS) {
-                                               *userData = activator;
-                                       }
-                               }
+                               *userData = activator;
                        }
                }
        }
@@ -110,40 +99,54 @@ static celix_status_t bundleActivator_cr
 
 static celix_status_t bundleActivator_createServiceListener(struct activator 
*activator, service_listener_pt *listener) {
        celix_status_t status = CELIX_SUCCESS;
-       apr_pool_t *pool;
-       apr_pool_create(&pool, activator->pool);
-       *listener = apr_palloc(pool, sizeof(*listener));
+
+       *listener = malloc(sizeof(*listener));
        if (!*listener) {
-               status = CELIX_ENOMEM;
-       } else {
-               (*listener)->handle = activator->manager;
-               (*listener)->serviceChanged = topologyManager_serviceChanged;
+               return CELIX_ENOMEM;
        }
 
+       (*listener)->handle = activator->manager;
+       (*listener)->serviceChanged = topologyManager_serviceChanged;
+
        return status;
 }
 
 celix_status_t bundleActivator_start(void * userData, bundle_context_pt 
context) {
        celix_status_t status = CELIX_SUCCESS;
        struct activator *activator = userData;
-       apr_pool_t *pool = NULL;
-       apr_pool_create(&pool, activator->pool);
 
-       endpoint_listener_pt endpointListener = apr_palloc(pool, 
sizeof(*endpointListener));
+       endpoint_listener_pt endpointListener = 
malloc(sizeof(*endpointListener));
        endpointListener->handle = activator->manager;
-       endpointListener->endpointAdded = topologyManager_endpointAdded;
-       endpointListener->endpointRemoved = topologyManager_endpointRemoved;
+       endpointListener->endpointAdded = topologyManager_addImportedService;
+       endpointListener->endpointRemoved = 
topologyManager_removeImportedService;
 
-       properties_pt props = properties_create();
        char *uuid = NULL;
-       bundleContext_getProperty(activator->context, (char 
*)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-       char *scope = apr_pstrcat(pool, "(&(", OSGI_FRAMEWORK_OBJECTCLASS, 
"=*)(!(", OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "=", uuid, ")))", NULL);
-       printf("TOPOLOGY_MANAGER: Endpoint listener Scope is %s\n", scope);
+       status = bundleContext_getProperty(activator->context, (char 
*)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+       if (!uuid) {
+               printf("TOPOLOGY_MANAGER: no framework UUID defined?!\n");
+               return CELIX_ILLEGAL_STATE;
+       }
+
+       size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + 
strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+       char *scope = malloc(len);
+       if (!scope) {
+               return CELIX_ENOMEM;
+       }
+
+       sprintf(scope, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, 
OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+       scope[len] = 0;
+
+       printf("TOPOLOGY_MANAGER: endpoint listener scope is %s\n", scope);
+
+       properties_pt props = properties_create();
        properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope);
 
+       // We can release the scope, as properties_set makes a copy of the key 
& value...
+       free(scope);
+
        bundleContext_registerService(context, (char *) 
OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, 
&activator->endpointListenerService);
 
-       listener_hook_service_pt hook = apr_palloc(pool, sizeof(*hook));
+       listener_hook_service_pt hook = malloc(sizeof(*hook));
        hook->handle = activator->manager;
        hook->added = topologyManager_listenerAdded;
        hook->removed = topologyManager_listenerRemoved;
@@ -161,7 +164,9 @@ celix_status_t bundleActivator_stop(void
        struct activator *activator = userData;
 
        serviceTracker_close(activator->remoteServiceAdminTracker);
+
        bundleContext_removeServiceListener(context, 
activator->serviceListener);
+
        serviceRegistration_unregister(activator->hook);
        serviceRegistration_unregister(activator->endpointListenerService);
 
@@ -169,12 +174,10 @@ celix_status_t bundleActivator_stop(void
 }
 
 celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt 
context) {
-
        struct activator *activator = userData;
-       if(activator==NULL || activator->manager==NULL){
+       if (!activator || !activator->manager) {
                return CELIX_BUNDLE_EXCEPTION;
        }
 
        return topologyManager_destroy(activator->manager);
-
 }

Modified: 
celix/trunk/remote_services/topology_manager/private/src/topology_manager.c
URL: 
http://svn.apache.org/viewvc/celix/trunk/remote_services/topology_manager/private/src/topology_manager.c?rev=1618562&r1=1618561&r2=1618562&view=diff
==============================================================================
--- celix/trunk/remote_services/topology_manager/private/src/topology_manager.c 
(original)
+++ celix/trunk/remote_services/topology_manager/private/src/topology_manager.c 
Mon Aug 18 08:52:48 2014
@@ -26,9 +26,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <apr_uuid.h>
-#include <apr_strings.h>
-
 #include "topology_manager.h"
 #include "bundle_context.h"
 #include "constants.h"
@@ -43,11 +40,15 @@
 #include "service_registration.h"
 
 struct topology_manager {
-       apr_pool_t *pool;
        bundle_context_pt context;
 
+       celix_thread_mutex_t rsaListLock;
        array_list_pt rsaList;
+
+       celix_thread_mutex_t exportedServicesLock;
        hash_map_pt exportedServices;
+
+       celix_thread_mutex_t importedServicesLock;
        hash_map_pt importedServices;
        hash_map_pt importInterests;
 };
@@ -57,37 +58,59 @@ struct import_interest {
        int refs;
 };
 
-celix_status_t topologyManager_notifyListeners(topology_manager_pt manager, 
remote_service_admin_service_pt rsa,  array_list_pt registrations);
-celix_status_t topologyManager_notifyListenersOfRemoval(topology_manager_pt 
manager, remote_service_admin_service_pt rsa,  export_registration_pt export);
+celix_status_t 
topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, 
remote_service_admin_service_pt rsa,  array_list_pt registrations);
+celix_status_t 
topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, 
remote_service_admin_service_pt rsa,  export_registration_pt export);
 
-celix_status_t topologyManager_create(bundle_context_pt context, apr_pool_t 
*pool, topology_manager_pt *manager) {
+celix_status_t topologyManager_create(bundle_context_pt context, 
topology_manager_pt *manager) {
        celix_status_t status = CELIX_SUCCESS;
 
-       *manager = apr_palloc(pool, sizeof(**manager));
+       *manager = malloc(sizeof(**manager));
        if (!*manager) {
-               status = CELIX_ENOMEM;
-       } else {
-               (*manager)->pool = pool;
-               (*manager)->context = context;
-               (*manager)->rsaList = NULL;
-               arrayList_create(&(*manager)->rsaList);
-               (*manager)->exportedServices = 
hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
-               (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, 
NULL);
-               (*manager)->importInterests = hashMap_create(utils_stringHash, 
NULL, utils_stringEquals, NULL);
+               return CELIX_ENOMEM;
        }
 
+       (*manager)->context = context;
+       (*manager)->rsaList = NULL;
+       arrayList_create(&(*manager)->rsaList);
+
+       status = celixThreadMutex_create(&(*manager)->rsaListLock, NULL);
+       status = celixThreadMutex_create(&(*manager)->exportedServicesLock, 
NULL);
+       status = celixThreadMutex_create(&(*manager)->importedServicesLock, 
NULL);
+
+       (*manager)->exportedServices = 
hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+       (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+       (*manager)->importInterests = hashMap_create(utils_stringHash, NULL, 
utils_stringEquals, NULL);
+
        return status;
 }
 
 celix_status_t topologyManager_destroy(topology_manager_pt manager) {
-
        celix_status_t status = CELIX_SUCCESS;
 
+       status = celixThreadMutex_lock(&manager->rsaListLock);
+
        arrayList_destroy(manager->rsaList);
+
+       status = celixThreadMutex_unlock(&manager->rsaListLock);
+       status = celixThreadMutex_destroy(&manager->rsaListLock);
+
+       status = celixThreadMutex_lock(&manager->exportedServicesLock);
+
        hashMap_destroy(manager->exportedServices, false, false);
+
+       status = celixThreadMutex_unlock(&manager->exportedServicesLock);
+       status = celixThreadMutex_destroy(&manager->exportedServicesLock);
+
+       status = celixThreadMutex_lock(&manager->importedServicesLock);
+
        hashMap_destroy(manager->importedServices, false, false);
        hashMap_destroy(manager->importInterests, false, false);
 
+       status = celixThreadMutex_unlock(&manager->importedServicesLock);
+       status = celixThreadMutex_destroy(&manager->importedServicesLock);
+
+       free(manager);
+
        return status;
 }
 
@@ -106,8 +129,13 @@ celix_status_t topologyManager_rsaAdded(
        topology_manager_pt manager = handle;
 
        printf("TOPOLOGY_MANAGER: Added RSA\n");
+
+       status = celixThreadMutex_lock(&manager->rsaListLock);
        arrayList_add(manager->rsaList, service);
+       status = celixThreadMutex_unlock(&manager->rsaListLock);
+
        // TODO add the imported/exported services to the given RSA...
+       manager->exportedServices;
 
        return status;
 }
@@ -115,6 +143,9 @@ celix_status_t topologyManager_rsaAdded(
 celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt 
reference, void * service) {
        celix_status_t status = CELIX_SUCCESS;
        topology_manager_pt manager = handle;
+
+       // Nop...
+
        return status;
 }
 
@@ -123,19 +154,36 @@ celix_status_t topologyManager_rsaRemove
        topology_manager_pt manager = handle;
 
        printf("TOPOLOGY_MANAGER: Removed RSA\n");
+
+       status = celixThreadMutex_lock(&manager->rsaListLock);
        arrayList_removeElement(manager->rsaList, service);
+       status = celixThreadMutex_unlock(&manager->rsaListLock);
+
        // TODO remove the imported/exported services from the given RSA...
 
        return status;
 }
 
+celix_status_t topologyManager_getRSAs(topology_manager_pt manager, 
array_list_pt *rsaList) {
+       celix_status_t status = CELIX_SUCCESS;
+
+       status = arrayList_create(rsaList);
+       if (status != CELIX_SUCCESS) {
+               return CELIX_ENOMEM;
+       }
+
+       status = celixThreadMutex_lock(&manager->rsaListLock);
+       arrayList_addAll(*rsaList, manager->rsaList);
+       status = celixThreadMutex_unlock(&manager->rsaListLock);
+
+       return status;
+}
+
 celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt 
event) {
        celix_status_t status = CELIX_SUCCESS;
        service_listener_pt listen = listener;
        topology_manager_pt manager = listen->handle;
 
-       printf("TOPOLOGY_MANAGER: found event reference %p\n", 
event->reference);
-
        service_registration_pt registration = NULL;
        serviceReference_getServiceRegistration(event->reference, 
&registration);
 
@@ -145,33 +193,67 @@ celix_status_t topologyManager_serviceCh
        char *export = properties_get(props, (char *) 
OSGI_RSA_SERVICE_EXPORTED_INTERFACES);
        char *serviceId = properties_get(props, (char 
*)OSGI_FRAMEWORK_SERVICE_ID);
 
-       if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
-               if (export != NULL) {
-                       printf("TOPOLOGY_MANAGER: Service registering: %s\n", 
name);
-                       status = topologyManager_exportService(manager, 
event->reference, serviceId);
-               }
-       } else if (event->type == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
-               printf("TOPOLOGY_MANAGER: Service unregistering: %s\n", name);
-               status = topologyManager_removeService(manager, 
event->reference, serviceId);
+       if (!export) {
+               // Nothing needs to be done: we're not interested...
+               return status;
+       }
+
+       switch (event->type) {
+               case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED:
+                       status = topologyManager_addExportedService(manager, 
event->reference, serviceId);
+                       break;
+               case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED:
+                       status = topologyManager_removeExportedService(manager, 
event->reference, serviceId);
+                       status = topologyManager_addExportedService(manager, 
event->reference, serviceId);
+                       break;
+               case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING:
+                       status = topologyManager_removeExportedService(manager, 
event->reference, serviceId);
+                       break;
+               case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH:
+                       break;
        }
 
        return status;
 }
 
-celix_status_t topologyManager_endpointAdded(void *handle, 
endpoint_description_pt endpoint, char *machtedFilter) {
+celix_status_t topologyManager_addImportedService(void *handle, 
endpoint_description_pt endpoint, char *matchedFilter) {
        celix_status_t status = CELIX_SUCCESS;
        topology_manager_pt manager = handle;
-       printf("TOPOLOGY_MANAGER: Endpoint (%s; %s) added...\n", 
endpoint->service, endpoint->id);
 
-       status = topologyManager_importService(manager, endpoint);
+       printf("TOPOLOGY_MANAGER: Add imported service (%s; %s)...\n", 
endpoint->service, endpoint->id);
+
+       // Create a local copy of the current list of RSAs, to ensure we do not 
run into threading issues...
+       array_list_pt localRSAs = NULL;
+       topologyManager_getRSAs(manager, &localRSAs);
+
+       status = celixThreadMutex_lock(&manager->importedServicesLock);
+
+       hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
+       hashMap_put(manager->importedServices, endpoint, imports);
+
+       int size = arrayList_size(localRSAs);
+       for (int iter = 0; iter < size; iter++) {
+               remote_service_admin_service_pt rsa = arrayList_get(localRSAs, 
iter);
+
+               import_registration_pt import = NULL;
+               status = rsa->importService(rsa->admin, endpoint, &import);
+               if (status == CELIX_SUCCESS) {
+                       hashMap_put(imports, rsa, import);
+               }
+       }
+
+       status = celixThreadMutex_unlock(&manager->importedServicesLock);
 
        return status;
 }
 
-celix_status_t topologyManager_endpointRemoved(void *handle, 
endpoint_description_pt endpoint, char *machtedFilter) {
+celix_status_t topologyManager_removeImportedService(void *handle, 
endpoint_description_pt endpoint, char *matchedFilter) {
        celix_status_t status = CELIX_SUCCESS;
        topology_manager_pt manager = handle;
-       printf("TOPOLOGY_MANAGER: Endpoint (%s; %s) removed...\n", 
endpoint->service, endpoint->id);
+
+       printf("TOPOLOGY_MANAGER: Remove imported service (%s; %s)...\n", 
endpoint->service, endpoint->id);
+
+       status = celixThreadMutex_lock(&manager->importedServicesLock);
 
        if (hashMap_containsKey(manager->importedServices, endpoint)) {
                hash_map_pt imports = hashMap_get(manager->importedServices, 
endpoint);
@@ -179,212 +261,218 @@ celix_status_t topologyManager_endpointR
 
                while (hashMapIterator_hasNext(iter)) {
                        hash_map_entry_pt entry = 
hashMapIterator_nextEntry(iter);
+
                        remote_service_admin_service_pt rsa = 
hashMapEntry_getKey(entry);
                        import_registration_pt import = 
hashMapEntry_getValue(entry);
-                       rsa->importRegistration_close(rsa->admin, import);
+
+                       status = rsa->importRegistration_close(rsa->admin, 
import);
+                       if (status == CELIX_SUCCESS) {
+                               hashMap_remove(imports, rsa);
+                       }
                }
 
                hashMapIterator_destroy(iter);
        }
 
+       status = celixThreadMutex_unlock(&manager->importedServicesLock);
+
        return status;
 }
 
-celix_status_t topologyManager_exportService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId) {
+celix_status_t topologyManager_addExportedService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId) {
        celix_status_t status = CELIX_SUCCESS;
-       hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
 
+       printf("TOPOLOGY_MANAGER: Add exported service (%s)...\n", serviceId);
+
+       // Create a local copy of the current list of RSAs, to ensure we do not 
run into threading issues...
+       array_list_pt localRSAs = NULL;
+       topologyManager_getRSAs(manager, &localRSAs);
+
+       status = celixThreadMutex_lock(&manager->exportedServicesLock);
+
+       hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL);
        hashMap_put(manager->exportedServices, reference, exports);
 
-       if (arrayList_size(manager->rsaList) == 0) {
-               char *symbolicName = NULL;
-               module_pt module = NULL;
-               bundle_pt bundle = NULL;
-               serviceReference_getBundle(reference, &bundle);
-               status = bundle_getCurrentModule(bundle, &module);
-               if (status == CELIX_SUCCESS) {
-                       status = module_getSymbolicName(module, &symbolicName);
-                       if (status == CELIX_SUCCESS) {
-                               printf("TOPOLOGY_MANAGER: No RemoteServiceAdmin 
available, unable to export service from bundle %s.\n", symbolicName);
-                       }
-               }
-       } else {
-               int size = arrayList_size(manager->rsaList);
-               int iter = 0;
-               for (iter = 0; iter < size; iter++) {
-                       remote_service_admin_service_pt rsa = 
arrayList_get(manager->rsaList, iter);
+       int size = arrayList_size(localRSAs);
+       for (int iter = 0; iter < size; iter++) {
+               remote_service_admin_service_pt rsa = arrayList_get(localRSAs, 
iter);
 
-                       array_list_pt endpoints = NULL;
-                       status = rsa->exportService(rsa->admin, serviceId, 
NULL, &endpoints);
-                       if (status == CELIX_SUCCESS) {
-                               hashMap_put(exports, rsa, endpoints);
-                               status = 
topologyManager_notifyListeners(manager, rsa, endpoints);
-                       }
+               array_list_pt endpoints = NULL;
+               status = rsa->exportService(rsa->admin, serviceId, NULL, 
&endpoints);
+
+               if (status == CELIX_SUCCESS) {
+                       hashMap_put(exports, rsa, endpoints);
+                       status = 
topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints);
                }
        }
 
+       status = celixThreadMutex_unlock(&manager->exportedServicesLock);
+
        return status;
 }
 
-celix_status_t topologyManager_notifyListeners(topology_manager_pt manager, 
remote_service_admin_service_pt rsa,  array_list_pt registrations) {
+celix_status_t topologyManager_removeExportedService(topology_manager_pt 
manager, service_reference_pt reference, char *serviceId) {
        celix_status_t status = CELIX_SUCCESS;
-       array_list_pt endpointListeners = NULL;
 
-       status = bundleContext_getServiceReferences(manager->context, 
OSGI_ENDPOINT_LISTENER_SERVICE, NULL, &endpointListeners);
-       if (status == CELIX_SUCCESS) {
-               if (endpointListeners != NULL) {
-                       int eplIt;
-                       for (eplIt = 0; eplIt < 
arrayList_size(endpointListeners); eplIt++) {
-                               service_reference_pt eplRef = 
arrayList_get(endpointListeners, eplIt);
-                               service_registration_pt registration = NULL;
-                               serviceReference_getServiceRegistration(eplRef, 
&registration);
-                               properties_pt props = NULL;
-                               serviceRegistration_getProperties(registration, 
&props);
-                               char *scope = properties_get(props, (char *) 
OSGI_ENDPOINT_LISTENER_SCOPE);
-                               filter_pt filter = filter_create(scope);
-                               endpoint_listener_pt epl = NULL;
-                               status = 
bundleContext_getService(manager->context, eplRef, (void **) &epl);
-                               if (status == CELIX_SUCCESS) {
-                                       int regIt;
-                                       for (regIt = 0; regIt < 
arrayList_size(registrations); regIt++) {
-                                               export_registration_pt export = 
arrayList_get(registrations, regIt);
-                                               export_reference_pt reference = 
NULL;
-                                               endpoint_description_pt 
endpoint = NULL;
-                                               status = 
rsa->exportRegistration_getExportReference(export, &reference);
-                                               if (status == CELIX_SUCCESS) {
-                                                       status = 
rsa->exportReference_getExportedEndpoint(reference, &endpoint);
-                                                       if (status == 
CELIX_SUCCESS) {
-                                                               bool 
matchResult = false;
-                                                               
filter_match(filter, endpoint->properties, &matchResult);
-                                                               if 
(matchResult) {
-                                                                       status 
= epl->endpointAdded(epl->handle, endpoint, scope);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                               filter_destroy(filter);
-                       }
-               }
-        }
+       printf("TOPOLOGY_MANAGER: Remove exported service (%s)...\n", 
serviceId);
 
-       if(endpointListeners != NULL) {
-               arrayList_destroy(endpointListeners);
+       status = celixThreadMutex_lock(&manager->exportedServicesLock);
+
+       hash_map_pt exports = hashMap_get(manager->exportedServices, reference);
+       if (exports) {
+               hash_map_iterator_pt iter = hashMapIterator_create(exports);
+               while (hashMapIterator_hasNext(iter)) {
+                       hash_map_entry_pt entry = 
hashMapIterator_nextEntry(iter);
+
+                       remote_service_admin_service_pt rsa = 
hashMapEntry_getKey(entry);
+                       array_list_pt exports = hashMapEntry_getValue(entry);
+
+                       for (int exportsIter = 0; exportsIter < 
arrayList_size(exports); exportsIter++) {
+                               export_registration_pt export = 
arrayList_get(exports, exportsIter);
+                               rsa->exportRegistration_close(export);
+
+                               
topologyManager_notifyListenersEndpointRemoved(manager, rsa, export);
+                       }
+               }
+               hashMapIterator_destroy(iter);
        }
 
+       status = celixThreadMutex_unlock(&manager->exportedServicesLock);
+
        return status;
 }
 
-celix_status_t topologyManager_importService(topology_manager_pt manager, 
endpoint_description_pt endpoint) {
+celix_status_t 
topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt
 rsa, export_registration_pt export, endpoint_description_pt *endpoint) {
        celix_status_t status = CELIX_SUCCESS;
-       hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL);
-
-       hashMap_put(manager->importedServices, endpoint, imports);
 
-       if (arrayList_size(manager->rsaList) == 0) {
-               printf("TOPOLOGY_MANAGER: No RemoteServiceAdmin available, 
unable to import service %s.\n", endpoint->service);
-       } else {
-               int size = arrayList_size(manager->rsaList);
-               int iter = 0;
-               for (iter = 0; iter < size; iter++) {
-                       remote_service_admin_service_pt rsa = 
arrayList_get(manager->rsaList, iter);
-
-                       import_registration_pt import = NULL;
-                       status = rsa->importService(rsa->admin, endpoint, 
&import);
-                       if (status == CELIX_SUCCESS) {
-                               hashMap_put(imports, rsa, import);
-                       }
-               }
+       export_reference_pt reference = NULL;
+       status = rsa->exportRegistration_getExportReference(export, &reference);
+       if (status != CELIX_SUCCESS) {
+               return status;
        }
 
+       status = rsa->exportReference_getExportedEndpoint(reference, endpoint);
+
        return status;
 }
 
-celix_status_t topologyManager_removeService(topology_manager_pt manager, 
service_reference_pt reference, char *serviceId) {
+celix_status_t 
topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, 
remote_service_admin_service_pt rsa, array_list_pt registrations) {
        celix_status_t status = CELIX_SUCCESS;
 
-       service_registration_pt registration = NULL;
-       serviceReference_getServiceRegistration(reference, &registration);
-       properties_pt props = NULL;
-       serviceRegistration_getProperties(registration, &props);
-       char *name = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
+       array_list_pt endpointListeners = NULL;
+       status = bundleContext_getServiceReferences(manager->context, 
OSGI_ENDPOINT_LISTENER_SERVICE, NULL, &endpointListeners);
+       if (status != CELIX_SUCCESS || !endpointListeners) {
+               return CELIX_BUNDLE_EXCEPTION;
+       }
 
-       printf("TOPOLOGY_MANAGER: Remove Service: %s.\n", name);
+       int eplSize = arrayList_size(endpointListeners);
+       for (int eplIt = 0; eplIt < eplSize; eplIt++) {
+               service_reference_pt eplRef = arrayList_get(endpointListeners, 
eplIt);
 
-       if (hashMap_containsKey(manager->exportedServices, reference)) {
-               hash_map_pt exports = hashMap_get(manager->exportedServices, 
reference);
-               hash_map_iterator_pt iter = hashMapIterator_create(exports);
-               while (hashMapIterator_hasNext(iter)) {
-                       hash_map_entry_pt entry = 
hashMapIterator_nextEntry(iter);
-                       remote_service_admin_service_pt rsa = 
hashMapEntry_getKey(entry);
-                       array_list_pt exports = hashMapEntry_getValue(entry);
-                       int exportsIter = 0;
-                       for (exportsIter = 0; exportsIter < 
arrayList_size(exports); exportsIter++) {
-                               export_registration_pt export = 
arrayList_get(exports, exportsIter);
-                               rsa->exportRegistration_close(export);
-                               
topologyManager_notifyListenersOfRemoval(manager, rsa, export);
+               service_registration_pt registration = NULL;
+               serviceReference_getServiceRegistration(eplRef, &registration);
+
+               properties_pt props = NULL;
+               serviceRegistration_getProperties(registration, &props);
+               char *scope = properties_get(props, (char *) 
OSGI_ENDPOINT_LISTENER_SCOPE);
+
+               endpoint_listener_pt epl = NULL;
+               status = bundleContext_getService(manager->context, eplRef, 
(void **) &epl);
+               if (status != CELIX_SUCCESS || !epl) {
+                       continue;
+               }
+
+               filter_pt filter = filter_create(scope);
+
+               int regSize = arrayList_size(registrations);
+               for (int regIt = 0; regIt < regSize; regIt++) {
+                       export_registration_pt export = 
arrayList_get(registrations, regIt);
+
+                       endpoint_description_pt endpoint = NULL;
+                       status = 
topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, 
&endpoint);
+                       if (status != CELIX_SUCCESS || !endpoint) {
+                               continue;
+                       }
+
+                       bool matchResult = false;
+                       filter_match(filter, endpoint->properties, 
&matchResult);
+                       if (matchResult) {
+                               status = epl->endpointAdded(epl->handle, 
endpoint, scope);
                        }
                }
-               hashMapIterator_destroy(iter);
+
+               filter_destroy(filter);
+       }
+
+       if (endpointListeners) {
+               arrayList_destroy(endpointListeners);
        }
 
        return status;
 }
 
-celix_status_t topologyManager_notifyListenersOfRemoval(topology_manager_pt 
manager, remote_service_admin_service_pt rsa,  export_registration_pt export) {
+celix_status_t 
topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, 
remote_service_admin_service_pt rsa,  export_registration_pt export) {
        celix_status_t status = CELIX_SUCCESS;
-       array_list_pt endpointListeners = NULL;
 
+       array_list_pt endpointListeners = NULL;
        status = bundleContext_getServiceReferences(manager->context, 
OSGI_ENDPOINT_LISTENER_SERVICE, NULL, &endpointListeners);
-       if (status == CELIX_SUCCESS) {
-               if (endpointListeners != NULL) {
-                       int eplIt;
-                       for (eplIt = 0; eplIt < 
arrayList_size(endpointListeners); eplIt++) {
-                               service_reference_pt eplRef = 
arrayList_get(endpointListeners, eplIt);
-                               endpoint_listener_pt epl = NULL;
-                               status = 
bundleContext_getService(manager->context, eplRef, (void **) &epl);
-                               if (status == CELIX_SUCCESS) {
-                                       export_reference_pt reference = NULL;
-                                       endpoint_description_pt endpoint = NULL;
-                                       status = 
rsa->exportRegistration_getExportReference(export, &reference);
-                                       if (status == CELIX_SUCCESS) {
-                                               status = 
rsa->exportReference_getExportedEndpoint(reference, &endpoint);
-                                               if (status == CELIX_SUCCESS) {
-                                                       status = 
epl->endpointRemoved(epl->handle, endpoint, NULL);
-                                               }
-                                       }
-                               }
-                       }
+       if (status != CELIX_SUCCESS || !endpointListeners) {
+               return CELIX_BUNDLE_EXCEPTION;
+       }
+
+       for (int eplIt = 0; eplIt < arrayList_size(endpointListeners); eplIt++) 
{
+               service_reference_pt eplRef = arrayList_get(endpointListeners, 
eplIt);
+
+               endpoint_listener_pt epl = NULL;
+               status = bundleContext_getService(manager->context, eplRef, 
(void **) &epl);
+               if (status != CELIX_SUCCESS || !epl) {
+                       continue;
                }
+
+               endpoint_description_pt endpoint = NULL;
+               status = 
topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, 
&endpoint);
+               if (status != CELIX_SUCCESS || !endpoint) {
+                       continue;
+               }
+
+               status = epl->endpointRemoved(epl->handle, endpoint, NULL);
        }
 
-       if(endpointListeners != NULL) {
+       if (endpointListeners) {
                arrayList_destroy(endpointListeners);
        }
 
        return status;
 }
 
-celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char 
*filter, char **updatedFilter) {
+celix_status_t topologyManager_extendFilter(bundle_context_pt context, char 
*filter, char **updatedFilter) {
        celix_status_t status = CELIX_SUCCESS;
-       apr_pool_t *pool = NULL;
-       apr_pool_create(&pool, manager->pool);
 
-       char *uuid = NULL;
-       bundleContext_getProperty(manager->context, (char 
*)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
-       *updatedFilter = apr_pstrcat(pool, "(&", filter, "(!(", 
OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "=", uuid, ")))", NULL);
+       char* uuid = NULL;
+       status = bundleContext_getProperty(context, (char 
*)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+       if (!uuid) {
+               printf("TOPOLOGY_MANAGER: no framework UUID defined?!\n");
+               return CELIX_BUNDLE_EXCEPTION;
+       }
+
+       int len = 10 + strlen(filter) + 
strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid);
+       *updatedFilter = malloc(len);
+       if (!*updatedFilter) {
+               return CELIX_ENOMEM;
+       }
+
+       sprintf(*updatedFilter, "(&%s(!(%s=%s)))", filter, 
OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+       (*updatedFilter)[len] = 0;
 
        return status;
 }
 
 celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt 
listeners) {
        celix_status_t status = CELIX_SUCCESS;
-
        topology_manager_pt manager = handle;
-       int i;
-       for (i = 0; i < arrayList_size(listeners); i++) {
+
+       for (int i = 0; i < arrayList_size(listeners); i++) {
                listener_hook_info_pt info = arrayList_get(listeners, i);
-               printf("TOPOLOGY_MANAGER: listener with filter \"%s\" added\n", 
info->filter);
 
                bundle_pt bundle, self;
                bundleContext_getBundle(info->context, &bundle);
@@ -394,21 +482,24 @@ celix_status_t topologyManager_listenerA
                        continue;
                }
 
-               char *filter;
-               topologyManager_extendFilter(manager, info->filter, &filter);
+               printf("TOPOLOGY_MANAGER: listener with filter \"%s\" added\n", 
info->filter);
+
+               char *filter = NULL;
+               topologyManager_extendFilter(manager->context, info->filter, 
&filter);
+
+               status = celixThreadMutex_lock(&manager->importedServicesLock);
 
                struct import_interest *interest = 
hashMap_get(manager->importInterests, filter);
-               if (interest != NULL) {
+               if (interest) {
                        interest->refs++;
                } else {
-                       apr_pool_t *pool = NULL;
-                       apr_pool_create(&pool, manager->pool);
-                       interest = apr_palloc(pool, sizeof(*interest));
+                       interest = malloc(sizeof(*interest));
                        interest->filter = filter;
                        interest->refs = 1;
                        hashMap_put(manager->importInterests, filter, interest);
-//                     endpointListener.extendScope(exFilter);
                }
+
+               status = 
celixThreadMutex_unlock(&manager->importedServicesLock);
        }
 
        return status;
@@ -416,34 +507,33 @@ celix_status_t topologyManager_listenerA
 
 celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt 
listeners) {
        celix_status_t status = CELIX_SUCCESS;
-
        topology_manager_pt manager = handle;
-       int i;
-       for (i = 0; i < arrayList_size(listeners); i++) {
+
+       for (int i = 0; i < arrayList_size(listeners); i++) {
                listener_hook_info_pt info = arrayList_get(listeners, i);
+
+               bundle_pt bundle, self;
+               bundleContext_getBundle(info->context, &bundle);
+               bundleContext_getBundle(manager->context, &self);
+               if (bundle == self) {
+                       printf("TOPOLOGY_MANAGER: Ignore myself\n");
+                       continue;
+               }
+
                printf("TOPOLOGY_MANAGER: listener with filter \"%s\" 
removed\n", info->filter);
 
-               char *filter;
-               topologyManager_extendFilter(manager, info->filter, &filter);
+               char *filter = NULL;
+               topologyManager_extendFilter(manager->context, info->filter, 
&filter);
+
+               status = celixThreadMutex_lock(&manager->importedServicesLock);
 
                struct import_interest *interest = 
hashMap_get(manager->importInterests, filter);
-               if (interest != NULL) {
-                       if (interest->refs-- <= 0) {
-                               // last reference, remove from scope
-//                             endpointListener.reduceScope(exFilter);
-                               hashMap_remove(manager->importInterests, 
filter);
-
-                               // clean up import registrations
-//                             List<ImportRegistration> irs = 
importedServices.remove(exFilter);
-//                             if (irs != null) {
-//                                     for (ImportRegistration ir : irs) {
-//                                             if (ir != null) {
-//                                                     ir.close();
-//                                             }
-//                                     }
-//                             }
-                       }
+               if (interest != NULL && interest->refs-- <= 0) {
+                       // last reference, remove from scope
+                       interest = hashMap_remove(manager->importInterests, 
filter);
                }
+
+               status = 
celixThreadMutex_unlock(&manager->importedServicesLock);
        }
 
        return status;


Reply via email to