incubator-celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From abroekh...@apache.org
Subject svn commit: r1043903 [2/5] - /incubator/celix/trunk/celix/
Date Thu, 09 Dec 2010 11:49:43 GMT
Added: incubator/celix/trunk/celix/framework.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/framework.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/framework.c (added)
+++ incubator/celix/trunk/celix/framework.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,745 @@
+/*
+ * framework.c
+ *
+ *  Created on: Mar 23, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <math.h>
+
+#include "framework.h"
+#include "filter.h"
+#include "constants.h"
+#include "archive.h"
+#include "hashtable_itr.h"
+#include "bundle.h"
+#include "wire.h"
+#include "resolver.h"
+#include "utils.h"
+#include "bundle_activator.h"
+#include "service_registry.h"
+#include "bundle_cache.h"
+#include "bundle_archive.h"
+#include "bundle_context.h"
+
+struct activator {
+	void * userData;
+	void (*start)(void * userData, BUNDLE_CONTEXT context);
+	void (*stop)(void * userData, BUNDLE_CONTEXT context);
+	void (*destroy)(void * userData);
+};
+
+//struct exception_context the_exception_context[1];
+
+ARRAY_LIST m_serviceListeners;
+
+HASH_MAP m_installRequestMap;
+
+pthread_mutex_t m_installRequestLock = PTHREAD_MUTEX_INITIALIZER;
+
+void framework_setBundleStateAndNotify(FRAMEWORK framework, BUNDLE bundle, int state);
+void framework_markBundleResolved(FRAMEWORK framework, MODULE module);
+
+bool framework_acquireBundleLock(FRAMEWORK framework, BUNDLE bundle, int desiredStates);
+bool framework_releaseBundleLock(FRAMEWORK framework, BUNDLE bundle);
+
+bool framework_acquireGlobalLock(FRAMEWORK framework);
+void framework_releaseGlobalLock(FRAMEWORK framework);
+
+long framework_getNextBundleId(FRAMEWORK framework);
+
+BUNDLE fw_installBundle2(FRAMEWORK framework, long id, char * location, BUNDLE_ARCHIVE archive);
+
+struct fw_serviceListener {
+	BUNDLE bundle;
+	SERVICE_LISTENER listener;
+	FILTER filter;
+};
+
+typedef struct fw_serviceListener * FW_SERVICE_LISTENER;
+
+FRAMEWORK framework_create() {
+	FRAMEWORK framework = (FRAMEWORK) malloc(sizeof(*framework));
+
+	BUNDLE bundle = bundle_create();
+	framework->bundle = bundle;
+
+	framework->installedBundleMap = NULL;
+	framework->registry = NULL;
+
+	pthread_cond_init(&framework->condition, NULL);
+	pthread_mutex_init(&framework->mutex, NULL);
+	pthread_mutex_init(&framework->bundleLock, NULL);
+
+	framework->interrupted = false;
+
+	framework->globalLockWaitersList = arrayList_create();
+	framework->globalLockCount = 0;
+	framework->globalLockThread = NULL;
+	framework->nextBundleId = 1l;
+
+	m_installRequestMap = hashMap_create(string_hash, string_hash, string_equals, string_equals);
+
+	return framework;
+}
+
+void fw_init(FRAMEWORK framework) {
+	framework_acquireBundleLock(framework, framework->bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE);
+
+	if ((bundle_getState(framework->bundle) == BUNDLE_INSTALLED) || (bundle_getState(framework->bundle) == BUNDLE_RESOLVED)) {
+		PROPERTIES props = createProperties();
+		setProperty(props, (char *) FRAMEWORK_STORAGE, ".cache");
+		framework->cache = bundleCache_create(props);
+
+		if (bundle_getState(framework->bundle) == BUNDLE_INSTALLED) {
+			// clean cache
+			// bundleCache_delete(framework->cache);
+		}
+	}
+
+	framework->installedBundleMap = hashMap_create(string_hash, NULL, string_equals, NULL);
+
+	hashMap_put(framework->installedBundleMap, bundleArchive_getLocation(bundle_getArchive(framework->bundle)), framework->bundle);
+
+	if (resolver_resolve(bundle_getModule(framework->bundle)) == NULL) {
+		printf("Unresolved constraints in System Bundle\n");
+		return;
+	}
+
+	// reload archives from cache
+	ARRAY_LIST archives = bundleCache_getArchives(framework->cache);
+	int arcIdx;
+	for (arcIdx = 0; arcIdx < arrayList_size(archives); arcIdx++) {
+		BUNDLE_ARCHIVE archive = (BUNDLE_ARCHIVE) arrayList_get(archives, arcIdx);
+		framework->nextBundleId = fmaxl(framework->nextBundleId, bundleArchive_getId(archive) + 1);
+
+		if (bundleArchive_getPersistentState(archive) == BUNDLE_UNINSTALLED) {
+			bundleArchive_closeAndDelete(archive);
+		} else {
+			fw_installBundle2(framework, bundleArchive_getId(archive), bundleArchive_getLocation(archive), archive);
+		}
+	}
+	framework->registry = serviceRegistry_create(fw_serviceChanged);
+
+	framework_setBundleStateAndNotify(framework, framework->bundle, BUNDLE_STARTING);
+
+	pthread_cond_init(&framework->shutdownGate, NULL);
+
+	void * handle = dlopen(NULL, RTLD_LAZY|RTLD_LOCAL);
+	if (handle == NULL) {
+		printf ("%s\n", dlerror());
+	}
+
+	bundle_setHandle(framework->bundle, handle);
+
+	ACTIVATOR activator = (ACTIVATOR) malloc(sizeof(*activator));
+	void * (*create)();
+	void (*start)(void * handle, BUNDLE_CONTEXT context);
+	void (*stop)(void * handle, BUNDLE_CONTEXT context);
+	void (*destroy)(void * handle);
+	create = dlsym(bundle_getHandle(framework->bundle), BUNDLE_ACTIVATOR_CREATE);
+	start = dlsym(bundle_getHandle(framework->bundle), BUNDLE_ACTIVATOR_START);
+	stop = dlsym(bundle_getHandle(framework->bundle), BUNDLE_ACTIVATOR_STOP);
+	destroy = dlsym(bundle_getHandle(framework->bundle), BUNDLE_ACTIVATOR_DESTROY);
+	activator->start = start;
+	activator->stop = stop;
+	activator->destroy = destroy;
+	bundle_setActivator(framework->bundle, activator);
+
+	BUNDLE_CONTEXT context = bundleContext_create(framework, framework->bundle);
+	bundle_setContext(framework->bundle, context);
+
+	void * userData = NULL;
+	if (create != NULL) {
+		userData = create();
+	}
+	activator->userData = userData;
+
+	if (start != NULL) {
+		start(userData, bundle_getContext(framework->bundle));
+	}
+
+
+	m_serviceListeners = arrayList_create();
+	framework_releaseBundleLock(framework, framework->bundle);
+}
+
+void framework_start(FRAMEWORK framework) {
+	if (framework_acquireBundleLock(framework, framework->bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE)) {
+		if ((bundle_getState(framework->bundle) == BUNDLE_INSTALLED) || (bundle_getState(framework->bundle) == BUNDLE_RESOLVED)) {
+			fw_init(framework);
+		}
+
+		if (bundle_getState(framework->bundle) == BUNDLE_STARTING) {
+			framework_setBundleStateAndNotify(framework, framework->bundle, BUNDLE_ACTIVE);
+		}
+
+		framework_releaseBundleLock(framework, framework->bundle);
+
+
+	} else {
+		printf("could not get lock\n");
+		return;
+	}
+}
+
+void framework_stop(FRAMEWORK framework) {
+	fw_stopBundle(framework, framework->bundle, 0);
+}
+
+BUNDLE fw_installBundle(FRAMEWORK framework, char * location) {
+	return fw_installBundle2(framework, -1, location, NULL);
+}
+
+BUNDLE fw_installBundle2(FRAMEWORK framework, long id, char * location, BUNDLE_ARCHIVE archive) {
+//	if (location == NULL) {
+//		struct exception e;
+//		e.code = 1;
+//		e.msg = "Location is NULL";
+//		Throw e;
+//	}
+
+  	framework_acquireInstallLock(framework, location);
+
+	if (bundle_getState(framework->bundle) == BUNDLE_STOPPING || bundle_getState(framework->bundle) == BUNDLE_UNINSTALLED) {
+		printf("The framework has been shutdown.\n");
+		return NULL;
+	}
+
+	BUNDLE bundle = framework_getBundle(framework, location);
+	if (bundle != NULL) {
+		framework_releaseInstallLock(framework, location);
+		return bundle;
+	}
+
+	if (archive == NULL) {
+		id = framework_getNextBundleId(framework);
+		archive = bundleCache_createArchive(framework->cache, id, location); //fw_createArchive(id, location);
+	} else {
+		// purge revision
+		// multiple revisions not yet implemented
+	}
+
+	bool locked = framework_acquireGlobalLock(framework);
+	if (!locked) {
+		printf("Unable to acquire the global lock to install the bundle\n");
+		framework_releaseInstallLock(framework, location);
+		return NULL;
+	}
+
+	bundle = bundle_createFromArchive(framework, archive);
+	framework_releaseGlobalLock(framework);
+
+	hashMap_put(framework->installedBundleMap, location, bundle);
+
+  	framework_releaseInstallLock(framework, location);
+
+	return bundle;
+}
+
+void fw_startBundle(FRAMEWORK framework, BUNDLE bundle, int options ATTRIBUTE_UNUSED) {
+	bool lock = framework_acquireBundleLock(framework, bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE);
+	if (!lock) {
+		printf("Unable to start\n");
+		return;
+	}
+
+	HASH_MAP wires;
+
+	void * handle;
+	BUNDLE_CONTEXT context;
+
+	switch (bundle_getState(bundle)) {
+		case BUNDLE_UNINSTALLED:
+			printf("Cannot start bundle since it is uninstalled.");
+			return;
+		case BUNDLE_STARTING:
+			printf("Cannot start bundle since it is starting.");
+			return;
+		case BUNDLE_STOPPING:
+			printf("Cannot start bundle since it is stopping.");
+			return;
+		case BUNDLE_ACTIVE:
+			printf("Cannot start bundle since it is already active.");
+			return;
+		case BUNDLE_INSTALLED:
+			wires = resolver_resolve(bundle_getModule(bundle));
+			framework_markResolvedModules(framework, wires);
+		case BUNDLE_RESOLVED:
+			context = bundleContext_create(framework, bundle);
+			bundle_setContext(bundle, context);
+
+			MANIFEST manifest = getManifest(bundle_getArchive(bundle));
+			char * library = manifest_getValue(manifest, HEADER_LIBRARY);
+
+	#ifdef __linux__
+			 char * library_prefix = "lib";
+			 char * library_extension = ".so";
+	#elif __APPLE__
+			 char * library_prefix = "lib";
+			 char * library_extension = ".dylib";
+	#elif WIN32
+			 char * library_prefix = "";
+			 char * library_extension = ".dll";
+	#endif
+
+			char * root = bundleArchive_getArchiveRoot(bundle_getArchive(bundle));
+			char * revision = bundleArchive_getRevision(bundle_getArchive(bundle));
+			char libraryPath[strlen(root) + strlen(revision) + strlen(library) +
+							 strlen(library_prefix) + strlen(library_extension) + 10];
+			strcpy(libraryPath, root);
+			strcat(libraryPath, "/version");
+			strcat(libraryPath, revision);
+			strcat(libraryPath, "/");
+			strcat(libraryPath, library_prefix);
+			strcat(libraryPath, library);
+			strcat(libraryPath, library_extension);
+
+			handle = dlopen(libraryPath, RTLD_LAZY|RTLD_LOCAL);
+			if (handle == NULL) {
+				printf ("%s\n", dlerror());
+			}
+
+			bundle_setHandle(bundle, handle);
+
+			ACTIVATOR activator = (ACTIVATOR) malloc(sizeof(*activator));
+			void * (*create)();
+			void (*start)(void * userData, BUNDLE_CONTEXT context);
+			void (*stop)(void * userData, BUNDLE_CONTEXT context);
+			void (*destroy)(void * userData);
+			create = dlsym(bundle_getHandle(bundle), BUNDLE_ACTIVATOR_CREATE);
+			start = dlsym(bundle_getHandle(bundle), BUNDLE_ACTIVATOR_START);
+			stop = dlsym(bundle_getHandle(bundle), BUNDLE_ACTIVATOR_STOP);
+			destroy = dlsym(bundle_getHandle(bundle), BUNDLE_ACTIVATOR_DESTROY);
+			activator->start = start;
+			activator->stop = stop;
+			activator->destroy = destroy;
+			bundle_setActivator(bundle, activator);
+
+			framework_setBundleStateAndNotify(framework, bundle, BUNDLE_STARTING);
+
+			void * userData = NULL;
+			if (create != NULL) {
+				userData = create();
+			}
+			activator->userData = userData;
+
+			if (start != NULL) {
+				start(userData, bundle_getContext(bundle));
+			}
+
+			framework_setBundleStateAndNotify(framework, bundle, BUNDLE_ACTIVE);
+
+			break;
+	}
+
+	framework_releaseBundleLock(framework, bundle);
+}
+
+void fw_stopBundle(FRAMEWORK framework, BUNDLE bundle, int options ATTRIBUTE_UNUSED) {
+	if (!framework_acquireBundleLock(framework, bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE)) {
+		printf("Cannot stop bundle");
+		return;
+	}
+
+	switch (bundle_getState(bundle)) {
+		case BUNDLE_UNINSTALLED:
+			printf("Cannot stop bundle since it is uninstalled.");
+			return;
+		case BUNDLE_STARTING:
+			printf("Cannot stop bundle since it is starting.");
+			return;
+		case BUNDLE_STOPPING:
+			printf("Cannot stop bundle since it is stopping.");
+			return;
+		case BUNDLE_INSTALLED:
+		case BUNDLE_RESOLVED:
+			return;
+		case BUNDLE_ACTIVE:
+			// only valid state
+			break;
+	}
+
+	framework_setBundleStateAndNotify(framework, bundle, BUNDLE_STOPPING);
+
+	if (bundle_getActivator(bundle)->stop != NULL) {
+		bundle_getActivator(bundle)->stop(bundle_getActivator(bundle)->userData, bundle_getContext(bundle));
+	}
+
+	if (bundle_getActivator(bundle)->destroy != NULL) {
+		bundle_getActivator(bundle)->destroy(bundle_getActivator(bundle)->userData);
+	}
+
+	if (module_getId(bundle_getModule(bundle)) != 0) {
+		bundle_getActivator(bundle)->start = NULL;
+		bundle_getActivator(bundle)->stop = NULL;
+		bundle_getActivator(bundle)->userData = NULL;
+		free(bundle_getActivator(bundle));
+		bundle_setActivator(bundle, NULL);
+
+		serviceRegistry_unregisterServices(framework->registry, bundle);
+		serviceRegistry_ungetServices(framework->registry, bundle);
+	}
+
+	framework_setBundleStateAndNotify(framework, bundle, BUNDLE_RESOLVED);
+
+	framework_releaseBundleLock(framework, bundle);
+}
+
+SERVICE_REGISTRATION fw_registerService(FRAMEWORK framework, BUNDLE bundle, char * serviceName, void * svcObj, HASHTABLE properties) {
+	if (serviceName == NULL) {
+		printf("Service name cannot be null");
+		return NULL;
+	} else if (svcObj == NULL) {
+		printf("Service object cannot be null");
+		return NULL;
+	}
+
+	SERVICE_REGISTRATION registration = NULL;
+	if (framework_acquireBundleLock(framework, bundle, BUNDLE_STARTING|BUNDLE_ACTIVE)) {
+		registration = serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties);
+		framework_releaseBundleLock(framework, bundle);
+	} else {
+		printf("Can only register services while bundle is active or starting");
+		return NULL;
+	}
+
+	return registration;
+}
+
+ARRAY_LIST fw_getServiceReferences(FRAMEWORK framework, BUNDLE bundle ATTRIBUTE_UNUSED, char * serviceName, char * sfilter) {
+	FILTER filter = NULL;
+	if (sfilter != NULL) {
+		filter = filter_create(sfilter);
+	}
+
+	ARRAY_LIST references = serviceRegistry_getServiceReferences(framework->registry, serviceName, filter);
+
+	if (filter != NULL) {
+		filter_destroy(filter);
+	}
+
+	int refIdx = 0;
+	for (refIdx = 0; (references != NULL) && refIdx < arrayList_size(references); refIdx++) {
+		SERVICE_REFERENCE ref = (SERVICE_REFERENCE) arrayList_get(references, refIdx);
+		SERVICE_REGISTRATION reg = ref->registration;
+		char * serviceName = getProperty(reg->properties, (char *) OBJECTCLASS);
+		if (!serviceReference_isAssignableTo(ref, bundle, serviceName)) {
+			arrayList_remove(references, refIdx);
+			refIdx--;
+		}
+	}
+
+	return references;
+}
+
+void * fw_getService(FRAMEWORK framework, BUNDLE bundle ATTRIBUTE_UNUSED, SERVICE_REFERENCE reference) {
+	return serviceRegistry_getService(framework->registry, bundle, reference);
+}
+
+bool framework_ungetService(FRAMEWORK framework, BUNDLE bundle ATTRIBUTE_UNUSED, SERVICE_REFERENCE reference) {
+	return serviceRegistry_ungetService(framework->registry, bundle, reference);
+}
+
+void fw_addServiceListener(BUNDLE bundle, SERVICE_LISTENER listener, char * sfilter) {
+	FW_SERVICE_LISTENER fwListener = (FW_SERVICE_LISTENER) malloc(sizeof(*fwListener));
+	fwListener->bundle = bundle;
+	if (sfilter != NULL) {
+		FILTER filter = filter_create(sfilter);
+		fwListener->filter = filter;
+	}
+	fwListener->listener = listener;
+	arrayList_add(m_serviceListeners, fwListener);
+}
+
+void fw_removeServiceListener(BUNDLE bundle, SERVICE_LISTENER listener) {
+	unsigned int i;
+	FW_SERVICE_LISTENER element;
+	for (i = 0; i < arrayList_size(m_serviceListeners); i++) {
+		element = (FW_SERVICE_LISTENER) arrayList_get(m_serviceListeners, i);
+		if (element->listener == listener && element->bundle == bundle) {
+			arrayList_remove(m_serviceListeners, i);
+			i--;
+			element->bundle = NULL;
+			filter_destroy(element->filter);
+			element->filter = NULL;
+			element->listener = NULL;
+			free(element);
+			element = NULL;
+			break;
+		}
+	}
+}
+
+void fw_serviceChanged(SERVICE_EVENT event, HASHTABLE oldprops) {
+	unsigned int i;
+	FW_SERVICE_LISTENER element;
+	SERVICE_REGISTRATION registration = event->reference->registration;
+	if (arrayList_size(m_serviceListeners) > 0) {
+		for (i = 0; i < arrayList_size(m_serviceListeners); i++) {
+			int matched = 0;
+			element = (FW_SERVICE_LISTENER) arrayList_get(m_serviceListeners, i);
+			matched = (element->filter == NULL) || filter_match(element->filter, registration->properties);
+			if (matched) {
+				element->listener->serviceChanged(element->listener, event);
+			} else if (event->type == MODIFIED) {
+				int matched = (element->filter == NULL) || filter_match(element->filter, oldprops);
+				if (matched) {
+					SERVICE_EVENT endmatch = (SERVICE_EVENT) malloc(sizeof(*endmatch));
+					endmatch->reference = event->reference;
+					endmatch->type = MODIFIED_ENDMATCH;
+					element->listener->serviceChanged(element->listener, endmatch);
+				}
+			}
+		}
+	}
+}
+
+MANIFEST getManifest(BUNDLE_ARCHIVE archive) {
+	char * root = bundleArchive_getArchiveRoot(archive);
+	char * revision = bundleArchive_getRevision(archive);
+	char manifest[strlen(root) + strlen(revision) + 30];
+	strcpy(manifest, root);
+	strcat(manifest, "/version");
+	strcat(manifest, revision);
+	strcat(manifest, "/MANIFEST/MANIFEST.MF");
+	return manifest_read(manifest);
+}
+
+long framework_getNextBundleId(FRAMEWORK framework) {
+	long id = framework->nextBundleId;
+	framework->nextBundleId++;
+	return id;
+}
+
+void framework_markResolvedModules(FRAMEWORK framework, HASH_MAP resolvedModuleWireMap) {
+	if (resolvedModuleWireMap != NULL) {
+		LINKED_LIST wireList = linkedList_create();
+		HASH_MAP_ITERATOR iterator = hashMapIterator_create(resolvedModuleWireMap);
+		while (hashMapIterator_hasNext(iterator)) {
+			HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iterator);
+			MODULE module = (MODULE) hashMapEntry_getKey(entry);
+			LINKED_LIST wires = (LINKED_LIST) hashMapEntry_getValue(entry);
+
+			linkedList_clear(wireList);
+
+			if (linkedList_size(wires) > 0) {
+				module_setWires(module, wires);
+			}
+
+			module_setResolved(module);
+			resolver_moduleResolved(module);
+			framework_markBundleResolved(framework, module);
+		}
+	}
+}
+
+void framework_markBundleResolved(FRAMEWORK framework, MODULE module) {
+	BUNDLE bundle = module_getBundle(module);
+	if (bundle != NULL) {
+		framework_acquireBundleLock(framework, bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_ACTIVE);
+		if (bundle_getState(bundle) != BUNDLE_INSTALLED) {
+			printf("Trying to resolve a resolved bundle");
+		} else {
+			framework_setBundleStateAndNotify(framework, bundle, BUNDLE_RESOLVED);
+			// framework_fireBundleEvent(BUNDLE_EVENT_RESOLVED, bundle);
+		}
+		framework_releaseBundleLock(framework, bundle);
+	}
+}
+
+ARRAY_LIST framework_getBundles(FRAMEWORK framework) {
+	ARRAY_LIST bundles = arrayList_create();
+	HASH_MAP_ITERATOR iterator = hashMapIterator_create(framework->installedBundleMap);
+	while (hashMapIterator_hasNext(iterator)) {
+		BUNDLE bundle = hashMapIterator_nextValue(iterator);
+		arrayList_add(bundles, bundle);
+	}
+	return bundles;
+}
+
+BUNDLE framework_getBundle(FRAMEWORK framework, char * location) {
+	BUNDLE bundle = hashMap_get(framework->installedBundleMap, location);
+	return bundle;
+}
+
+BUNDLE framework_getBundleById(FRAMEWORK framework, long id) {
+	HASH_MAP_ITERATOR iter = hashMapIterator_create(framework->installedBundleMap);
+	while (hashMapIterator_hasNext(iter)) {
+		BUNDLE b = hashMapIterator_nextValue(iter);
+		if (bundleArchive_getId(bundle_getArchive(b)) == id) {
+			return b;
+		}
+	}
+	return NULL;
+}
+
+int framework_acquireInstallLock(FRAMEWORK framework, char * location) {
+	pthread_mutex_lock(&m_installRequestLock);
+
+	while (hashMap_get(m_installRequestMap, location) != NULL) {
+		pthread_cond_wait(&framework->condition, &m_installRequestLock);
+	}
+	hashMap_put(m_installRequestMap, location, location);
+
+	pthread_mutex_unlock(&m_installRequestLock);
+}
+
+int framework_releaseInstallLock(FRAMEWORK framework, char * location) {
+	pthread_mutex_lock(&m_installRequestLock);
+
+	hashMap_remove(m_installRequestMap, location);
+	pthread_cond_broadcast(&framework->condition);
+
+	pthread_mutex_unlock(&m_installRequestLock);
+}
+
+void framework_setBundleStateAndNotify(FRAMEWORK framework, BUNDLE bundle, int state) {
+	pthread_mutex_lock(&framework->bundleLock);
+
+	bundle_setState(bundle, state);
+	pthread_cond_broadcast(&framework->condition);
+
+	pthread_mutex_unlock(&framework->bundleLock);
+}
+
+bool framework_acquireBundleLock(FRAMEWORK framework, BUNDLE bundle, int desiredStates) {
+	pthread_mutex_lock(&framework->bundleLock);
+
+	while (!bundle_isLockable(bundle)
+			|| ((framework->globalLockThread != NULL)
+			&& (framework->globalLockThread != pthread_self()))) {
+		if ((desiredStates & bundle_getState(bundle)) == 0) {
+			pthread_mutex_unlock(&framework->bundleLock);
+			return false;
+		} else if (framework->globalLockThread == pthread_self()
+				&& (bundle_getLockingThread(bundle) != NULL)
+				&& arrayList_contains(framework->globalLockWaitersList, bundle_getLockingThread(bundle))) {
+			framework->interrupted = true;
+//			pthread_cond_signal_thread_np(&framework->condition, bundle_getLockingThread(bundle));
+			pthread_cond_signal(&framework->condition);
+		}
+
+		pthread_cond_wait(&framework->condition, &framework->bundleLock);
+	}
+
+	if ((desiredStates & bundle_getState(bundle)) == 0) {
+		pthread_mutex_unlock(&framework->bundleLock);
+		return false;
+	}
+
+	if (!bundle_lock(bundle)) {
+		pthread_mutex_unlock(&framework->bundleLock);
+		return false;
+	}
+
+	pthread_mutex_unlock(&framework->bundleLock);
+	return true;
+}
+
+bool framework_releaseBundleLock(FRAMEWORK framework, BUNDLE bundle) {
+	pthread_mutex_lock(&framework->bundleLock);
+
+	if (!bundle_unlock(bundle)) {
+		pthread_mutex_unlock(&framework->bundleLock);
+		return false;
+	}
+	if (bundle_getLockingThread(bundle) == NULL) {
+		pthread_cond_broadcast(&framework->condition);
+	}
+
+	pthread_mutex_unlock(&framework->bundleLock);
+
+	return true;
+}
+
+bool framework_acquireGlobalLock(FRAMEWORK framework) {
+	pthread_mutex_lock(&framework->bundleLock);
+
+	bool interrupted = false;
+
+	while (!interrupted
+			&& (framework->globalLockThread != NULL)
+			&& (framework->globalLockThread != pthread_self())) {
+		pthread_t currentThread = pthread_self();
+		arrayList_add(framework->globalLockWaitersList, currentThread);
+		pthread_cond_broadcast(&framework->condition);
+
+		pthread_cond_wait(&framework->condition, &framework->bundleLock);
+		if (framework->interrupted) {
+			interrupted = true;
+			framework->interrupted = false;
+		}
+
+		arrayList_removeElement(framework->globalLockWaitersList, currentThread);
+	}
+
+	if (!interrupted) {
+		framework->globalLockCount++;
+		framework->globalLockThread = pthread_self();
+	}
+
+	pthread_mutex_unlock(&framework->bundleLock);
+
+	return !interrupted;
+}
+
+void framework_releaseGlobalLock(FRAMEWORK framework) {
+	pthread_mutex_lock(&framework->bundleLock);
+
+	if (framework->globalLockThread == pthread_self()) {
+		framework->globalLockCount--;
+		if (framework->globalLockCount == 0) {
+			framework->globalLockThread = NULL;
+			pthread_cond_broadcast(&framework->condition);
+		}
+	} else {
+		printf("The current thread does not own the global lock");
+	}
+
+	pthread_mutex_unlock(&framework->bundleLock);
+}
+
+void framework_waitForStop(FRAMEWORK framework) {
+	pthread_mutex_lock(&framework->mutex);
+	pthread_cond_wait(&framework->shutdownGate, &framework->mutex);
+	pthread_mutex_unlock(&framework->mutex);
+}
+
+void * framework_shutdown(void * framework) {
+	FRAMEWORK fw = (FRAMEWORK) framework;
+
+	HASH_MAP_ITERATOR iterator = hashMapIterator_create(fw->installedBundleMap);
+	while (hashMapIterator_hasNext(iterator)) {
+		BUNDLE bundle = hashMapIterator_nextValue(iterator);
+		if (bundle_getState(bundle) == BUNDLE_ACTIVE || bundle_getState(bundle) == BUNDLE_STARTING) {
+			fw_stopBundle(fw, bundle, 0);
+		}
+	}
+
+	pthread_mutex_lock(&fw->mutex);
+	pthread_cond_broadcast(&fw->shutdownGate);
+	pthread_mutex_unlock(&fw->mutex);
+
+	pthread_exit(NULL);
+}
+
+void bundleActivator_start(void * userData, BUNDLE_CONTEXT context) {
+	// nothing to do
+}
+
+void bundleActivator_stop(void * userData, BUNDLE_CONTEXT context) {
+	pthread_t shutdownThread;
+	pthread_create(&shutdownThread, NULL, framework_shutdown, bundleContext_getFramework(context));
+}
+
+void bundleActivator_destroy(void * userData) {
+
+}

Added: incubator/celix/trunk/celix/framework.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/framework.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/framework.h (added)
+++ incubator/celix/trunk/celix/framework.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,54 @@
+/*
+ * framework.h
+ *
+ *  Created on: Mar 23, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef FRAMEWORK_H_
+#define FRAMEWORK_H_
+
+#include "headers.h"
+#include "manifest.h"
+#include "wire.h"
+#include "hash_map.h"
+#include "array_list.h"
+
+FRAMEWORK framework_create();
+void fw_init(FRAMEWORK framework);
+
+BUNDLE fw_installBundle(FRAMEWORK framework, char * location);
+
+void fw_startBundle(FRAMEWORK framework, BUNDLE bundle, int options);
+void fw_stopBundle(FRAMEWORK framework, BUNDLE bundle, int options);
+
+SERVICE_REGISTRATION fw_registerService(FRAMEWORK framework, BUNDLE bundle, char * serviceName, void * svcObj, HASHTABLE properties);
+void fw_unregisterService(SERVICE_REGISTRATION registration);
+
+ARRAY_LIST fw_getServiceReferences(FRAMEWORK framework, BUNDLE bundle, char * serviceName, char * filter);
+void * fw_getService(FRAMEWORK framework, BUNDLE bundle, SERVICE_REFERENCE reference);
+bool framework_ungetService(FRAMEWORK framework, BUNDLE bundle, SERVICE_REFERENCE reference);
+
+void fw_addServiceListener(BUNDLE bundle, SERVICE_LISTENER listener, char * filter);
+void fw_removeServiceListener(BUNDLE bundle, SERVICE_LISTENER listener);
+void fw_serviceChanged(SERVICE_EVENT event, HASHTABLE oldprops);
+
+//BUNDLE_ARCHIVE fw_createArchive(long id, char * location);
+//void revise(BUNDLE_ARCHIVE archive, char * location);
+MANIFEST getManifest(BUNDLE_ARCHIVE archive);
+
+BUNDLE findBundle(BUNDLE_CONTEXT context);
+SERVICE_REGISTRATION findRegistration(SERVICE_REFERENCE reference);
+
+SERVICE_REFERENCE listToArray(ARRAY_LIST list);
+void framework_markResolvedModules(FRAMEWORK framework, HASH_MAP wires);
+
+ARRAY_LIST framework_getBundles();
+
+void framework_waitForStop();
+
+ARRAY_LIST framework_getBundles(FRAMEWORK framework);
+BUNDLE framework_getBundle(FRAMEWORK framework, char * location);
+BUNDLE framework_getBundleById(FRAMEWORK framework, long id);
+
+#endif /* FRAMEWORK_H_ */

