CELIX-446: Renames services example to best practice and create a new services example for C.
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5872268f Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5872268f Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5872268f Branch: refs/heads/develop Commit: 5872268f2862bf52b441796b7a5c958946bfef83 Parents: 673837f Author: Pepijn Noltes <[email protected]> Authored: Wed May 9 21:33:42 2018 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Wed May 9 21:33:42 2018 +0200 ---------------------------------------------------------------------- examples/celix-examples/CMakeLists.txt | 2 + .../best_practice_example_c/CMakeLists.txt | 40 ++++ .../best_practice_example_c/api/example.h | 34 ++++ .../best_practice_example_c/bar/CMakeLists.txt | 39 ++++ .../bar/private/include/bar.h | 32 ++++ .../bar/private/src/bar.c | 58 ++++++ .../bar/private/src/bar_activator.c | 70 +++++++ .../best_practice_example_c/foo1/CMakeLists.txt | 39 ++++ .../foo1/private/include/foo1.h | 36 ++++ .../foo1/private/src/foo1.c | 102 +++++++++++ .../foo1/private/src/foo1_activator.c | 88 +++++++++ .../best_practice_example_c/foo2/CMakeLists.txt | 39 ++++ .../foo2/private/include/foo2.h | 36 ++++ .../foo2/private/src/foo2.c | 113 ++++++++++++ .../foo2/private/src/foo2_activator.c | 88 +++++++++ .../services_example_c/CMakeLists.txt | 47 +++-- .../services_example_c/api/example.h | 34 ---- .../services_example_c/api/example_calc.h | 32 ++++ .../services_example_c/bar/CMakeLists.txt | 39 ---- .../bar/private/include/bar.h | 32 ---- .../services_example_c/bar/private/src/bar.c | 58 ------ .../bar/private/src/bar_activator.c | 70 ------- .../services_example_c/foo1/CMakeLists.txt | 39 ---- .../foo1/private/include/foo1.h | 36 ---- .../services_example_c/foo1/private/src/foo1.c | 102 ----------- .../foo1/private/src/foo1_activator.c | 88 --------- .../services_example_c/foo2/CMakeLists.txt | 39 ---- .../foo2/private/include/foo2.h | 36 ---- .../services_example_c/foo2/private/src/foo2.c | 113 ------------ .../foo2/private/src/foo2_activator.c | 88 --------- .../services_example_c/src/consumer_example.c | 182 +++++++++++++++++++ .../services_example_c/src/provider_example.c | 134 ++++++++++++++ framework/include/bundle_context.h | 11 +- framework/include/service_tracker.h | 8 +- framework/private/mock/bundle_context_mock.c | 2 +- framework/src/bundle_context.c | 20 +- framework/src/service_tracker.c | 32 +++- framework/tst/bundle_context_services_test.cpp | 14 +- 38 files changed, 1245 insertions(+), 827 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt index 0937cc9..2ade793 100644 --- a/examples/celix-examples/CMakeLists.txt +++ b/examples/celix-examples/CMakeLists.txt @@ -25,6 +25,8 @@ if (EXAMPLES) add_subdirectory(hello_world_test) add_subdirectory(services_example_c) + + add_subdirectory(best_practice_example_c) add_subdirectory(services_example_cxx) add_subdirectory(dm_example) http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/CMakeLists.txt new file mode 100644 index 0000000..075a6e7 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/CMakeLists.txt @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +include_directories( + ${PROJECT_SOURCE_DIR}/dependency_manager/public/include + ${PROJECT_SOURCE_DIR}/utils/public/include + api +) + +add_subdirectory(foo1) +add_subdirectory(foo2) +add_subdirectory(bar) + +add_celix_container(best_practice_example_c + GROUP services_example + COPY + BUNDLES + Celix::shell + Celix::shell_tui + dm_shell + bar + foo1 + foo2 + PROPERTIES + example=value +) http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/api/example.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/api/example.h b/examples/celix-examples/best_practice_example_c/api/example.h new file mode 100644 index 0000000..b0e0166 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/api/example.h @@ -0,0 +1,34 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +#ifndef EXAMPLE_H_ +#define EXAMPLE_H_ + +#define EXAMPLE_NAME "org.example" +#define EXAMPLE_VERSION "1.0.0" +#define EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)" + + +struct example_struct { + void *handle; + int (*method)(void *handle, int arg1, double arg2, double *result); +} ; + +typedef struct example_struct example_t; + +#endif /* EXAMPLE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt new file mode 100644 index 0000000..7df3051 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +include_directories( + private/include +) + +add_celix_bundle(bar + SYMBOLIC_NAME bar + VERSION 1.0.0 + SOURCES + private/src/bar_activator + private/src/bar.c +) + +IF(APPLE) + target_link_libraries(bar PRIVATE Celix::framework -Wl,-all_load dependency_manager_static) +else() + if(ENABLE_ADDRESS_SANITIZER) + #With asan there can be undefined symbols + target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework ) + else() + target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework ) + endif() +endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h b/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h new file mode 100644 index 0000000..5e1da8b --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h @@ -0,0 +1,32 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#ifndef BAR_H_ +#define BAR_H_ + +#include "example.h" + +typedef struct bar_struct bar_t; + +bar_t* bar_create(void); +void bar_destroy(bar_t *self); + +int bar_method(bar_t *self, int arg1, double arg2, double *out); + +#endif //BAR_H_ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c b/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c new file mode 100644 index 0000000..5099201 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c @@ -0,0 +1,58 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "bar.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <stdbool.h> +#include <pthread.h> +#include <assert.h> + + +#define OK 0 +#define ERROR 1 + +struct bar_struct { + double prefValue; +}; + +bar_t* bar_create(void) { + bar_t *self = calloc(1, sizeof(*self)); + if (self != NULL) { + self->prefValue = 42; + } else { + //log error + } + return self; +}; + +void bar_destroy(bar_t *self) { + free(self); +} + +int bar_method(bar_t *self, int arg1, double arg2, double *out) { + double update = (self->prefValue + arg1) * arg2; + self->prefValue = update; + *out = update; + return OK; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c b/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c new file mode 100644 index 0000000..0fa7889 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c @@ -0,0 +1,70 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "dm_activator.h" +#include "bar.h" + +#include <stdlib.h> + +struct activator { + bar_t *bar; + example_t exampleService; +}; + +celix_status_t dm_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + struct activator *act = calloc(1, sizeof(*act)); + if (act != NULL) { + + act->bar = bar_create(); + act->exampleService.handle = act->bar; + act->exampleService.method = (void*) bar_method; + + if (act->bar != NULL) { + *userData = act; + } else { + free(act); + } + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + dm_component_pt cmp = NULL; + component_create(context, "BAR", &cmp); + component_setImplementation(cmp, activator->bar); + component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL); + + dependencyManager_add(manager, cmp); + return status; +} + +celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + bar_destroy(activator->bar); + free(activator); + return status; +}; + http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt new file mode 100644 index 0000000..d732c76 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +include_directories( + private/include +) + +add_celix_bundle(foo1 + SYMBOLIC_NAME foo1 + VERSION 1.0.0 + SOURCES + private/src/foo1_activator + private/src/foo1.c +) + +IF(APPLE) + target_link_libraries(foo1 PRIVATE -Wl,-all_load dependency_manager_static) +else() + if(ENABLE_ADDRESS_SANITIZER) + #With asan there can be undefined symbols + target_link_libraries(foo1 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) + else() + target_link_libraries(foo1 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) + endif() +endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h b/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h new file mode 100644 index 0000000..f556b44 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h @@ -0,0 +1,36 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#ifndef FOO1_H_ +#define FOO1_H_ + +#include "example.h" + +typedef struct foo1_struct foo1_t; + +foo1_t* foo1_create(void); +void foo1_destroy(foo1_t *self); + +int foo1_start(foo1_t *self); +int foo1_stop(foo1_t *self); + +int foo1_setExample(foo1_t *self, const example_t *example); + + +#endif //FOO1_H_ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c new file mode 100644 index 0000000..1f1f56f --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c @@ -0,0 +1,102 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "foo1.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <stdbool.h> +#include <pthread.h> +#include <assert.h> + + +#define OK 0 +#define ERROR 1 + +static void* foo1_thread(void*); + +struct foo1_struct { + const example_t *example; + pthread_mutex_t mutex; //protecting example + pthread_t thread; + bool running; +}; + +foo1_t* foo1_create(void) { + foo1_t *self = calloc(1, sizeof(*self)); + if (self != NULL) { + pthread_mutex_init(&self->mutex, NULL); + self->running = false; + } else { + //log error + } + return self; +}; + +void foo1_destroy(foo1_t *self) { + assert(!self->running); + pthread_mutex_destroy(&self->mutex); + free(self); +} + +int foo1_start(foo1_t *self) { + printf("starting foo1\n"); + self->running = true; + pthread_create(&self->thread, NULL, foo1_thread, self); + return OK; +} + +int foo1_stop(foo1_t *self) { + printf("stopping foo1\n"); + self->running = false; + pthread_kill(self->thread, SIGUSR1); + pthread_join(self->thread, NULL); + return OK; +} + +int foo1_setExample(foo1_t *self, const example_t *example) { + printf("Setting example %p for foo1\n", example); + pthread_mutex_lock(&self->mutex); + self->example = example; //NOTE could be NULL if req is not mandatory + pthread_mutex_unlock(&self->mutex); + return OK; +} + +static void* foo1_thread(void *userdata) { + foo1_t *self = userdata; + double result; + int rc; + while (self->running) { + pthread_mutex_lock(&self->mutex); + if (self->example != NULL) { + rc = self->example->method(self->example->handle, 1, 2.0, &result); + if (rc == 0) { + printf("Result is %f\n", result); + } else { + printf("Error invoking method for example\n"); + } + } + pthread_mutex_unlock(&self->mutex); + usleep(30000000); + } + return NULL; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c new file mode 100644 index 0000000..f94888b --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c @@ -0,0 +1,88 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "dm_activator.h" +#include "foo1.h" + +#include <stdlib.h> + +struct activator { + foo1_t *foo; +}; + +celix_status_t dm_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + struct activator *act = calloc(1, sizeof(*act)); + if (act != NULL) { + act->foo = foo1_create(); + if (act->foo != NULL) { + *userData = act; + } else { + free(act); + } + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + dm_component_pt cmp = NULL; + component_create(context, "FOO1", &cmp); + component_setImplementation(cmp, activator->foo); + + /* + With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component + with type foo1_t* + */ + component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL); + + dm_service_dependency_pt dep = NULL; + serviceDependency_create(&dep); + serviceDependency_setRequired(dep, true); + serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL); + serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING); + + /* + With the serviceDependency_setCallbacksSafe we register callbacks when a service + is added and about to be removed for the component type foo1_t* and service type example_t*. + + We should protect the usage of the + service because after removal of the service the memory location of that service + could be freed + */ + serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL); + component_addServiceDependency(cmp, dep); + + dependencyManager_add(manager, cmp); + + return status; +} + +celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + foo1_destroy(activator->foo); + free(activator); + return status; +}; + http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt new file mode 100644 index 0000000..adb8f64 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +include_directories( + private/include +) + +add_celix_bundle(foo2 + SYMBOLIC_NAME foo2 + VERSION 1.0.0 + SOURCES + private/src/foo2_activator + private/src/foo2.c +) + +IF(APPLE) + target_link_libraries(foo2 PRIVATE -Wl,-all_load dependency_manager_static) +else() + if(ENABLE_ADDRESS_SANITIZER) + #With asan there can be undefined symbols + target_link_libraries(foo2 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) + else() + target_link_libraries(foo2 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) + endif() +endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h b/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h new file mode 100644 index 0000000..9f09276 --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h @@ -0,0 +1,36 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#ifndef FOO2_H_ +#define FOO2_H_ + +#include "example.h" + +typedef struct foo2_struct foo2_t; + +foo2_t* foo2_create(void); +void foo2_destroy(foo2_t *self); + +int foo2_start(foo2_t *self); +int foo2_stop(foo2_t *self); + +int foo2_addExample(foo2_t *self, const example_t *example); +int foo2_removeExample(foo2_t *self, const example_t *example); + +#endif //FOO2_H_ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c new file mode 100644 index 0000000..b98e20b --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c @@ -0,0 +1,113 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "foo2.h" + +#include "array_list.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <stdbool.h> +#include <pthread.h> +#include <assert.h> + + +#define OK 0 +#define ERROR 1 + +static void* foo2_thread(void*); + +struct foo2_struct { + array_list_pt examples; + pthread_t thread; + bool running; +}; + +foo2_t* foo2_create(void) { + foo2_t *self = calloc(1, sizeof(*self)); + if (self != NULL) { + self->examples = NULL; + arrayList_create(&self->examples); + self->running = false; + } else { + //log error + } + return self; +}; + +void foo2_destroy(foo2_t *self) { + assert(!self->running); + arrayList_destroy(self->examples); + free(self); +} + +int foo2_start(foo2_t *self) { + printf("starting foo2\n"); + self->running = true; + pthread_create(&self->thread, NULL, foo2_thread, self); + return OK; +} + +int foo2_stop(foo2_t *self) { + printf("stopping foo2\n"); + self->running = false; + pthread_kill(self->thread, SIGUSR1); + pthread_join(self->thread, NULL); + return OK; +} + +int foo2_addExample(foo2_t *self, const example_t *example) { + //NOTE foo2 is suspended -> thread is not running -> safe to update + int status = OK; + printf("Adding example %p for foo2\n", example); + status = arrayList_add(self->examples, (void *)example); + return status; +} + +int foo2_removeExample(foo2_t *self, const example_t *example) { + //NOTE foo2 is suspended -> thread is not running -> safe to update + int status = OK; + printf("Removing example %p for foo2\n", example); + status = arrayList_removeElement(self->examples, (void*)example); + return status; +} + +static void* foo2_thread(void *userdata) { + foo2_t *self = userdata; + double result; + int rc; + while (self->running) { + unsigned int size = arrayList_size(self->examples); + int i; + for (i = 0; i < size; i += 1) { + const example_t* example = arrayList_get(self->examples, i); + rc = example->method(example->handle, 1, 2.0, &result); + if (rc == 0) { + printf("Result is %f\n", result); + } else { + printf("Error invoking method for example\n"); + } + } + usleep(15000000); + } + return NULL; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c new file mode 100644 index 0000000..5c047da --- /dev/null +++ b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c @@ -0,0 +1,88 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include "dm_activator.h" +#include "foo2.h" + +#include <stdlib.h> + +struct activator { + foo2_t *foo; +}; + +celix_status_t dm_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + struct activator *act = calloc(1, sizeof(*act)); + if (act != NULL) { + act->foo = foo2_create(); + if (act->foo != NULL) { + *userData = act; + } else { + free(act); + } + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + dm_component_pt cmp = NULL; + component_create(context, "FOO2", &cmp); + component_setImplementation(cmp, activator->foo); + + /* + With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component + with type foo1_t* + */ + component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL); + + dm_service_dependency_pt dep = NULL; + serviceDependency_create(&dep); + serviceDependency_setRequired(dep, false); + serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL); + serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND); + + /* + With the serviceDependency_setCallbacksSafe we register callbacks when a service + is added and about to be removed for the component type foo1_t* and service type example_t*. + + We should protect the usage of the + service because after removal of the service the memory location of that service + could be freed + */ + serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL); + component_addServiceDependency(cmp, dep); + + dependencyManager_add(manager, cmp); + + return status; +} + +celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + foo2_destroy(activator->foo); + free(activator); + return status; +}; + http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/CMakeLists.txt b/examples/celix-examples/services_example_c/CMakeLists.txt index 65760b7..6f7913b 100644 --- a/examples/celix-examples/services_example_c/CMakeLists.txt +++ b/examples/celix-examples/services_example_c/CMakeLists.txt @@ -5,39 +5,36 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -if (BUILD_DEPENDENCY_MANAGER) - include_directories( - ${PROJECT_SOURCE_DIR}/dependency_manager/public/include - ${PROJECT_SOURCE_DIR}/utils/public/include - api - ) +add_library(services_example_c_api INTERFACE) +target_include_directories(services_example_c_api INTERFACE api) - add_subdirectory(foo1) - add_subdirectory(foo2) - add_subdirectory(bar) - add_celix_container(services_example_c - GROUP services_example - COPY - BUNDLES - Celix::shell - Celix::shell_tui - dm_shell - bar - foo1 - foo2 - PROPERTIES - example=value - ) +add_celix_bundle(provider_example + VERSION 1.0.0 + SOURCES src/provider_example.c +) +target_link_libraries(provider_example PRIVATE services_example_c_api) -endif () +add_celix_bundle(consumer_example + VERSION 1.0.0 + SOURCES src/consumer_example.c + ) +target_link_libraries(consumer_example PRIVATE services_example_c_api) + +add_celix_container(services_example_c + BUNDLES + Celix::shell + Celix::shell_tui + provider_example + consumer_example +) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/api/example.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/api/example.h b/examples/celix-examples/services_example_c/api/example.h deleted file mode 100644 index b0e0166..0000000 --- a/examples/celix-examples/services_example_c/api/example.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -#ifndef EXAMPLE_H_ -#define EXAMPLE_H_ - -#define EXAMPLE_NAME "org.example" -#define EXAMPLE_VERSION "1.0.0" -#define EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)" - - -struct example_struct { - void *handle; - int (*method)(void *handle, int arg1, double arg2, double *result); -} ; - -typedef struct example_struct example_t; - -#endif /* EXAMPLE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/api/example_calc.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/api/example_calc.h b/examples/celix-examples/services_example_c/api/example_calc.h new file mode 100644 index 0000000..89481fa --- /dev/null +++ b/examples/celix-examples/services_example_c/api/example_calc.h @@ -0,0 +1,32 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#ifndef CELIX_EXAMPLE_CALC_H +#define CELIX_EXAMPLE_CALC_H + +#define EXAMPLE_CALC_NAME "example_calc" + +struct example_calc { + void *handle; + int (*calc)(void *handle, int input); +}; + +typedef struct example_calc example_calc_t; + +#endif //CELIX_EXAMPLE_CALC_H http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/bar/CMakeLists.txt b/examples/celix-examples/services_example_c/bar/CMakeLists.txt deleted file mode 100644 index 7df3051..0000000 --- a/examples/celix-examples/services_example_c/bar/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include_directories( - private/include -) - -add_celix_bundle(bar - SYMBOLIC_NAME bar - VERSION 1.0.0 - SOURCES - private/src/bar_activator - private/src/bar.c -) - -IF(APPLE) - target_link_libraries(bar PRIVATE Celix::framework -Wl,-all_load dependency_manager_static) -else() - if(ENABLE_ADDRESS_SANITIZER) - #With asan there can be undefined symbols - target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework ) - else() - target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework ) - endif() -endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/include/bar.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/bar/private/include/bar.h b/examples/celix-examples/services_example_c/bar/private/include/bar.h deleted file mode 100644 index 5e1da8b..0000000 --- a/examples/celix-examples/services_example_c/bar/private/include/bar.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#ifndef BAR_H_ -#define BAR_H_ - -#include "example.h" - -typedef struct bar_struct bar_t; - -bar_t* bar_create(void); -void bar_destroy(bar_t *self); - -int bar_method(bar_t *self, int arg1, double arg2, double *out); - -#endif //BAR_H_ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/src/bar.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/bar/private/src/bar.c b/examples/celix-examples/services_example_c/bar/private/src/bar.c deleted file mode 100644 index 5099201..0000000 --- a/examples/celix-examples/services_example_c/bar/private/src/bar.c +++ /dev/null @@ -1,58 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "bar.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <signal.h> -#include <stdbool.h> -#include <pthread.h> -#include <assert.h> - - -#define OK 0 -#define ERROR 1 - -struct bar_struct { - double prefValue; -}; - -bar_t* bar_create(void) { - bar_t *self = calloc(1, sizeof(*self)); - if (self != NULL) { - self->prefValue = 42; - } else { - //log error - } - return self; -}; - -void bar_destroy(bar_t *self) { - free(self); -} - -int bar_method(bar_t *self, int arg1, double arg2, double *out) { - double update = (self->prefValue + arg1) * arg2; - self->prefValue = update; - *out = update; - return OK; -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c b/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c deleted file mode 100644 index 0fa7889..0000000 --- a/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c +++ /dev/null @@ -1,70 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "dm_activator.h" -#include "bar.h" - -#include <stdlib.h> - -struct activator { - bar_t *bar; - example_t exampleService; -}; - -celix_status_t dm_create(bundle_context_pt context, void **userData) { - celix_status_t status = CELIX_SUCCESS; - struct activator *act = calloc(1, sizeof(*act)); - if (act != NULL) { - - act->bar = bar_create(); - act->exampleService.handle = act->bar; - act->exampleService.method = (void*) bar_method; - - if (act->bar != NULL) { - *userData = act; - } else { - free(act); - } - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - - dm_component_pt cmp = NULL; - component_create(context, "BAR", &cmp); - component_setImplementation(cmp, activator->bar); - component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL); - - dependencyManager_add(manager, cmp); - return status; -} - -celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - bar_destroy(activator->bar); - free(activator); - return status; -}; - http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo1/CMakeLists.txt b/examples/celix-examples/services_example_c/foo1/CMakeLists.txt deleted file mode 100644 index d732c76..0000000 --- a/examples/celix-examples/services_example_c/foo1/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include_directories( - private/include -) - -add_celix_bundle(foo1 - SYMBOLIC_NAME foo1 - VERSION 1.0.0 - SOURCES - private/src/foo1_activator - private/src/foo1.c -) - -IF(APPLE) - target_link_libraries(foo1 PRIVATE -Wl,-all_load dependency_manager_static) -else() - if(ENABLE_ADDRESS_SANITIZER) - #With asan there can be undefined symbols - target_link_libraries(foo1 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) - else() - target_link_libraries(foo1 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) - endif() -endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/include/foo1.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo1/private/include/foo1.h b/examples/celix-examples/services_example_c/foo1/private/include/foo1.h deleted file mode 100644 index f556b44..0000000 --- a/examples/celix-examples/services_example_c/foo1/private/include/foo1.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#ifndef FOO1_H_ -#define FOO1_H_ - -#include "example.h" - -typedef struct foo1_struct foo1_t; - -foo1_t* foo1_create(void); -void foo1_destroy(foo1_t *self); - -int foo1_start(foo1_t *self); -int foo1_stop(foo1_t *self); - -int foo1_setExample(foo1_t *self, const example_t *example); - - -#endif //FOO1_H_ http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/src/foo1.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo1/private/src/foo1.c b/examples/celix-examples/services_example_c/foo1/private/src/foo1.c deleted file mode 100644 index 1f1f56f..0000000 --- a/examples/celix-examples/services_example_c/foo1/private/src/foo1.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "foo1.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <signal.h> -#include <stdbool.h> -#include <pthread.h> -#include <assert.h> - - -#define OK 0 -#define ERROR 1 - -static void* foo1_thread(void*); - -struct foo1_struct { - const example_t *example; - pthread_mutex_t mutex; //protecting example - pthread_t thread; - bool running; -}; - -foo1_t* foo1_create(void) { - foo1_t *self = calloc(1, sizeof(*self)); - if (self != NULL) { - pthread_mutex_init(&self->mutex, NULL); - self->running = false; - } else { - //log error - } - return self; -}; - -void foo1_destroy(foo1_t *self) { - assert(!self->running); - pthread_mutex_destroy(&self->mutex); - free(self); -} - -int foo1_start(foo1_t *self) { - printf("starting foo1\n"); - self->running = true; - pthread_create(&self->thread, NULL, foo1_thread, self); - return OK; -} - -int foo1_stop(foo1_t *self) { - printf("stopping foo1\n"); - self->running = false; - pthread_kill(self->thread, SIGUSR1); - pthread_join(self->thread, NULL); - return OK; -} - -int foo1_setExample(foo1_t *self, const example_t *example) { - printf("Setting example %p for foo1\n", example); - pthread_mutex_lock(&self->mutex); - self->example = example; //NOTE could be NULL if req is not mandatory - pthread_mutex_unlock(&self->mutex); - return OK; -} - -static void* foo1_thread(void *userdata) { - foo1_t *self = userdata; - double result; - int rc; - while (self->running) { - pthread_mutex_lock(&self->mutex); - if (self->example != NULL) { - rc = self->example->method(self->example->handle, 1, 2.0, &result); - if (rc == 0) { - printf("Result is %f\n", result); - } else { - printf("Error invoking method for example\n"); - } - } - pthread_mutex_unlock(&self->mutex); - usleep(30000000); - } - return NULL; -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c b/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c deleted file mode 100644 index f94888b..0000000 --- a/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "dm_activator.h" -#include "foo1.h" - -#include <stdlib.h> - -struct activator { - foo1_t *foo; -}; - -celix_status_t dm_create(bundle_context_pt context, void **userData) { - celix_status_t status = CELIX_SUCCESS; - struct activator *act = calloc(1, sizeof(*act)); - if (act != NULL) { - act->foo = foo1_create(); - if (act->foo != NULL) { - *userData = act; - } else { - free(act); - } - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - - dm_component_pt cmp = NULL; - component_create(context, "FOO1", &cmp); - component_setImplementation(cmp, activator->foo); - - /* - With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component - with type foo1_t* - */ - component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL); - - dm_service_dependency_pt dep = NULL; - serviceDependency_create(&dep); - serviceDependency_setRequired(dep, true); - serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL); - serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING); - - /* - With the serviceDependency_setCallbacksSafe we register callbacks when a service - is added and about to be removed for the component type foo1_t* and service type example_t*. - - We should protect the usage of the - service because after removal of the service the memory location of that service - could be freed - */ - serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL); - component_addServiceDependency(cmp, dep); - - dependencyManager_add(manager, cmp); - - return status; -} - -celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - foo1_destroy(activator->foo); - free(activator); - return status; -}; - http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo2/CMakeLists.txt b/examples/celix-examples/services_example_c/foo2/CMakeLists.txt deleted file mode 100644 index adb8f64..0000000 --- a/examples/celix-examples/services_example_c/foo2/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include_directories( - private/include -) - -add_celix_bundle(foo2 - SYMBOLIC_NAME foo2 - VERSION 1.0.0 - SOURCES - private/src/foo2_activator - private/src/foo2.c -) - -IF(APPLE) - target_link_libraries(foo2 PRIVATE -Wl,-all_load dependency_manager_static) -else() - if(ENABLE_ADDRESS_SANITIZER) - #With asan there can be undefined symbols - target_link_libraries(foo2 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) - else() - target_link_libraries(foo2 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive) - endif() -endif() http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/include/foo2.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo2/private/include/foo2.h b/examples/celix-examples/services_example_c/foo2/private/include/foo2.h deleted file mode 100644 index 9f09276..0000000 --- a/examples/celix-examples/services_example_c/foo2/private/include/foo2.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#ifndef FOO2_H_ -#define FOO2_H_ - -#include "example.h" - -typedef struct foo2_struct foo2_t; - -foo2_t* foo2_create(void); -void foo2_destroy(foo2_t *self); - -int foo2_start(foo2_t *self); -int foo2_stop(foo2_t *self); - -int foo2_addExample(foo2_t *self, const example_t *example); -int foo2_removeExample(foo2_t *self, const example_t *example); - -#endif //FOO2_H_ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/src/foo2.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo2/private/src/foo2.c b/examples/celix-examples/services_example_c/foo2/private/src/foo2.c deleted file mode 100644 index b98e20b..0000000 --- a/examples/celix-examples/services_example_c/foo2/private/src/foo2.c +++ /dev/null @@ -1,113 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "foo2.h" - -#include "array_list.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <signal.h> -#include <stdbool.h> -#include <pthread.h> -#include <assert.h> - - -#define OK 0 -#define ERROR 1 - -static void* foo2_thread(void*); - -struct foo2_struct { - array_list_pt examples; - pthread_t thread; - bool running; -}; - -foo2_t* foo2_create(void) { - foo2_t *self = calloc(1, sizeof(*self)); - if (self != NULL) { - self->examples = NULL; - arrayList_create(&self->examples); - self->running = false; - } else { - //log error - } - return self; -}; - -void foo2_destroy(foo2_t *self) { - assert(!self->running); - arrayList_destroy(self->examples); - free(self); -} - -int foo2_start(foo2_t *self) { - printf("starting foo2\n"); - self->running = true; - pthread_create(&self->thread, NULL, foo2_thread, self); - return OK; -} - -int foo2_stop(foo2_t *self) { - printf("stopping foo2\n"); - self->running = false; - pthread_kill(self->thread, SIGUSR1); - pthread_join(self->thread, NULL); - return OK; -} - -int foo2_addExample(foo2_t *self, const example_t *example) { - //NOTE foo2 is suspended -> thread is not running -> safe to update - int status = OK; - printf("Adding example %p for foo2\n", example); - status = arrayList_add(self->examples, (void *)example); - return status; -} - -int foo2_removeExample(foo2_t *self, const example_t *example) { - //NOTE foo2 is suspended -> thread is not running -> safe to update - int status = OK; - printf("Removing example %p for foo2\n", example); - status = arrayList_removeElement(self->examples, (void*)example); - return status; -} - -static void* foo2_thread(void *userdata) { - foo2_t *self = userdata; - double result; - int rc; - while (self->running) { - unsigned int size = arrayList_size(self->examples); - int i; - for (i = 0; i < size; i += 1) { - const example_t* example = arrayList_get(self->examples, i); - rc = example->method(example->handle, 1, 2.0, &result); - if (rc == 0) { - printf("Result is %f\n", result); - } else { - printf("Error invoking method for example\n"); - } - } - usleep(15000000); - } - return NULL; -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c b/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c deleted file mode 100644 index 5c047da..0000000 --- a/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ - -#include "dm_activator.h" -#include "foo2.h" - -#include <stdlib.h> - -struct activator { - foo2_t *foo; -}; - -celix_status_t dm_create(bundle_context_pt context, void **userData) { - celix_status_t status = CELIX_SUCCESS; - struct activator *act = calloc(1, sizeof(*act)); - if (act != NULL) { - act->foo = foo2_create(); - if (act->foo != NULL) { - *userData = act; - } else { - free(act); - } - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - - dm_component_pt cmp = NULL; - component_create(context, "FOO2", &cmp); - component_setImplementation(cmp, activator->foo); - - /* - With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component - with type foo1_t* - */ - component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL); - - dm_service_dependency_pt dep = NULL; - serviceDependency_create(&dep); - serviceDependency_setRequired(dep, false); - serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL); - serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND); - - /* - With the serviceDependency_setCallbacksSafe we register callbacks when a service - is added and about to be removed for the component type foo1_t* and service type example_t*. - - We should protect the usage of the - service because after removal of the service the memory location of that service - could be freed - */ - serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL); - component_addServiceDependency(cmp, dep); - - dependencyManager_add(manager, cmp); - - return status; -} - -celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - foo2_destroy(activator->foo); - free(activator); - return status; -}; - http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/src/consumer_example.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/src/consumer_example.c b/examples/celix-examples/services_example_c/src/consumer_example.c new file mode 100644 index 0000000..c472662 --- /dev/null +++ b/examples/celix-examples/services_example_c/src/consumer_example.c @@ -0,0 +1,182 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <constants.h> + +#include "example_calc.h" +#include "bundle_activator.h" + +typedef struct activator_data { + int trackCount; + celix_bundle_context_t *ctx; + pthread_t thread; + + pthread_mutex_t mutex; //protects running + bool running; +} activator_data_t; + +static bool isRunning(activator_data_t *data) { + bool result = false; + pthread_mutex_lock(&data->mutex); + result = data->running; + pthread_mutex_unlock(&data->mutex); + return result; +} + +static void setRunning(activator_data_t *data, bool val) { + pthread_mutex_lock(&data->mutex); + data->running = val; + pthread_mutex_unlock(&data->mutex); +} + +struct info { + int result; + int count; +}; + +static void useCalc(void *handle, void *svc) { + struct info *i = handle; + example_calc_t *calc = svc; + i->result += calc->calc(calc->handle, 1); + i->count += 1; +} + +static void gccExample(activator_data_t *data) { +#ifdef __GNUC__ + + int result = 0; + long rank = 0; + long svcId = 0; + + void use(void *handle, void *svc, const celix_properties_t *props) { + example_calc_t *calc = svc; + rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L); + svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L); + result = calc->calc(calc->handle, 1); + } + + celix_service_use_options_t opts; + memset(&opts, 0, sizeof(opts)); + + opts.serviceName = EXAMPLE_CALC_NAME; + opts.callbackHandle = NULL; //can be null for trampolines + opts.useWithProperties = use; + bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts); + + printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId); + +#endif +} + +static void clangExample(activator_data_t *data) { +#ifdef __clang__ + /*TODO +#include <Block.h> + __block result = 0; + __block rank = 0; + __block svcId = 0; + + void (^use)(void *handle, void *svc, const celix_properties_t *props) = ^(void *handle, void *svc, const celix_properties_t *props) { + example_calc_t *calc = svc; + rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L); + svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L); + result = calc->calc(calc->handle, 1); + }; + + celix_service_use_options_t opts; + memset(&opts, 0, sizeof(opts)); + + opts.serviceName = EXAMPLE_CALC_NAME; + opts.callbackHandle = NULL; //can be null for trampolines + opts.useWithProperties = use; + bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts); + + printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId); + */ +#endif +} + +void * run(void *handle) { + activator_data_t *data = handle; + + printf("starting consumer thread\n"); + + while (isRunning(data)) { + + struct info info; + info.result = 0; + info.count = 0; + celix_bundleContext_useServices(data->ctx, EXAMPLE_CALC_NAME, &info, useCalc); + printf("Called calc services %i times, total result is %i\n", info.count, info.result); + + gccExample(data); //gcc trampolines example (nested functions) + + clangExample(data); //TODO use clang blocks + + //TODO tracker example + + sleep(5); + } + + printf("exiting consumer thread\n"); + + pthread_exit(NULL); + return NULL; +} + +celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) { + celix_status_t status = CELIX_SUCCESS; + activator_data_t *data = calloc(1, sizeof(*data)); + if (data != NULL) { + data->ctx = ctx; + data->trackCount = 0; + data->running = true; + pthread_mutex_init(&data->mutex, NULL); + *out = data; + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + pthread_create(&data->thread, NULL, run, data); + return CELIX_SUCCESS; +} + +celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + setRunning(data, false); + pthread_join(data->thread, NULL); + return CELIX_SUCCESS; +} + +celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + if (data != NULL) { + pthread_mutex_destroy(&data->mutex); + free(data); + } + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/src/provider_example.c ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_c/src/provider_example.c b/examples/celix-examples/services_example_c/src/provider_example.c new file mode 100644 index 0000000..f322303 --- /dev/null +++ b/examples/celix-examples/services_example_c/src/provider_example.c @@ -0,0 +1,134 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#include "example_calc.h" +#include "bundle_activator.h" +#include "constants.h" + +typedef struct activator_data { + long svcIds[100]; + example_calc_t svc; + celix_bundle_context_t *ctx; + pthread_t thread; + + pthread_mutex_t mutex; //protects running + bool running; +} activator_data_t; + + +static int calc(void *handle __attribute__((unused)), int input) { + return 42 * input; +} + +static bool isRunning(activator_data_t *data) { + bool result = false; + pthread_mutex_lock(&data->mutex); + result = data->running; + pthread_mutex_unlock(&data->mutex); + return result; +} + +static void setRunning(activator_data_t *data, bool val) { + pthread_mutex_lock(&data->mutex); + data->running = val; + pthread_mutex_unlock(&data->mutex); +} + +void * run(void *handle) { + activator_data_t *data = handle; + + printf("starting service register thread\n"); + + int i = 0; + bool up = true; + while (isRunning(data)) { + if (up) { + properties_t *props = properties_create(); + celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand()); + data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props); + } else { //down + celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]); + } + if (i == 99) { + up = false; + } else if (i == 0) { + up = true; + } + usleep(100000); + } + + for (int i = 0; i < 100; ++i) { + long id = data->svcIds[i]; + if (id >=0 ) { + celix_bundleContext_unregisterService(data->ctx, id); + } + } + + printf("exiting service register thread\n"); + + pthread_exit(NULL); + return NULL; +} + +celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) { + celix_status_t status = CELIX_SUCCESS; + activator_data_t *data = calloc(1, sizeof(*data)); + if (data != NULL) { + data->svc.handle = data; + data->svc.calc = calc; + data->ctx = ctx; + data->running = true; + pthread_mutex_init(&data->mutex, NULL); + + for (int i = 0; i < 100; ++i) { + data->svcIds[i] = -1L; + } + + *out = data; + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + pthread_create(&data->thread, NULL, run ,data); + return CELIX_SUCCESS; +} + +celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + setRunning(data, false); + pthread_join(data->thread, NULL); + return CELIX_SUCCESS; +} + +celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) { + activator_data_t *data = handle; + if (data != NULL) { + pthread_mutex_destroy(&data->mutex); + free(data); + } + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/include/bundle_context.h ---------------------------------------------------------------------- diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h index 4ba5904..5ab777a 100644 --- a/framework/include/bundle_context.h +++ b/framework/include/bundle_context.h @@ -330,7 +330,7 @@ bool celix_bundleContext_useServiceWithId( long serviceId, const char *serviceName /*sanity check*/, void *callbackHandle, - void (*use)(void *handle, void* svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) + void (*use)(void *handle, void* svc) ); /** @@ -352,7 +352,7 @@ bool celix_bundleContext_useService( celix_bundle_context_t *ctx, const char* serviceName, void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) + void (*use)(void *handle, void *svc) ); /** @@ -375,7 +375,7 @@ void celix_bundleContext_useServices( celix_bundle_context_t *ctx, const char* serviceName, void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) + void (*use)(void *handle, void *svc) ); @@ -392,7 +392,10 @@ typedef struct celix_service_use_options { * Callback info */ void *callbackHandle; - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); + + void (*use)(void *handle, void *svc); + void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props); + void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); } celix_service_use_options_t; /** http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/include/service_tracker.h ---------------------------------------------------------------------- diff --git a/framework/include/service_tracker.h b/framework/include/service_tracker.h index 513b8cc..baf2a00 100644 --- a/framework/include/service_tracker.h +++ b/framework/include/service_tracker.h @@ -116,7 +116,9 @@ bool celix_serviceTracker_useHighestRankingService( celix_service_tracker_t *tracker, const char *serviceName /*sanity*/, void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner) + void (*use)(void *handle, void *svc), + void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props), + void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner) ); @@ -127,7 +129,9 @@ void celix_serviceTracker_useServices( service_tracker_t *tracker, const char* serviceName /*sanity*/, void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner) + void (*use)(void *handle, void *svc), + void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props), + void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner) ); #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/private/mock/bundle_context_mock.c ---------------------------------------------------------------------- diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c index bddd7fd..8225580 100644 --- a/framework/private/mock/bundle_context_mock.c +++ b/framework/private/mock/bundle_context_mock.c @@ -226,7 +226,7 @@ bool celix_bundleContext_useServiceWithId( long serviceId, const char *serviceName, void *callbackHandle, - void (*use)(void *handle, void* svc, const properties_t *props, const bundle_t *owner) + void (*use)(void *handle, void* svc) ) { mock_c()->actualCall("celix_bundleContext_registerServiceForLang") ->withPointerParameters("ctx", ctx)
