You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/12/03 12:09:54 UTC

[2/2] celix git commit: CELIX-317: Apply dm with suspend strategy patch

CELIX-317: Apply dm with suspend strategy patch


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/f26cc786
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/f26cc786
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/f26cc786

Branch: refs/heads/develop
Commit: f26cc7864c63f0bf742a2a7a5bb183948611857e
Parents: e61ef6f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu Dec 3 12:06:57 2015 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu Dec 3 12:06:57 2015 +0100

----------------------------------------------------------------------
 .../include/dm_service_dependency_impl.h        |  1 +
 .../private/src/dm_component_impl.c             | 35 ++++++++++++++++++++
 .../private/src/dm_service_dependency.c         | 29 ++++++++++++++++
 .../public/include/dm_service_dependency.h      |  7 ++++
 .../phase3/private/include/phase3_cmp.h         |  2 +-
 .../phase3/private/src/phase3_activator.c       |  6 +++-
 .../dm_example/phase3/private/src/phase3_cmp.c  | 30 ++++++++++++++++-
 7 files changed, 107 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/dependency_manager/private/include/dm_service_dependency_impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager/private/include/dm_service_dependency_impl.h b/dependency_manager/private/include/dm_service_dependency_impl.h
index bde435f..e018ab1 100644
--- a/dependency_manager/private/include/dm_service_dependency_impl.h
+++ b/dependency_manager/private/include/dm_service_dependency_impl.h
@@ -41,6 +41,7 @@ struct dm_service_dependency {
 	bool available;
 	bool instanceBound;
 	bool required;
+	dm_service_dependency_strategy_t strategy;
 
 	service_set_fpt set;
 	service_add_fpt add;

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/dependency_manager/private/src/dm_component_impl.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_component_impl.c b/dependency_manager/private/src/dm_component_impl.c
index 969c592..699c9e4 100644
--- a/dependency_manager/private/src/dm_component_impl.c
+++ b/dependency_manager/private/src/dm_component_impl.c
@@ -123,6 +123,9 @@ static celix_status_t component_handleChanged(dm_component_pt component, dm_serv
 static celix_status_t component_handleRemoved(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event);
 static celix_status_t component_handleSwapped(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event, dm_event_pt newEvent);
 
+static celix_status_t component_suspend(dm_component_pt component, dm_service_dependency_pt dependency);
+static celix_status_t component_resume(dm_component_pt component, dm_service_dependency_pt dependency);
+
 celix_status_t component_create(bundle_context_pt context, const char *name, dm_component_pt *out) {
     celix_status_t status = CELIX_SUCCESS;
 
@@ -407,6 +410,30 @@ celix_status_t component_handleEventTask(dm_component_pt component, dm_handle_ev
 	return status;
 }
 
+static celix_status_t component_suspend(dm_component_pt component, dm_service_dependency_pt dependency) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	dm_service_dependency_strategy_t strategy;
+	serviceDependency_getStrategy(dependency, &strategy);
+	if (strategy == DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND &&  component->callbackStop != NULL) {
+		status = component->callbackStop(component->implementation);
+	}
+
+	return status;
+}
+
+static celix_status_t component_resume(dm_component_pt component, dm_service_dependency_pt dependency) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	dm_service_dependency_strategy_t strategy;
+	serviceDependency_getStrategy(dependency, &strategy);
+	if (strategy == DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND &&  component->callbackStop != NULL) {
+		status = component->callbackStart(component->implementation);
+	}
+
+	return status;
+}
+
 celix_status_t component_handleAdded(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event) {
     celix_status_t status = CELIX_SUCCESS;
 
@@ -447,7 +474,9 @@ celix_status_t component_handleAdded(dm_component_pt component, dm_service_depen
             break;
         }
         case DM_CMP_STATE_TRACKING_OPTIONAL:
+		component_suspend(component,dependency);
             serviceDependency_invokeAdd(dependency, event);
+		component_resume(component,dependency);
             dm_event_pt event = NULL;
             component_getDependencyEvent(component, dependency, &event);
             component_updateInstance(component, dependency, event, false, true);
@@ -475,7 +504,9 @@ celix_status_t component_handleChanged(dm_component_pt component, dm_service_dep
         serviceDependency_invokeSet(dependency, event);
         switch (component->state) {
             case DM_CMP_STATE_TRACKING_OPTIONAL:
+			component_suspend(component,dependency);
                 serviceDependency_invokeChange(dependency, event);
+			component_resume(component,dependency);
                 dm_event_pt hevent = NULL;
                 component_getDependencyEvent(component, dependency, &hevent);
                 component_updateInstance(component, dependency, hevent, true, false);
@@ -541,8 +572,10 @@ celix_status_t component_handleRemoved(dm_component_pt component, dm_service_dep
                 break;
             }
             case DM_CMP_STATE_TRACKING_OPTIONAL:
+			component_suspend(component,dependency);
                 serviceDependency_invokeSet(dependency, event);
                 serviceDependency_invokeRemove(dependency, event);
+			component_resume(component,dependency);
                 dm_event_pt hevent = NULL;
                 component_getDependencyEvent(component, dependency, &hevent);
                 component_updateInstance(component, dependency, hevent, false, false);
@@ -591,7 +624,9 @@ celix_status_t component_handleSwapped(dm_component_pt component, dm_service_dep
                 break;
             }
             case DM_CMP_STATE_TRACKING_OPTIONAL:
+			component_suspend(component,dependency);
                 serviceDependency_invokeSwap(dependency, event, newEvent);
+			component_resume(component,dependency);
                 break;
             default:
                 break;

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/dependency_manager/private/src/dm_service_dependency.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_service_dependency.c b/dependency_manager/private/src/dm_service_dependency.c
index 636fd47..a85567b 100644
--- a/dependency_manager/private/src/dm_service_dependency.c
+++ b/dependency_manager/private/src/dm_service_dependency.c
@@ -36,6 +36,7 @@
 #include "dm_component_impl.h"
 
 #define DEFAULT_RANKING     0
+#define DM_SERVICE_DEPENDENCY_DEFAULT_STRATEGY DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING
 
 static celix_status_t serviceDependency_addedService(void *_ptr, service_reference_pt reference, void *service);
 static celix_status_t serviceDependency_modifiedService(void *_ptr, service_reference_pt reference, void *service);
@@ -52,6 +53,7 @@ celix_status_t serviceDependency_create(dm_service_dependency_pt *dependency_ptr
 		(*dependency_ptr)->available = false;
 		(*dependency_ptr)->instanceBound = false;
 		(*dependency_ptr)->required = false;
+		(*dependency_ptr)->strategy = DM_SERVICE_DEPENDENCY_DEFAULT_STRATEGY;
 
 		(*dependency_ptr)->set = NULL;
 		(*dependency_ptr)->add = NULL;
@@ -121,6 +123,33 @@ celix_status_t serviceDependency_setRequired(dm_service_dependency_pt dependency
 	return status;
 }
 
+celix_status_t serviceDependency_setStrategy(dm_service_dependency_pt dependency, dm_service_dependency_strategy_t strategy) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+	else{
+		dependency->strategy = strategy;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_getStrategy(dm_service_dependency_pt dependency, dm_service_dependency_strategy_t* strategy){
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+	else{
+		*strategy = dependency->strategy;
+	}
+
+	return status;
+
+}
+
 celix_status_t serviceDependency_setService(dm_service_dependency_pt dependency, char *serviceName, char *filter) {
 	celix_status_t status = CELIX_SUCCESS;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/dependency_manager/public/include/dm_service_dependency.h
----------------------------------------------------------------------
diff --git a/dependency_manager/public/include/dm_service_dependency.h b/dependency_manager/public/include/dm_service_dependency.h
index 1a98dea..0e3f780 100644
--- a/dependency_manager/public/include/dm_service_dependency.h
+++ b/dependency_manager/public/include/dm_service_dependency.h
@@ -33,6 +33,11 @@
 
 typedef struct dm_service_dependency *dm_service_dependency_pt;
 
+typedef enum dm_service_dependency_strategy_enum {
+	DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING,
+	DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
+} dm_service_dependency_strategy_t;
+
 typedef int (*service_set_fpt)(void *handle, void *service);
 typedef int (*service_add_fpt)(void *handle, void *service);
 typedef int (*service_change_fpt)(void *handle, void *service);
@@ -49,6 +54,8 @@ celix_status_t serviceDependency_create(dm_service_dependency_pt *dependency_ptr
 celix_status_t serviceDependency_destroy(dm_service_dependency_pt *dependency_ptr);
 
 celix_status_t serviceDependency_setRequired(dm_service_dependency_pt dependency, bool required);
+celix_status_t serviceDependency_setStrategy(dm_service_dependency_pt dependency,dm_service_dependency_strategy_t strategy);
+celix_status_t serviceDependency_getStrategy(dm_service_dependency_pt dependency,dm_service_dependency_strategy_t* strategy);
 celix_status_t serviceDependency_setService(dm_service_dependency_pt dependency, char *serviceName, char *filter);
 celix_status_t serviceDependency_getFilter(dm_service_dependency_pt dependency, char **filter);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/examples/dm_example/phase3/private/include/phase3_cmp.h
----------------------------------------------------------------------
diff --git a/examples/dm_example/phase3/private/include/phase3_cmp.h b/examples/dm_example/phase3/private/include/phase3_cmp.h
index ec9282d..3e4f087 100644
--- a/examples/dm_example/phase3/private/include/phase3_cmp.h
+++ b/examples/dm_example/phase3/private/include/phase3_cmp.h
@@ -31,7 +31,7 @@
 
 typedef struct phase3_cmp_struct phase3_cmp_t;
 
-phase3_cmp_t *phase3_create(void);
+phase3_cmp_t *phase3_create(bool lockStrategy);
 int phase3_init(phase3_cmp_t *cmp);
 int phase3_start(phase3_cmp_t *cmp);
 int phase3_stop(phase3_cmp_t *cmp);

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/examples/dm_example/phase3/private/src/phase3_activator.c
----------------------------------------------------------------------
diff --git a/examples/dm_example/phase3/private/src/phase3_activator.c b/examples/dm_example/phase3/private/src/phase3_activator.c
index 74f6bb2..bc6a4f7 100644
--- a/examples/dm_example/phase3/private/src/phase3_activator.c
+++ b/examples/dm_example/phase3/private/src/phase3_activator.c
@@ -47,7 +47,10 @@ celix_status_t dm_init(void * userData, bundle_context_pt context, dm_dependency
 
     struct phase3_activator_struct *act = (struct phase3_activator_struct *)userData;
 
-	act->phase3Cmp = phase3_create();
+    dm_service_dependency_strategy_t strategy = DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND;
+    bool lockStrategy = (strategy==DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
+
+	act->phase3Cmp = phase3_create(lockStrategy);
 	if (act->phase3Cmp != NULL) {
 
 		dm_component_pt cmp;
@@ -58,6 +61,7 @@ celix_status_t dm_init(void * userData, bundle_context_pt context, dm_dependency
 		dm_service_dependency_pt dep;
 		serviceDependency_create(&dep);
 		serviceDependency_setService(dep, PHASE2_NAME, NULL);
+		serviceDependency_setStrategy(dep, strategy);
         serviceDependency_setCallbacksSafe(dep, phase3_cmp_t *, phase2_t *, NULL, phase3_addPhase2, NULL, phase3_removePhase2, NULL);
 		serviceDependency_setRequired(dep, true);
 		component_addServiceDependency(cmp, dep);

http://git-wip-us.apache.org/repos/asf/celix/blob/f26cc786/examples/dm_example/phase3/private/src/phase3_cmp.c
----------------------------------------------------------------------
diff --git a/examples/dm_example/phase3/private/src/phase3_cmp.c b/examples/dm_example/phase3/private/src/phase3_cmp.c
index f8ca948..a38d77d 100644
--- a/examples/dm_example/phase3/private/src/phase3_cmp.c
+++ b/examples/dm_example/phase3/private/src/phase3_cmp.c
@@ -40,17 +40,19 @@ struct phase3_cmp_struct {
 	double currentValue;
     celix_thread_mutex_t mutex;
     array_list_pt phase2Services; //phase2_t *
+	bool lockStrategy;
 };
 
 static void *phase3_thread(void *data);
 
-phase3_cmp_t *phase3_create(void) {
+phase3_cmp_t *phase3_create(bool lockStrategy) {
 	phase3_cmp_t *cmp = calloc(1, sizeof(*cmp));
 	if (cmp != NULL) {
 		cmp->currentValue = 0.0;
         cmp->running = false;
         celixThreadMutex_create(&cmp->mutex, NULL);
         arrayList_create(&cmp->phase2Services);
+		cmp->lockStrategy = lockStrategy;
 	}
 	return cmp;
 }
@@ -81,25 +83,44 @@ int phase3_deinit(phase3_cmp_t *cmp) {
 }
 
 void phase3_destroy(phase3_cmp_t *cmp) {
+	if(cmp->lockStrategy){
     celixThreadMutex_lock(&cmp->mutex);
+	}
+
     arrayList_destroy(cmp->phase2Services);
+
+	if(cmp->lockStrategy){
     celixThreadMutex_unlock(&cmp->mutex);
+	}
+
     celixThreadMutex_destroy(&cmp->mutex);
     free(cmp);
 	printf("destroy phase3\n");
 }
 
 int phase3_addPhase2(phase3_cmp_t *cmp, phase2_t *phase2) {
+	if(cmp->lockStrategy){
     celixThreadMutex_lock(&cmp->mutex);
+	}
+
     arrayList_add(cmp->phase2Services, phase2);
+
+	if(cmp->lockStrategy){
     celixThreadMutex_unlock(&cmp->mutex);
+	}
     return 0;
 }
 
 int phase3_removePhase2(phase3_cmp_t *cmp, phase2_t *phase2) {
+	if(cmp->lockStrategy){
     celixThreadMutex_lock(&cmp->mutex);
+	}
+
     arrayList_removeElement(cmp->phase2Services, phase2);
+
+	if(cmp->lockStrategy){
     celixThreadMutex_unlock(&cmp->mutex);
+	}
     return 0;
 }
 
@@ -111,14 +132,21 @@ static void *phase3_thread(void *data) {
     double value;
 
     while (cmp->running) {
+		if(cmp->lockStrategy){
         celixThreadMutex_lock(&cmp->mutex);
+		}
+
         size = arrayList_size(cmp->phase2Services);
         for (i = 0; i < size; i += 1) {
             phase2_t *serv = arrayList_get(cmp->phase2Services, i);
             serv->getData(serv->handle, &value);
             printf("PHASE3: Data from %p is %f\n", serv, value);
         }
+
+		if(cmp->lockStrategy){
         celixThreadMutex_unlock(&cmp->mutex);
+		}
+
         usleep(SLEEPTIME);
     }