Added: incubator/celix/trunk/celix/hash_map.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hash_map.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hash_map.c (added)
+++ incubator/celix/trunk/celix/hash_map.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,483 @@
+/*
+ * hash_map.c
+ *
+ *  Created on: Jul 21, 2010
+ *      Author: alexanderb
+ */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "hash_map.h"
+#include "hash_map_private.h"
+
+static unsigned int DEFAULT_INITIAL_CAPACITY = 16;
+static float DEFAULT_LOAD_FACTOR = 0.75f;
+static unsigned int MAXIMUM_CAPACITY = 1 << 30;
+
+unsigned int hashMap_hashCode(void * toHash) {
+	intptr_t address = (intptr_t) toHash;
+	return address;
+}
+
+int hashMap_equals(void * toCompare, void * compare) {
+	return toCompare == compare;
+}
+
+int hashMap_entryEquals(HASH_MAP map, HASH_MAP_ENTRY entry, HASH_MAP_ENTRY compare) {
+	if (entry->key == compare->key || map->equalsKey(entry->key, compare->key)) {
+		if (entry->value == compare->value || map->equalsValue(entry->value, compare->value)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static unsigned int hashMap_hash(unsigned int h) {
+	h += ~(h << 9);
+	h ^=  ((h >> 14) | (h << 18)); /* >>> */
+	h +=  (h << 4);
+	h ^=  ((h >> 10) | (h << 22)); /* >>> */
+	return h;
+}
+
+static unsigned int hashMap_indexFor(unsigned int h, unsigned int length) {
+	return h & (length - 1);
+}
+
+HASH_MAP hashMap_create(unsigned int (*keyHash)(void *), unsigned int (*valueHash)(void *),
+		int (*keyEquals)(void *, void *), int (*valueEquals)(void *, void *)) {
+	HASH_MAP map = (HASH_MAP) malloc(sizeof(*map));
+	map->treshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
+	map->table = (HASH_MAP_ENTRY *) malloc(sizeof(HASH_MAP_ENTRY) * DEFAULT_INITIAL_CAPACITY);
+	memset(map->table, 0, DEFAULT_INITIAL_CAPACITY * sizeof(HASH_MAP_ENTRY *));
+	map->size = 0;
+	map->modificationCount = 0;
+	map->tablelength = DEFAULT_INITIAL_CAPACITY;
+	map->hashKey = hashMap_hashCode;
+	map->hashValue = hashMap_hashCode;
+	map->equalsKey = hashMap_equals;
+	map->equalsValue = hashMap_equals;
+
+	if (keyHash != NULL) {
+		map->hashKey = keyHash;
+	}
+	if (valueHash != NULL) {
+		map->hashValue = valueHash;
+	}
+	if (keyEquals != NULL) {
+		map->equalsKey = keyEquals;
+	}
+	if (valueEquals != NULL) {
+		map->equalsValue = valueEquals;
+	}
+
+	return map;
+}
+
+int hashMap_size(HASH_MAP map) {
+	return map->size;
+}
+
+bool hashMap_isEmpty(HASH_MAP map) {
+	return hashMap_size(map) == 0;
+}
+
+void * hashMap_get(HASH_MAP map, void * key) {
+	if (key == NULL) {
+		HASH_MAP_ENTRY entry = map->table[0];
+		for (entry = map->table[0]; entry != NULL; entry = entry->next) {
+			if (entry->key == NULL) {
+				return entry->value;
+			}
+		}
+		return NULL;
+	}
+
+	unsigned int hash = hashMap_hash(map->hashKey(key));
+	HASH_MAP_ENTRY entry = NULL;
+	for (entry = map->table[hashMap_indexFor(hash, map->tablelength)]; entry != NULL; entry = entry->next) {
+		if (entry->hash == hash && (entry->key == key || map->equalsKey(key, entry->key))) {
+			return entry->value;
+		}
+	}
+	return NULL;
+}
+
+bool hashMap_containsKey(HASH_MAP map, void * key) {
+	return hashMap_getEntry(map, key) != NULL;
+}
+
+HASH_MAP_ENTRY hashMap_getEntry(HASH_MAP map, void * key) {
+	unsigned int hash = (key == NULL) ? 0 : hashMap_hash(map->hashKey(key));
+	HASH_MAP_ENTRY entry;
+	int index = hashMap_indexFor(hash, map->tablelength);
+	for (entry = map->table[index]; entry != NULL; entry = entry->next) {
+		if (entry->hash == hash && (entry->key == key || map->equalsKey(key, entry->key))) {
+			return entry;
+		}
+	}
+	return NULL;
+}
+
+void * hashMap_put(HASH_MAP map, void * key, void * value) {
+	if (key == NULL) {
+		HASH_MAP_ENTRY entry;
+		for (entry = map->table[0]; entry != NULL; entry = entry->next) {
+			if (entry->key == NULL) {
+				void * oldValue = entry->value;
+				entry->value = value;
+				return oldValue;
+			}
+		}
+		map->modificationCount++;
+		hashMap_addEntry(map, 0, NULL, value, 0);
+		return NULL;
+	}
+	unsigned int hash = hashMap_hash(map->hashKey(key));
+	int i = hashMap_indexFor(hash, map->tablelength);
+	HASH_MAP_ENTRY entry;
+	for (entry = map->table[i]; entry != NULL; entry = entry->next) {
+		if (entry->hash == hash && (entry->key == key || map->equalsKey(key, entry->key))) {
+			void * oldValue = entry->value;
+			entry->value = value;
+			return oldValue;
+		}
+	}
+	map->modificationCount++;
+	hashMap_addEntry(map, hash, key, value, i);
+	return NULL;
+}
+
+void hashMap_resize(HASH_MAP map, int newCapacity) {
+	if (map->tablelength == MAXIMUM_CAPACITY) {
+		return;
+	}
+
+	HASH_MAP_ENTRY * newTable = (HASH_MAP_ENTRY *) malloc(sizeof(HASH_MAP_ENTRY) * newCapacity);
+	int j;
+	for (j = 0; j < map->tablelength; j++) {
+		HASH_MAP_ENTRY entry = map->table[j];
+		if (entry != NULL) {
+			map->table[j] = NULL;
+			do {
+				HASH_MAP_ENTRY next = entry->next;
+				int i = hashMap_indexFor(entry->hash, newCapacity);
+				entry->next = newTable[i];
+				newTable[i] = entry;
+				entry = next;
+			} while (entry != NULL);
+		}
+	}
+	free(map->table);
+	map->table = newTable;
+	map->tablelength = newCapacity;
+	map->treshold = (unsigned int) ceil(newCapacity * DEFAULT_LOAD_FACTOR);
+}
+
+void * hashMap_remove(HASH_MAP map, void * key) {
+	HASH_MAP_ENTRY entry = hashMap_removeEntryForKey(map, key);
+	return (entry == NULL ? NULL : entry->value);
+}
+
+void * hashMap_removeEntryForKey(HASH_MAP map, void * key) {
+	unsigned int hash = (key == NULL) ? 0 : hashMap_hash(map->hashKey(key));
+	int i = hashMap_indexFor(hash, map->tablelength);
+	HASH_MAP_ENTRY prev = map->table[i];
+	HASH_MAP_ENTRY entry = prev;
+
+	while (entry != NULL) {
+		HASH_MAP_ENTRY next = entry->next;
+		if (entry->hash == hash && (entry->key == key || key != NULL && map->equalsKey(key, entry->key))) {
+			map->modificationCount++;
+			map->size--;
+			if (prev == entry) {
+				map->table[i] = next;
+			} else {
+				prev->next = next;
+			}
+			return entry;
+		}
+		prev = entry;
+		entry = next;
+	}
+
+	return entry;
+}
+
+HASH_MAP_ENTRY hashMap_removeMapping(HASH_MAP map, HASH_MAP_ENTRY entry) {
+	if (entry == NULL) {
+		return NULL;
+	}
+	unsigned int hash = (entry->key == NULL) ? 0 : hashMap_hash(map->hashKey(entry->key));
+	int i = hashMap_indexFor(hash, map->tablelength);
+	HASH_MAP_ENTRY prev = map->table[i];
+	HASH_MAP_ENTRY e = prev;
+
+	while (e != NULL) {
+		HASH_MAP_ENTRY next = e->next;
+		if (e->hash == hash && hashMap_entryEquals(map, e, entry)) {
+			map->modificationCount++;
+			map->size--;
+			if (prev == e) {
+				map->table[i] = next;
+			} else {
+				prev->next = next;
+			}
+			return e;
+ 		}
+		prev = e;
+		e = next;
+	}
+
+	return e;
+}
+
+void hashMap_clear(HASH_MAP map) {
+	map->modificationCount++;
+	HASH_MAP_ENTRY * table = map->table;
+	int i;
+	for (i = 0; i < map->tablelength; i++) {
+		HASH_MAP_ENTRY entry = table[i];
+		while (entry != NULL) {
+			HASH_MAP_ENTRY f = entry;
+			entry = entry->next;
+			free(f);
+		}
+		table[i] = NULL;
+	}
+	map->size = 0;
+}
+
+bool hashMap_containsValue(HASH_MAP map, void * value) {
+	if (value == NULL) {
+		int i;
+		for (i = 0; i < map->tablelength; i++) {
+			HASH_MAP_ENTRY entry;
+			for (entry = map->table[i]; entry != NULL; entry = entry->next) {
+				if (entry->value == NULL) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	int i;
+	for (i = 0; i < map->tablelength; i++) {
+		HASH_MAP_ENTRY entry;
+		for (entry = map->table[i]; entry != NULL; entry = entry->next) {
+			if (entry->value == value || map->equalsValue(entry->value, value)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+void hashMap_addEntry(HASH_MAP map, int hash, void * key, void * value, int bucketIndex) {
+	HASH_MAP_ENTRY entry = map->table[bucketIndex];
+	HASH_MAP_ENTRY new = (HASH_MAP_ENTRY) malloc(sizeof(*new));
+	new->hash = hash;
+	new->key = key;
+	new->value = value;
+	new->next = entry;
+	map->table[bucketIndex] = new;
+	if (map->size++ >= map->treshold) {
+		hashMap_resize(map, 2 * map->tablelength);
+	}
+}
+
+HASH_MAP_ITERATOR hashMapIterator_create(HASH_MAP map) {
+	HASH_MAP_ITERATOR iterator = (HASH_MAP_ITERATOR) malloc(sizeof(*iterator));
+	iterator->map = map;
+	iterator->expectedModCount = map->modificationCount;
+	iterator->index = 0;
+	iterator->next = NULL;
+	if (map->size > 0) {
+		while (iterator->index < map->tablelength && (iterator->next = map->table[iterator->index++]) == NULL) {
+		}
+	}
+	return iterator;
+}
+
+bool hashMapIterator_hasNext(HASH_MAP_ITERATOR iterator) {
+	return iterator->next != NULL;
+}
+
+void hashMapIterator_remove(HASH_MAP_ITERATOR iterator) {
+	if (iterator->current == NULL) {
+		return;
+	}
+	if (iterator->expectedModCount != iterator->map->modificationCount) {
+		return;
+	}
+	void * key = iterator->current->key;
+	iterator->current = NULL;
+	hashMap_removeEntryForKey(iterator->map, key);
+	iterator->expectedModCount = iterator->map->modificationCount;
+}
+
+void * hashMapIterator_nextValue(HASH_MAP_ITERATOR iterator) {
+	if (iterator->expectedModCount != iterator->map->modificationCount) {
+		return NULL;
+	}
+	HASH_MAP_ENTRY entry = iterator->next;
+	if (entry == NULL) {
+		return NULL;
+	}
+	if ((iterator->next = entry->next) == NULL) {
+		while (iterator->index < iterator->map->tablelength && (iterator->next = iterator->map->table[iterator->index++]) == NULL) {
+		}
+	}
+	iterator->current = entry;
+	return entry->value;
+}
+
+void * hashMapIterator_nextKey(HASH_MAP_ITERATOR iterator) {
+	if (iterator->expectedModCount != iterator->map->modificationCount) {
+		return NULL;
+	}
+	HASH_MAP_ENTRY entry = iterator->next;
+	if (entry == NULL) {
+		return NULL;
+	}
+	if ((iterator->next = entry->next) == NULL) {
+		while (iterator->index < iterator->map->tablelength && (iterator->next = iterator->map->table[iterator->index++]) == NULL) {
+		}
+	}
+	iterator->current = entry;
+	return entry->key;
+}
+
+HASH_MAP_ENTRY hashMapIterator_nextEntry(HASH_MAP_ITERATOR iterator) {
+	if (iterator->expectedModCount != iterator->map->modificationCount) {
+		return NULL;
+	}
+	HASH_MAP_ENTRY entry = iterator->next;
+	if (entry == NULL) {
+		return NULL;
+	}
+	if ((iterator->next = entry->next) == NULL) {
+		while (iterator->index < iterator->map->tablelength && (iterator->next = iterator->map->table[iterator->index++]) == NULL) {
+		}
+	}
+	iterator->current = entry;
+	return entry;
+}
+
+HASH_MAP_KEY_SET hashMapKeySet_create(HASH_MAP map) {
+	HASH_MAP_KEY_SET keySet = (HASH_MAP_KEY_SET) malloc(sizeof(*keySet));
+	keySet->map = map;
+
+	return keySet;
+}
+
+int hashMapKeySet_size(HASH_MAP_KEY_SET keySet) {
+	return keySet->map->size;
+}
+
+bool hashMapKeySet_contains(HASH_MAP_KEY_SET keySet, void * key) {
+	return hashMap_containsKey(keySet->map, key);
+}
+
+bool hashMapKeySet_remove(HASH_MAP_KEY_SET keySet, void * key) {
+	return hashMap_removeEntryForKey(keySet->map, key) != NULL;
+}
+
+void hashMapKeySet_clear(HASH_MAP_KEY_SET keySet) {
+	hashMap_clear(keySet->map);
+}
+
+bool hashMapKeySet_isEmpty(HASH_MAP_KEY_SET keySet) {
+	return hashMapKeySet_size(keySet) == 0;
+}
+
+HASH_MAP_VALUES hashMapValues_create(HASH_MAP map) {
+	HASH_MAP_VALUES values = (HASH_MAP_VALUES) malloc(sizeof(*values));
+	values->map = map;
+
+	return values;
+}
+
+HASH_MAP_ITERATOR hashMapValues_iterator(HASH_MAP_VALUES values) {
+	return hashMapIterator_create(values->map);
+}
+
+int hashMapValues_size(HASH_MAP_VALUES values) {
+	return values->map->size;
+}
+
+bool hashMapValues_contains(HASH_MAP_VALUES values, void * value) {
+	return hashMap_containsValue(values->map, value);
+}
+
+bool hashMapValues_remove(HASH_MAP_VALUES values, void * value) {
+	HASH_MAP_ITERATOR iterator = hashMapValues_iterator(values);
+	if (value == NULL) {
+		while (hashMapIterator_hasNext(iterator)) {
+			if (hashMapIterator_nextValue(iterator) == NULL) {
+				hashMapIterator_remove(iterator);
+				return true;
+			}
+		}
+	} else {
+		while (hashMapIterator_hasNext(iterator)) {
+			if (values->map->equalsValue(value, hashMapIterator_nextValue(iterator))) {
+				hashMapIterator_remove(iterator);
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+void hashMapValues_clear(HASH_MAP_VALUES values) {
+	hashMap_clear(values->map);
+}
+
+bool hashMapValues_isEmpty(HASH_MAP_VALUES values) {
+	return hashMapValues_size(values) == 0;
+}
+
+HASH_MAP_ENTRY_SET hashMapEntrySet_create(HASH_MAP map) {
+	HASH_MAP_ENTRY_SET entrySet = (HASH_MAP_ENTRY_SET) malloc(sizeof(*entrySet));
+	entrySet->map = map;
+
+	return entrySet;
+}
+
+int hashMapEntrySet_size(HASH_MAP_ENTRY_SET entrySet) {
+	return entrySet->map->size;
+}
+
+bool hashMapEntrySet_contains(HASH_MAP_ENTRY_SET entrySet, HASH_MAP_ENTRY entry) {
+	return hashMap_containsValue(entrySet->map, entry);
+}
+
+bool hashMapEntrySet_remove(HASH_MAP_VALUES entrySet, HASH_MAP_ENTRY entry) {
+	return hashMap_removeMapping(entrySet->map, entry) != NULL;
+}
+
+void hashMapEntrySet_clear(HASH_MAP_ENTRY_SET entrySet) {
+	hashMap_clear(entrySet->map);
+}
+
+bool hashMapEntrySet_isEmpty(HASH_MAP_ENTRY_SET entrySet) {
+	return hashMapEntrySet_size(entrySet) == 0;
+}
+
+void * hashMapEntry_getKey(HASH_MAP_ENTRY entry) {
+	return entry->key;
+}
+
+void * hashMapEntry_getValue(HASH_MAP_ENTRY entry) {
+	return entry->value;
+}
+
+
+
+
+

Added: incubator/celix/trunk/celix/hash_map.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hash_map.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hash_map.h (added)
+++ incubator/celix/trunk/celix/hash_map.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,66 @@
+/*
+ * hash_map.h
+ *
+ *  Created on: Jul 21, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef HASH_MAP_H_
+#define HASH_MAP_H_
+
+#include <stdbool.h>
+
+typedef struct hashMapEntry * HASH_MAP_ENTRY;
+typedef struct hashMap * HASH_MAP;
+
+typedef struct hashMapIterator * HASH_MAP_ITERATOR;
+
+typedef struct hashMapKeySet * HASH_MAP_KEY_SET;
+typedef struct hashMapValues * HASH_MAP_VALUES;
+typedef struct hashMapEntrySet * HASH_MAP_ENTRY_SET;
+
+HASH_MAP hashMap_create(unsigned int (*keyHash)(void *), unsigned int (*valueHash)(void *),
+		int (*keyEquals)(void *, void *), int (*valueEquals)(void *, void *));
+int hashMap_size(HASH_MAP map);
+bool hashMap_isEmpty(HASH_MAP map);
+void * hashMap_get(HASH_MAP map, void * key);
+bool hashMap_containsKey(HASH_MAP map, void * key);
+HASH_MAP_ENTRY hashMap_getEntry(HASH_MAP map, void * key);
+void * hashMap_put(HASH_MAP map, void * key, void * value);
+void * hashMap_remove(HASH_MAP map, void * key);
+void hashMap_clear(HASH_MAP map);
+bool hashMap_containsValue(HASH_MAP map, void * value);
+
+HASH_MAP_ITERATOR hashMapIterator_create(HASH_MAP map);
+bool hashMapIterator_hasNext(HASH_MAP_ITERATOR iterator);
+void hashMapIterator_remove(HASH_MAP_ITERATOR iterator);
+void * hashMapIterator_nextValue(HASH_MAP_ITERATOR iterator);
+void * hashMapIterator_nextKey(HASH_MAP_ITERATOR iterator);
+HASH_MAP_ENTRY hashMapIterator_nextEntry(HASH_MAP_ITERATOR iterator);
+
+HASH_MAP_KEY_SET hashMapKeySet_create(HASH_MAP map);
+int hashMapKeySet_size(HASH_MAP_KEY_SET keySet);
+bool hashMapKeySet_contains(HASH_MAP_KEY_SET keySet, void * key);
+bool hashMapKeySet_remove(HASH_MAP_KEY_SET keySet, void * key);
+void hashMapKeySet_clear(HASH_MAP_KEY_SET keySet);
+bool hashMapKeySet_isEmpty(HASH_MAP_KEY_SET keySet);
+
+HASH_MAP_VALUES hashMapValues_create(HASH_MAP map);
+HASH_MAP_ITERATOR hashMapValues_iterator(HASH_MAP_VALUES values);
+int hashMapValues_size(HASH_MAP_VALUES values);
+bool hashMapValues_contains(HASH_MAP_VALUES values, void * o);
+bool hashMapValues_remove(HASH_MAP_VALUES values, void * o);
+void hashMapValues_clear(HASH_MAP_VALUES values);
+bool hashMapValues_isEmpty(HASH_MAP_VALUES values);
+
+HASH_MAP_ENTRY_SET hashMapEntrySet_create(HASH_MAP map);
+int hashMapEntrySet_size(HASH_MAP_ENTRY_SET entrySet);
+bool hashMapEntrySet_contains(HASH_MAP_ENTRY_SET entrySet, HASH_MAP_ENTRY entry);
+bool hashMapEntrySet_remove(HASH_MAP_VALUES entrySet, HASH_MAP_ENTRY entry);
+void hashMapEntrySet_clear(HASH_MAP_ENTRY_SET entrySet);
+bool hashMapEntrySet_isEmpty(HASH_MAP_ENTRY_SET entrySet);
+
+void * hashMapEntry_getKey(HASH_MAP_ENTRY entry);
+void * hashMapEntry_getValue(HASH_MAP_ENTRY entry);
+
+#endif /* HASH_MAP_H_ */

Added: incubator/celix/trunk/celix/hash_map_private.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hash_map_private.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hash_map_private.h (added)
+++ incubator/celix/trunk/celix/hash_map_private.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,62 @@
+/*
+ * hash_map_private.h
+ *
+ *  Created on: Jul 21, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef HASH_MAP_PRIVATE_H_
+#define HASH_MAP_PRIVATE_H_
+
+#include "hash_map.h"
+
+unsigned int hashMap_hashCode(void * toHash);
+int hashMap_equals(void * toCompare, void * compare);
+
+void hashMap_resize(HASH_MAP map, int newCapacity);
+void * hashMap_removeEntryForKey(HASH_MAP map, void * key);
+HASH_MAP_ENTRY hashMap_removeMapping(HASH_MAP map, HASH_MAP_ENTRY entry);
+void hashMap_addEntry(HASH_MAP map, int hash, void * key, void * value, int bucketIndex);
+
+struct hashMapEntry {
+	void * key;
+	void * value;
+	HASH_MAP_ENTRY next;
+	unsigned int hash;
+};
+
+struct hashMap {
+	HASH_MAP_ENTRY * table;
+	unsigned int size;
+	unsigned int treshold;
+	unsigned int modificationCount;
+	unsigned int tablelength;
+
+	unsigned int (*hashKey)(void * key);
+	unsigned int (*hashValue)(void * value);
+	int (*equalsKey)(void * key1, void * key2);
+	int (*equalsValue)(void * value1, void * value2);
+};
+
+struct hashMapIterator {
+	HASH_MAP map;
+	HASH_MAP_ENTRY next;
+	HASH_MAP_ENTRY current;
+	int expectedModCount;
+	int index;
+};
+
+struct hashMapKeySet {
+	HASH_MAP map;
+};
+
+struct hashMapValues {
+	HASH_MAP map;
+};
+
+struct hashMapEntrySet {
+	HASH_MAP map;
+};
+
+
+#endif /* HASH_MAP_PRIVATE_H_ */

Added: incubator/celix/trunk/celix/hashtable.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable.c (added)
+++ incubator/celix/trunk/celix/hashtable.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,274 @@
+/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            //freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable.h (added)
+++ incubator/celix/trunk/celix/hashtable.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,199 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable_itr.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable_itr.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable_itr.c (added)
+++ incubator/celix/trunk/celix/hashtable_itr.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,188 @@
+/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+#include <stdlib.h> /* defines NULL */
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* key      - return the key of the (key,value) pair at the current position */
+/* value    - return the value of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{ return i->e->k; }
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{ return i->e->v; }
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+    struct entry *remember_e, *remember_parent;
+    int ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    free(remember_e);
+    return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k)
+{
+    struct entry *e, *parent;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            return -1;
+        }
+        parent = e;
+        e = e->next;
+    }
+    return 0;
+}
+
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable_itr.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable_itr.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable_itr.h (added)
+++ incubator/celix/trunk/celix/hashtable_itr.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,112 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    struct entry *parent;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable_private.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable_private.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable_private.h (added)
+++ incubator/celix/trunk/celix/hashtable_private.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable_utility.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable_utility.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable_utility.c (added)
+++ incubator/celix/trunk/celix/hashtable_utility.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,71 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_utility.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*****************************************************************************/
+/* hashtable_change
+ *
+ * function to change the value associated with a key, where there already
+ * exists a value bound to the key in the hashtable.
+ * Source due to Holger Schemel.
+ * 
+ *  */
+int
+hashtable_change(struct hashtable *h, void *k, void *v)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            free(e->v);
+            e->v = v;
+            return -1;
+        }
+        e = e->next;
+    }
+    return 0;
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/hashtable_utility.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/hashtable_utility.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/hashtable_utility.h (added)
+++ incubator/celix/trunk/celix/hashtable_utility.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,55 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_CWC22_UTILITY_H__
+#define __HASHTABLE_CWC22_UTILITY_H__
+
+/*****************************************************************************
+ * hashtable_change
+ *
+ * function to change the value associated with a key, where there already
+ * exists a value bound to the key in the hashtable.
+ * Source due to Holger Schemel.
+ *
+ * @name        hashtable_change
+ * @param   h   the hashtable
+ * @param       key
+ * @param       value
+ *
+ */
+int
+hashtable_change(struct hashtable *h, void *k, void *v);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

Added: incubator/celix/trunk/celix/headers.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/headers.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/headers.h (added)
+++ incubator/celix/trunk/celix/headers.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,146 @@
+/*
+ * headers.h
+ *
+ *  Created on: Mar 25, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef HEADERS_H_
+#define HEADERS_H_
+
+#include <stdio.h>
+#include <dirent.h>
+#include <pthread.h>
+
+#include "array_list.h"
+#include "properties.h"
+//#include "cexcept.h"
+#include "linkedlist.h"
+#include "version.h"
+#include "version_range.h"
+#include "manifest.h"
+#include "hash_map.h"
+#include "bundle_archive.h"
+#include "bundle_state.h"
+#include "bundle_cache.h"
+
+#if defined(__GNUC__)
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+
+//struct exception { int code; const char *msg; };
+//define_exception_type(struct exception);
+
+//extern struct exception_context the_exception_context[1];
+
+struct framework {
+	struct bundle * bundle;
+	HASH_MAP installedBundleMap;
+	long nextBundleId;
+	struct serviceRegistry * registry;
+	BUNDLE_CACHE cache;
+
+	pthread_cond_t shutdownGate;
+	pthread_cond_t condition;
+
+	pthread_mutex_t mutex;
+	pthread_mutex_t bundleLock;
+
+	pthread_t globalLockThread;
+	ARRAY_LIST globalLockWaitersList;
+	int globalLockCount;
+
+	bool interrupted;
+};
+
+typedef struct framework * FRAMEWORK;
+
+typedef struct bundleContext * BUNDLE_CONTEXT;
+
+typedef struct activator * ACTIVATOR;
+
+typedef struct module * MODULE;
+
+typedef struct requirement * REQUIREMENT;
+
+typedef struct capability * CAPABILITY;
+
+typedef struct wire * WIRE;
+
+typedef struct bundle * BUNDLE;
+
+struct serviceReference {
+	BUNDLE bundle;
+	struct serviceRegistration * registration;
+};
+
+typedef struct serviceReference * SERVICE_REFERENCE;
+
+typedef enum serviceEventType
+{
+	REGISTERED = 0x00000001,
+	MODIFIED = 0x00000002,
+	UNREGISTERING = 0x00000004,
+	MODIFIED_ENDMATCH = 0x00000008,
+} SERVICE_EVENT_TYPE;
+
+struct serviceEvent {
+	SERVICE_REFERENCE reference;
+	SERVICE_EVENT_TYPE type;
+};
+
+typedef struct serviceEvent * SERVICE_EVENT;
+
+struct serviceRegistry {
+	HASH_MAP serviceRegistrations;
+	HASH_MAP inUseMap;
+	void (*serviceChanged)(SERVICE_EVENT, PROPERTIES);
+	long currentServiceId;
+
+
+	pthread_mutex_t mutex;
+};
+
+typedef struct serviceRegistry * SERVICE_REGISTRY;
+
+struct serviceRegistration {
+	SERVICE_REGISTRY registry;
+	char * className;
+	SERVICE_REFERENCE reference;
+	HASHTABLE properties;
+	void * svcObj;
+	long serviceId;
+
+	pthread_mutex_t mutex;
+	bool isUnregistering;
+};
+
+typedef struct serviceRegistration * SERVICE_REGISTRATION;
+
+struct serviceListener {
+	void * handle;
+	void (*serviceChanged)(void * listener, SERVICE_EVENT event);
+};
+
+typedef struct serviceListener * SERVICE_LISTENER;
+
+struct serviceTrackerCustomizer {
+	void * handle;
+	void * (*addingService)(void * handle, SERVICE_REFERENCE reference);
+	void (*addedService)(void * handle, SERVICE_REFERENCE reference, void * service);
+	void (*modifiedService)(void * handle, SERVICE_REFERENCE reference, void * service);
+	void (*removedService)(void * handle, SERVICE_REFERENCE reference, void * service);
+};
+
+typedef struct serviceTrackerCustomizer * SERVICE_TRACKER_CUSTOMIZER;
+
+struct serviceTracker {
+	BUNDLE_CONTEXT context;
+	char * className;
+};
+
+typedef struct serviceTracker * SERVICE_TRACKER;
+
+#endif /* HEADERS_H_ */



Mime
View raw message