Added functionality to add new interfaces to a DM-component when it is active
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/efed212c Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/efed212c Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/efed212c Branch: refs/heads/master Commit: efed212cbd189666558e2388dbc9bfd4dc276f79 Parents: 6f78b67 Author: Erjan Altena <[email protected]> Authored: Tue Jan 9 14:15:43 2018 +0100 Committer: Erjan Altena <[email protected]> Committed: Tue Jan 9 14:15:43 2018 +0100 ---------------------------------------------------------------------- .../private/src/dm_component_impl.c | 67 +++++++++++--------- .../phase1/private/include/phase1_cmp.h | 3 +- .../phase1/private/src/phase1_activator.c | 1 + .../dm_example/phase1/private/src/phase1_cmp.c | 11 ++++ 4 files changed, 52 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/efed212c/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 13a2ee0..e0d9f52 100644 --- a/dependency_manager/private/src/dm_component_impl.c +++ b/dependency_manager/private/src/dm_component_impl.c @@ -39,7 +39,7 @@ struct dm_component_struct { char id[DM_COMPONENT_MAX_ID_LENGTH]; char name[DM_COMPONENT_MAX_NAME_LENGTH]; bundle_context_pt context; - array_list_pt dm_interfaces; + array_list_pt dm_interfaces; //protected by mutex void* implementation; @@ -338,40 +338,42 @@ celix_status_t component_setCLanguageProperty(dm_component_pt component, bool se celix_status_t component_addInterface(dm_component_pt component, const char* serviceName, const char* serviceVersion, const void* service, properties_pt properties) { celix_status_t status = CELIX_SUCCESS; - if (component->active) { - return CELIX_ILLEGAL_STATE; - } else { - dm_interface_t *interface = (dm_interface_t *) calloc(1, sizeof(*interface)); - char *name = strdup(serviceName); + dm_interface_t *interface = (dm_interface_t *) calloc(1, sizeof(*interface)); + char *name = strdup(serviceName); - if (properties == NULL) { - properties = properties_create(); - } + if (properties == NULL) { + properties = properties_create(); + } - if ((properties_get(properties, CELIX_FRAMEWORK_SERVICE_VERSION) == NULL) && (serviceVersion != NULL)) { - properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion); - } + if ((properties_get(properties, CELIX_FRAMEWORK_SERVICE_VERSION) == NULL) && (serviceVersion != NULL)) { + properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion); + } - if (component->setCLanguageProperty && properties_get(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE) == NULL) { //always set default lang to C - properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE); - } + if (component->setCLanguageProperty && properties_get(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE) == NULL) { //always set default lang to C + properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE); + } - if (interface && name) { - interface->serviceName = name; - interface->service = service; - interface->properties = properties; - interface->registration = NULL; - arrayList_add(component->dm_interfaces, interface); - } else { - free(interface); - free(name); - status = CELIX_ENOMEM; + if (interface && name) { + interface->serviceName = name; + interface->service = service; + interface->properties = properties; + interface->registration = NULL; + celixThreadMutex_lock(&component->mutex); + arrayList_add(component->dm_interfaces, interface); + celixThreadMutex_unlock(&component->mutex); + if (component->state == DM_CMP_STATE_TRACKING_OPTIONAL) { + component_registerServices(component); } + } else { + free(interface); + free(name); + status = CELIX_ENOMEM; } return status; } + celix_status_t component_getInterfaces(dm_component_pt component, array_list_pt *out) { celix_status_t status = CELIX_SUCCESS; array_list_pt names = NULL; @@ -1179,12 +1181,17 @@ celix_status_t component_registerServices(dm_component_pt component) { if (component->context != NULL) { unsigned int i; + celixThreadMutex_lock(&component->mutex); for (i = 0; i < arrayList_size(component->dm_interfaces); i++) { dm_interface_t *interface = arrayList_get(component->dm_interfaces, i); + if (interface->registration == NULL) { properties_pt regProps = NULL; properties_copy(interface->properties, ®Props); - bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, &interface->registration); + bundleContext_registerService(component->context, interface->serviceName, interface->service, regProps, + &interface->registration); + } } + celixThreadMutex_unlock(&component->mutex); } return status; @@ -1195,12 +1202,14 @@ celix_status_t component_unregisterServices(dm_component_pt component) { unsigned int i; + celixThreadMutex_lock(&component->mutex); for (i = 0; i < arrayList_size(component->dm_interfaces); i++) { - dm_interface_t *interface = arrayList_get(component->dm_interfaces, i); + dm_interface_t *interface = arrayList_get(component->dm_interfaces, i); - serviceRegistration_unregister(interface->registration); - interface->registration = NULL; + serviceRegistration_unregister(interface->registration); + interface->registration = NULL; } + celixThreadMutex_unlock(&component->mutex); return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/efed212c/examples/dm_example/phase1/private/include/phase1_cmp.h ---------------------------------------------------------------------- diff --git a/examples/dm_example/phase1/private/include/phase1_cmp.h b/examples/dm_example/phase1/private/include/phase1_cmp.h index 5715f6e..153eed1 100644 --- a/examples/dm_example/phase1/private/include/phase1_cmp.h +++ b/examples/dm_example/phase1/private/include/phase1_cmp.h @@ -26,11 +26,12 @@ #ifndef PHASE1_CMP_H #define PHASE1_CMP_H - +#include "dm_component.h" typedef struct phase1_cmp_struct phase1_cmp_t; phase1_cmp_t *phase1_create(void); +void phase1_setComp(phase1_cmp_t *cmp, dm_component_pt dmCmp); int phase1_init(phase1_cmp_t *cmp); int phase1_start(phase1_cmp_t *cmp); int phase1_stop(phase1_cmp_t *cmp); http://git-wip-us.apache.org/repos/asf/celix/blob/efed212c/examples/dm_example/phase1/private/src/phase1_activator.c ---------------------------------------------------------------------- diff --git a/examples/dm_example/phase1/private/src/phase1_activator.c b/examples/dm_example/phase1/private/src/phase1_activator.c index 783e642..31dcb16 100644 --- a/examples/dm_example/phase1/private/src/phase1_activator.c +++ b/examples/dm_example/phase1/private/src/phase1_activator.c @@ -62,6 +62,7 @@ celix_status_t dm_init(void * userData, bundle_context_pt context, dm_dependency component_create(context, "PHASE1_PROCESSING_COMPONENT", &cmp); component_setImplementation(cmp, act->phase1Cmp); component_setCallbacksSafe(cmp, phase1_cmp_t *, phase1_init, phase1_start, phase1_stop, phase1_deinit); + phase1_setComp(act->phase1Cmp, cmp); component_addInterface(cmp, PHASE1_NAME, PHASE1_VERSION, &act->phase1Serv, props); dependencyManager_add(manager, cmp); http://git-wip-us.apache.org/repos/asf/celix/blob/efed212c/examples/dm_example/phase1/private/src/phase1_cmp.c ---------------------------------------------------------------------- diff --git a/examples/dm_example/phase1/private/src/phase1_cmp.c b/examples/dm_example/phase1/private/src/phase1_cmp.c index 75de182..40da821 100644 --- a/examples/dm_example/phase1/private/src/phase1_cmp.c +++ b/examples/dm_example/phase1/private/src/phase1_cmp.c @@ -31,6 +31,7 @@ #include "celix_threads.h" #include "phase1_cmp.h" +#include "dm_component.h" #define SLEEPTIME 1000 @@ -38,6 +39,8 @@ struct phase1_cmp_struct { celix_thread_t thread; bool running; unsigned int counter; + dm_component_pt component; + }; static void *phase1_thread(void *data); @@ -51,6 +54,10 @@ phase1_cmp_t *phase1_create(void) { return cmp; } +void phase1_setComp(phase1_cmp_t *cmp, dm_component_pt dmCmp) { + cmp->component = dmCmp; +} + int phase1_init(phase1_cmp_t *cmp) { printf("init phase1\n"); return 0; @@ -86,6 +93,10 @@ static void *phase1_thread(void *data) { while (cmp->running) { cmp->counter += 1; + if (cmp->counter == 2) { + static char *runtime_interface = "DUMMY INTERFACE: DO NOT USE\n"; + component_addInterface(cmp->component, "RUNTIME_ADDED_INTERFACE", "1.0.0", runtime_interface, NULL); + } usleep(SLEEPTIME); }
