celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From abroekh...@apache.org
Subject svn commit: r1618562 - in /celix/trunk/remote_services/topology_manager/private: include/topology_manager.h src/activator.c src/topology_manager.c
Date Mon, 18 Aug 2014 08:52:48 GMT
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;



Mime
View raw message