celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject [2/2] celix git commit: CELIX-368: Updates using services documentation. Update c example and adds C++ example. Updates C++ DM API
Date Wed, 05 Oct 2016 20:35:03 GMT
CELIX-368: Updates using services documentation. Update c example and adds C++ example. Updates C++ DM API


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

Branch: refs/heads/develop
Commit: 1b25a0a8e0cb07521c4d341ef3d60a7fcaedf70c
Parents: 42414fa
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Wed Oct 5 22:38:05 2016 +0200
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Wed Oct 5 22:38:05 2016 +0200

----------------------------------------------------------------------
 .../include/celix/dm/Component.h                |   4 +-
 .../include/celix/dm/Component_Impl.h           |  12 +-
 .../include/celix/dm/DependencyManager.h        |   3 +-
 .../include/celix/dm/ServiceDependency.h        |  22 +--
 .../include/celix/dm/ServiceDependency_Impl.h   |  25 +++-
 dependency_manager_cxx/include/celix/dm/types.h |   2 +-
 .../getting_started/using_services_with_c.md    |  20 ++-
 .../getting_started/using_services_with_cxx.md  | 140 +++++++++++++++++++
 examples/CMakeLists.txt                         |   3 +-
 examples/best_practice_example/CMakeLists.txt   |  42 ------
 examples/best_practice_example/README.md        |   3 -
 examples/best_practice_example/api/example.h    |  34 -----
 .../best_practice_example/bar/CMakeLists.txt    |  39 ------
 .../bar/private/include/bar.h                   |  32 -----
 .../best_practice_example/bar/private/src/bar.c |  58 --------
 .../bar/private/src/bar_activator.c             |  70 ----------
 .../best_practice_example/foo1/CMakeLists.txt   |  39 ------
 .../foo1/private/include/foo1.h                 |  36 -----
 .../foo1/private/src/foo1.c                     |  99 -------------
 .../foo1/private/src/foo1_activator.c           |  88 ------------
 .../best_practice_example/foo2/CMakeLists.txt   |  39 ------
 .../foo2/private/include/foo2.h                 |  36 -----
 .../foo2/private/src/foo2.c                     | 109 ---------------
 .../foo2/private/src/foo2_activator.c           |  88 ------------
 .../dm_example_cxx/phase1/include/Phase1Cmp.h   |   2 -
 .../dm_example_cxx/phase1/src/BarActivator.cc   |  57 ++++++++
 .../phase2a/src/Phase2aActivator.cc             |   3 +-
 .../phase2b/src/Phase2bActivator.cc             |   3 +-
 examples/services_example_c/CMakeLists.txt      |  43 ++++++
 examples/services_example_c/api/example.h       |  34 +++++
 examples/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 ++++++++++
 examples/services_example_c/foo1/CMakeLists.txt |  39 ++++++
 .../foo1/private/include/foo1.h                 |  36 +++++
 .../services_example_c/foo1/private/src/foo1.c  |  99 +++++++++++++
 .../foo1/private/src/foo1_activator.c           |  88 ++++++++++++
 examples/services_example_c/foo2/CMakeLists.txt |  39 ++++++
 .../foo2/private/include/foo2.h                 |  36 +++++
 .../services_example_c/foo2/private/src/foo2.c  | 109 +++++++++++++++
 .../foo2/private/src/foo2_activator.c           |  88 ++++++++++++
 examples/services_example_cxx/CMakeLists.txt    |  46 ++++++
 .../services_example_cxx/api/IAnotherExample.h  |  33 +++++
 examples/services_example_cxx/api/example.h     |  43 ++++++
 .../services_example_cxx/bar/CMakeLists.txt     |  39 ++++++
 .../bar/private/include/Bar.h                   |  40 ++++++
 .../bar/private/include/BarActivator.h          |  36 +++++
 .../services_example_cxx/bar/private/src/Bar.cc |  48 +++++++
 .../bar/private/src/BarActivator.cc             |  49 +++++++
 .../services_example_cxx/baz/CMakeLists.txt     |  39 ++++++
 .../baz/private/include/Baz.h                   |  54 +++++++
 .../baz/private/include/BazActivator.h          |  34 +++++
 .../services_example_cxx/baz/private/src/Baz.cc |  84 +++++++++++
 .../baz/private/src/BazActivator.cc             |  45 ++++++
 .../services_example_cxx/foo/CMakeLists.txt     |  39 ++++++
 .../foo/private/include/Foo.h                   |  45 ++++++
 .../foo/private/include/FooActivator.h          |  34 +++++
 .../services_example_cxx/foo/private/src/Foo.cc |  60 ++++++++
 .../foo/private/src/FooActivator.cc             |  43 ++++++
 60 files changed, 1880 insertions(+), 849 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/Component.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/Component.h b/dependency_manager_cxx/include/celix/dm/Component.h
index 578714c..d323389 100644
--- a/dependency_manager_cxx/include/celix/dm/Component.h
+++ b/dependency_manager_cxx/include/celix/dm/Component.h
@@ -140,7 +140,7 @@ namespace celix { namespace dm {
          * @return the Service Dependency reference for chaining (fluent API)
          */
         template<class I>
-        ServiceDependency<T,I>& createServiceDependency();
+        ServiceDependency<T,I>& createServiceDependency(const std::string name = std::string{});
 
         /**
          Creates and adds a C++ service dependency to the component
@@ -156,7 +156,7 @@ namespace celix { namespace dm {
          * @return the DM Component reference for chaining (fluent API)
          */
         template<typename I>
-        CServiceDependency<T,I>& createCServiceDependency();
+        CServiceDependency<T,I>& createCServiceDependency(const std::string name);
 
         /**
          * Removes a C service dependency to the component

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/Component_Impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/Component_Impl.h b/dependency_manager_cxx/include/celix/dm/Component_Impl.h
index 07dbeea..d2fcf94 100644
--- a/dependency_manager_cxx/include/celix/dm/Component_Impl.h
+++ b/dependency_manager_cxx/include/celix/dm/Component_Impl.h
@@ -76,12 +76,12 @@ Component<T>& Component<T>::addCInterface(const void* svc, const std::string ser
 
 template<class T>
 template<class I>
-ServiceDependency<T,I>& Component<T>::createServiceDependency() {
+ServiceDependency<T,I>& Component<T>::createServiceDependency(const std::string name) {
 #ifdef __EXCEPTIONS
     auto dep = std::shared_ptr<ServiceDependency<T,I>> {new ServiceDependency<T,I>()};
 #else
-    static ServiceDependency<T,I> invalidDep{false};
-    auto dep = std::shared_ptr<ServiceDependency<T,I>> {new(std::nothrow) ServiceDependency<T,I>()};
+    static ServiceDependency<T,I> invalidDep{std::string{}, false};
+    auto dep = std::shared_ptr<ServiceDependency<T,I>> {new(std::nothrow) ServiceDependency<T,I>(name)};
     if (dep == nullptr) {
         return invalidDep;
     }
@@ -102,12 +102,12 @@ Component<T>& Component<T>::remove(ServiceDependency<T,I>& dep) {
 
 template<class T>
 template<typename I>
-CServiceDependency<T,I>& Component<T>::createCServiceDependency() {
+CServiceDependency<T,I>& Component<T>::createCServiceDependency(const std::string name) {
 #ifdef __EXCEPTIONS
     auto dep = std::shared_ptr<CServiceDependency<T,I>> {new CServiceDependency<T,I>()};
 #else
-    static CServiceDependency<T,I> invalidDep{false};
-    auto dep = std::shared_ptr<CServiceDependency<T,I>> {new(std::nothrow) CServiceDependency<T,I>()};
+    static CServiceDependency<T,I> invalidDep{std::string{}, false};
+    auto dep = std::shared_ptr<CServiceDependency<T,I>> {new(std::nothrow) CServiceDependency<T,I>(name)};
     if (dep == nullptr) {
         return invalidDep;
     }

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/DependencyManager.h b/dependency_manager_cxx/include/celix/dm/DependencyManager.h
index a9f11b9..1991c9d 100644
--- a/dependency_manager_cxx/include/celix/dm/DependencyManager.h
+++ b/dependency_manager_cxx/include/celix/dm/DependencyManager.h
@@ -54,8 +54,9 @@ namespace celix { namespace dm {
          */
         template<class T>
         Component<T>& createComponent(std::shared_ptr<T> inst = std::shared_ptr<T>{nullptr}) {
-            Component<T>* cmp = Component<T>::create(this->context);
+            Component<T>* cmp = Component<T>::create(this->context);;
             if (cmp->isValid()) {
+                cmp->setInstance(inst);
                 this->components.push_back(std::unique_ptr<BaseComponent> {cmp});
             }
             return *cmp;

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/ServiceDependency.h b/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
index b42ef76..2d19200 100644
--- a/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
+++ b/dependency_manager_cxx/include/celix/dm/ServiceDependency.h
@@ -101,18 +101,24 @@ namespace celix { namespace dm {
 
         void setupService();
     public:
-        CServiceDependency(bool valid = true) : TypedServiceDependency<T>(valid) {};
+        CServiceDependency(const std::string name, bool valid = true);
         virtual ~CServiceDependency() = default;
 
         /**
-         * Sets the service name, version and filter for the C service dependency.
+         * Sets the service version range for the C service dependency.
          *
-         * @param serviceName The service name. Must have a value
          * @param serviceVersionRange The service version range, can be an empty string
+         * @return the C service dependency reference for chaining (fluent API)
+         */
+        CServiceDependency<T,I>& setVersionRange(const std::string serviceVersionRange);
+
+        /**
+         * Sets the service filter for the C service dependency.
+         *
          * @param filter The (additional) filter to use (e.g. "(location=front)")
          * @return the C service dependency reference for chaining (fluent API)
          */
-        CServiceDependency<T,I>& setCService(const std::string serviceName, const std::string serviceVersionRange = std::string{}, const std::string filter = std::string{});
+        CServiceDependency<T,I>& setFilter(const std::string filter);
 
         /**
          * Specify if the service dependency is required. Default is false
@@ -189,7 +195,7 @@ namespace celix { namespace dm {
         int invokeCallback(void(T::*fp)(I*), const void* service);
         int invokeCallbackWithProperties(void(T::*fp)(I*, Properties&&), service_reference_pt  ref, const void* service);
     public:
-        ServiceDependency(bool valid = true);
+        ServiceDependency(const std::string name = std::string{}, bool valid = true);
         virtual ~ServiceDependency() = default;
 
         /**
@@ -197,21 +203,21 @@ namespace celix { namespace dm {
          *
          * @return the C++ service dependency reference for chaining (fluent API)
          */
-        ServiceDependency<T,I>& setName(std::string name);
+        ServiceDependency<T,I>& setName(const std::string name);
 
         /**
          * Set the service filter of the service dependency.
          *
          * @return the C++ service dependency reference for chaining (fluent API)
          */
-        ServiceDependency<T,I>& setFilter(std::string filter);
+        ServiceDependency<T,I>& setFilter(const std::string filter);
 
         /**
          * Set the service version range of the service dependency.
          *
          * @return the C++ service dependency reference for chaining (fluent API)
          */
-        ServiceDependency<T,I>& setVersion(std::string versionRange);
+        ServiceDependency<T,I>& setVersionRange(const std::string versionRange);
 
         /**
          * Set the set callback for when the service dependency becomes available

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h b/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
index 13055b6..2bc788d 100644
--- a/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
+++ b/dependency_manager_cxx/include/celix/dm/ServiceDependency_Impl.h
@@ -24,9 +24,20 @@
 using namespace celix::dm;
 
 template<class T, typename I>
-CServiceDependency<T,I>& CServiceDependency<T,I>::setCService(const std::string serviceName, const std::string serviceVersionRange, const std::string filter) {
-    this->name = serviceName;
+CServiceDependency<T,I>::CServiceDependency(const std::string name, bool valid) : TypedServiceDependency<T>(valid) {
+    this->name = name;
+    this->setupService();
+}
+
+template<class T, typename I>
+CServiceDependency<T,I>& CServiceDependency<T,I>::setVersionRange(const std::string serviceVersionRange) {
     this->versionRange = serviceVersionRange;
+    this->setupService();
+    return *this;
+}
+
+template<class T, typename I>
+CServiceDependency<T,I>& CServiceDependency<T,I>::setFilter(const std::string filter) {
     this->filter = filter;
     this->setupService();
     return *this;
@@ -201,8 +212,12 @@ int CServiceDependency<T,I>::invokeCallbackWithProperties(void(T::*fp)(const I*,
 }
 
 template<class T, class I>
-ServiceDependency<T,I>::ServiceDependency(bool valid) : TypedServiceDependency<T>(valid) {
-    setupService();
+ServiceDependency<T,I>::ServiceDependency(std::string name, bool valid) : TypedServiceDependency<T>(valid) {
+    if (!name.empty()) {
+        this->setName(name);
+    } else {
+        this->setupService();
+    }
 };
 
 template<class T, class I>
@@ -273,7 +288,7 @@ ServiceDependency<T,I>& ServiceDependency<T,I>::setFilter(std::string filter) {
 };
 
 template<class T, class I>
-ServiceDependency<T,I>& ServiceDependency<T,I>::setVersion(std::string versionRange) {
+ServiceDependency<T,I>& ServiceDependency<T,I>::setVersionRange(std::string versionRange) {
     this->versionRange = versionRange;
     setupService();
     return *this;

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/dependency_manager_cxx/include/celix/dm/types.h
----------------------------------------------------------------------
diff --git a/dependency_manager_cxx/include/celix/dm/types.h b/dependency_manager_cxx/include/celix/dm/types.h
index 9971de7..e1f33d9 100644
--- a/dependency_manager_cxx/include/celix/dm/types.h
+++ b/dependency_manager_cxx/include/celix/dm/types.h
@@ -71,7 +71,7 @@ namespace celix { namespace dm {
         while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ';') {
             epos += 1;
         }
-        size_t len = epos - bpos - 1;
+        size_t len = epos - bpos;
         result = result.substr(bpos, len);
 #endif
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/documents/getting_started/using_services_with_c.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/using_services_with_c.md b/documents/getting_started/using_services_with_c.md
index 5dd6ce9..2d7d820 100644
--- a/documents/getting_started/using_services_with_c.md
+++ b/documents/getting_started/using_services_with_c.md
@@ -6,7 +6,7 @@ This example gives an overview for providing and using services with Apache Celi
 
 ## Services
 
-To start-of, C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs.
+To start of, C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs. 
 
 By convention use the following service layout:
 
@@ -55,7 +55,7 @@ because it is not possible to create the const pointer of those typedefs and it
 For versioning, semantic versioning should be used.
 
 A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
-For a C Service change that are incompatible are:
+For a C Service versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
 
 - Removing a function
 - Adding a function to before any other function
@@ -63,17 +63,20 @@ For a C Service change that are incompatible are:
 - Changing the signature of a function
 - Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
 
-A backwards compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
+A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
 Changes considered backwards compatible which extend the functionality are:
 
 - Adding a function to the back of the service struct
 
-A backwards compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
-Changes considered backwards compatible which does not extend the functionaility are:
+A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
+Changes considered backwards binary compatible which does not extend the functionality are:
 
 - Changes in the documentation
 - Renaming of arguments
 
+For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
+ but not advisable
+
  
 ## Components
 
@@ -89,8 +92,8 @@ The init/deinit function can be used to include (de)initialization which is not
 
 ## Code Examples
 
-The next code block contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
-The complete example can be found [here](../../examples/best_practice_example).
+The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
+The complete example can be found [here](../../examples/services_example_c).
 
 The error checking is very minimal in these example to keep the focus on how to interact with services and how to deal with errors in C / Celix.
 
@@ -585,3 +588,6 @@ The suspend or non-locking strategy `DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND` (de
 
 The suspend strategy has the advantage of reducing locks' usage: of course, suspending the component has its own overhead (e.g. stopping and restarting threads), but this overhead is "paid" only in case of changes in service dependencies, while the locking overhead is always paid.
 
+## See also
+
+See the [Dependency Manager example](../../examples/dm_example) for a working example and good starting point to create more complex bundles.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/documents/getting_started/using_services_with_cxx.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/using_services_with_cxx.md b/documents/getting_started/using_services_with_cxx.md
new file mode 100644
index 0000000..8b7a5a4
--- /dev/null
+++ b/documents/getting_started/using_services_with_cxx.md
@@ -0,0 +1,140 @@
+#Apache Celix - Using Services with C
+
+## Intro 
+
+This example gives an overview for providing and using C and C++ services with Apache Celix with C++.
+
+## Services
+
+### C++ Services
+TO start of, C++ service in Celix are just (abstract) classes. 
+
+In the following example there also a projected default constructor to ensure no instantiation of the service is possible:
+```C++
+//IAnotherExample.h
+#ifndef ANOTHER_EXAMPLE_H
+#define ANOTHER_EXAMPLE_H
+
+#define ANOTHER_EXAMPLE_VERSION "1.0.0"
+#define ANOTHER_EXAMPLE_VERSION "1.0.0"
+#define ANOTHER_EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)"
+
+class IAnotherExample {
+protected:
+    IAnotherExample() = default;
+public:
+    virtual void method() = 0;
+};
+
+#endif //ANOTHER_EXAMPLE_H
+```
+
+For a Celix service a service name, service provider version and service consumer range should be declared.
+This is explicitly done with macros to prevent symbols so to that no linking dependencies are introduced. 
+For C++ the service name can be inferred. 
+
+### C Services
+C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs.
+
+By convention use the following service layout:
+```C
+//example.h
+#ifndef EXAMPLE_H_
+#define EXAMPLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXAMPLE_H_ */
+
+```
+
+For C service a struct containing the function pointers needs to be declared.
+The first element of the service struct should be a handle which can be used to store the service context, as convention we keep this pointer a void pointer to explicitly make it opaque.
+Note that also an opaque struct could be used (e.g a declared but not defined struct), but this can become problematic concerning components registering multiple services. 
+In that case explicit cast are needed to prevent warning and this can be confusing for the To prevent that issues void pointers are preferred.
+
+The rest of the element should be function pointers, which by convention should return an celix_status_t or int (which is technically the same). 
+The return value is used as a way of handling errors and is also needed to be able to make remote services (e.g. to be able to handle remote exceptions).
+
+The first argument of a service function should be the service handle and if there is a result the last argument should be a output parameter (either pre allocated (e.g. double *) or not (e.g. double **)).
+If the caller is not the owner of the output argument, a const pointer should be used (e.g. const char**). 
+It is also possible to create typedef of the pointer to the service struct (e.g. typedef struct example_struct example_t), but this is not needed. 
+
+In the Celix code base there are still service which uses a typedef with a pointer (e.g. typedef struct example_struct* example_struct_pt). This should be avoided, 
+because it is not possible to create the const pointer of those typedefs and it is not possible to include those typedef inside a existing struct without the needed for an additional malloc.
+
+
+
+### Semantic Versioning
+For versioning, semantic versioning should be used.
+
+A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
+
+### Versioning C++ Services
+For C++ Services versioning is used ot express binary compatibility changes that are incompatible are:
+
+- Everything. Seriously, binary compatibility in C++ is difficult and should be avoided. 
+
+Note that is is possible to use versioning for source compatibility and setup the build environment accordingly, but this is not part of this guide.
+
+### Versioning C Services
+For C Services versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
+
+- Removing a function
+- Adding a function to before any other function
+- Moving a function to an other location in the service struct
+- Changing the signature of a function
+- Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
+
+A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
+Changes considered backwards compatible which extend the functionality are:
+
+- Adding a function to the back of the service struct
+
+A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
+Changes considered backwards binary compatible which does not extend the functionality are:
+
+- Changes in the documentation
+- Renaming of arguments
+
+For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
+ but not advisable
+
+ 
+## Components
+
+Component are concrete classes in C++. This do not have to implement specific interface, expect the C++ service interfaces they provide.
+
+## Code Examples
+
+The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
+The complete example can be found [here](../../examples/services_example_cxx).
+
+### Bar example
+
+The bar example is a simple component providing the C `example` service and C++ `IAnotherExample` service. 
+
+
+TODO
+
+## See also
+
+See the [C++ Dependency Manager example](../../examples/dm_example_cxx) for a working example and good starting point to create more complex bundles.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 04f2bd4..0e3f87e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -19,7 +19,8 @@ if (EXAMPLES)
     add_subdirectory(hello_world)
     add_subdirectory(hello_world_test)
 
-    add_subdirectory(best_practice_example)
+    add_subdirectory(services_example_c)
+    add_subdirectory(services_example_cxx)
 
     if (NOT ANDROID)
     	add_subdirectory(mongoose)

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/best_practice_example/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/CMakeLists.txt b/examples/best_practice_example/CMakeLists.txt
deleted file mode 100644
index 1b94159..0000000
--- a/examples/best_practice_example/CMakeLists.txt
+++ /dev/null
@@ -1,42 +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.
-if (BUILD_DEPENDENCY_MANAGER)
-
-    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_deploy(best-practice-example
-        COPY
-        BUNDLES
-            shell
-            shell_tui
-            dm_shell
-            bar
-            foo1
-            foo2
-        PROPERTIES
-            example=value
-    )
-
-endif ()

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/best_practice_example/README.md
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/README.md b/examples/best_practice_example/README.md
deleted file mode 100644
index 3f678b6..0000000
--- a/examples/best_practice_example/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Best Practice Example
-
-For more information about this example see [Best Practices](../../documents/best_practices/README.md)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/best_practice_example/api/example.h
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/api/example.h b/examples/best_practice_example/api/example.h
deleted file mode 100644
index b0e0166..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/bar/CMakeLists.txt b/examples/best_practice_example/bar/CMakeLists.txt
deleted file mode 100644
index 7ebb45c..0000000
--- a/examples/best_practice_example/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_bundle(bar
-    SYMBOLIC_NAME bar
-    VERSION 1.0.0
-    SOURCES
-        private/src/bar_activator
-        private/src/bar.c
-)
-
-IF(APPLE)
-    target_link_libraries(bar celix_framework -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(bar -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
-    else()
-        target_link_libraries(bar -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/1b25a0a8/examples/best_practice_example/bar/private/include/bar.h
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/bar/private/include/bar.h b/examples/best_practice_example/bar/private/include/bar.h
deleted file mode 100644
index 5e1da8b..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/bar/private/src/bar.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/bar/private/src/bar.c b/examples/best_practice_example/bar/private/src/bar.c
deleted file mode 100644
index 5099201..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/bar/private/src/bar_activator.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/bar/private/src/bar_activator.c b/examples/best_practice_example/bar/private/src/bar_activator.c
deleted file mode 100644
index 0fa7889..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/foo1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo1/CMakeLists.txt b/examples/best_practice_example/foo1/CMakeLists.txt
deleted file mode 100644
index 0d1b93c..0000000
--- a/examples/best_practice_example/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_bundle(foo1
-    SYMBOLIC_NAME foo1
-    VERSION 1.0.0
-    SOURCES
-        private/src/foo1_activator
-        private/src/foo1.c
-)
-
-IF(APPLE)
-    target_link_libraries(foo1 celix_framework -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(foo1 -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
-    else()
-        target_link_libraries(foo1 -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/1b25a0a8/examples/best_practice_example/foo1/private/include/foo1.h
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo1/private/include/foo1.h b/examples/best_practice_example/foo1/private/include/foo1.h
deleted file mode 100644
index f556b44..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/foo1/private/src/foo1.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo1/private/src/foo1.c b/examples/best_practice_example/foo1/private/src/foo1.c
deleted file mode 100644
index ba8ce19..0000000
--- a/examples/best_practice_example/foo1/private/src/foo1.c
+++ /dev/null
@@ -1,99 +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) {
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo1_thread, self);
-    return OK;
-}
-
-int foo1_stop(foo1_t *self) {
-    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) {
-    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(10000000);
-    }
-    return NULL;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/best_practice_example/foo1/private/src/foo1_activator.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo1/private/src/foo1_activator.c b/examples/best_practice_example/foo1/private/src/foo1_activator.c
deleted file mode 100644
index f94888b..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/foo2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo2/CMakeLists.txt b/examples/best_practice_example/foo2/CMakeLists.txt
deleted file mode 100644
index 1096c6c..0000000
--- a/examples/best_practice_example/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_bundle(foo2
-    SYMBOLIC_NAME foo2
-    VERSION 1.0.0
-    SOURCES
-        private/src/foo2_activator
-        private/src/foo2.c
-)
-
-IF(APPLE)
-    target_link_libraries(foo2 celix_framework -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(foo2 -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
-    else()
-        target_link_libraries(foo2 -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/1b25a0a8/examples/best_practice_example/foo2/private/include/foo2.h
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo2/private/include/foo2.h b/examples/best_practice_example/foo2/private/include/foo2.h
deleted file mode 100644
index 9f09276..0000000
--- a/examples/best_practice_example/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/1b25a0a8/examples/best_practice_example/foo2/private/src/foo2.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo2/private/src/foo2.c b/examples/best_practice_example/foo2/private/src/foo2.c
deleted file mode 100644
index 932d42d..0000000
--- a/examples/best_practice_example/foo2/private/src/foo2.c
+++ /dev/null
@@ -1,109 +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) {
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo2_thread, self);
-    return OK;
-}
-
-int foo2_stop(foo2_t *self) {
-    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;
-    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;
-    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(10000000);
-    }
-    return NULL;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/best_practice_example/foo2/private/src/foo2_activator.c
----------------------------------------------------------------------
diff --git a/examples/best_practice_example/foo2/private/src/foo2_activator.c b/examples/best_practice_example/foo2/private/src/foo2_activator.c
deleted file mode 100644
index 0f61e9a..0000000
--- a/examples/best_practice_example/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, foo2_removeExample, 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;
-	foo2_destroy(activator->foo);
-	free(activator);
-	return status;
-};
-

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/dm_example_cxx/phase1/include/Phase1Cmp.h
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase1/include/Phase1Cmp.h b/examples/dm_example_cxx/phase1/include/Phase1Cmp.h
index 4a4662d..4401be0 100644
--- a/examples/dm_example_cxx/phase1/include/Phase1Cmp.h
+++ b/examples/dm_example_cxx/phase1/include/Phase1Cmp.h
@@ -24,8 +24,6 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#define IPHASE1_VERSION "1.0.0"
-
 class Phase1Cmp : public IPhase1 {
     uint32_t counter = 0;
 public:

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/dm_example_cxx/phase1/src/BarActivator.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase1/src/BarActivator.cc b/examples/dm_example_cxx/phase1/src/BarActivator.cc
new file mode 100644
index 0000000..2f84d8e
--- /dev/null
+++ b/examples/dm_example_cxx/phase1/src/BarActivator.cc
@@ -0,0 +1,57 @@
+/**
+ * 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 "Phase1Cmp.h"
+#include "Phase1Activator.h"
+
+using namespace celix::dm;
+
+/* This example create a C++ component providing a C++ and C service
+ * For the C service a service struct in initialized and registered
+ * For the C++ service the object itself is used
+ */
+
+DmActivator* DmActivator::create(DependencyManager& mng) {
+    return new Phase1Activator(mng);
+}
+
+void Phase1Activator::init() {
+    std::shared_ptr<Phase1Cmp> cmp {new Phase1Cmp()};
+
+    Properties cmdProps;
+    cmdProps[OSGI_SHELL_COMMAND_NAME] = "phase1_info";
+    cmdProps[OSGI_SHELL_COMMAND_USAGE] = "phase1_info";
+    cmdProps[OSGI_SHELL_COMMAND_DESCRIPTION] = "Print information about the Phase1Cmp";
+
+
+    cmd.handle = cmp.get();
+    cmd.executeCommand = [](void *handle, char* line, FILE* out, FILE *err) {
+        Phase1Cmp* cmp = (Phase1Cmp*)handle;
+        return cmp->infoCmd(line, out, err);
+    };
+
+    createComponent(cmp)  //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
+        .addInterface<IPhase1>(IPHASE1_VERSION)
+        .addCInterface(&cmd, OSGI_SHELL_COMMAND_SERVICE_NAME, "", cmdProps)
+        .setCallbacks(&Phase1Cmp::init, &Phase1Cmp::start, &Phase1Cmp::stop, &Phase1Cmp::deinit);
+}
+
+void Phase1Activator::deinit() {
+    //nothing to do
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc b/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
index 8a640ec..fdb8236 100644
--- a/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
+++ b/examples/dm_example_cxx/phase2a/src/Phase2aActivator.cc
@@ -42,9 +42,8 @@ void Phase2Activator::init() {
             .setRequired(true)
             .setCallbacks(&Phase2Cmp::setPhase1);
 
-    cmp.createCServiceDependency<log_service_t>()
+    cmp.createCServiceDependency<log_service_t>(OSGI_LOGSERVICE_NAME)
             .setRequired(false)
-            .setCService(OSGI_LOGSERVICE_NAME, {}, {})
             .setCallbacks(&Phase2Cmp::setLogService);
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
----------------------------------------------------------------------
diff --git a/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc b/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
index 101e813..1aae052 100644
--- a/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
+++ b/examples/dm_example_cxx/phase2b/src/Phase2bActivator.cc
@@ -40,9 +40,8 @@ void Phase2Activator::init() {
             .setRequired(true)
             .setCallbacks(&Phase2Cmp::setPhase1);
 
-    cmp.createCServiceDependency<log_service_t>()
+    cmp.createCServiceDependency<log_service_t>(OSGI_LOGSERVICE_NAME)
             .setRequired(false)
-            .setCService(OSGI_LOGSERVICE_NAME)
             .setCallbacks(&Phase2Cmp::setLogService);
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/services_example_c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/CMakeLists.txt b/examples/services_example_c/CMakeLists.txt
new file mode 100644
index 0000000..f6a5066
--- /dev/null
+++ b/examples/services_example_c/CMakeLists.txt
@@ -0,0 +1,43 @@
+# 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.
+if (BUILD_DEPENDENCY_MANAGER)
+
+    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_deploy(services_example_c
+        GROUP services_example
+        COPY
+        BUNDLES
+            shell
+            shell_tui
+            dm_shell
+            bar
+            foo1
+            foo2
+        PROPERTIES
+            example=value
+    )
+
+endif ()

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/services_example_c/api/example.h
----------------------------------------------------------------------
diff --git a/examples/services_example_c/api/example.h b/examples/services_example_c/api/example.h
new file mode 100644
index 0000000..b0e0166
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/CMakeLists.txt b/examples/services_example_c/bar/CMakeLists.txt
new file mode 100644
index 0000000..7ebb45c
--- /dev/null
+++ b/examples/services_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_bundle(bar
+    SYMBOLIC_NAME bar
+    VERSION 1.0.0
+    SOURCES
+        private/src/bar_activator
+        private/src/bar.c
+)
+
+IF(APPLE)
+    target_link_libraries(bar celix_framework -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(bar -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
+    else()
+        target_link_libraries(bar -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/1b25a0a8/examples/services_example_c/bar/private/include/bar.h
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/private/include/bar.h b/examples/services_example_c/bar/private/include/bar.h
new file mode 100644
index 0000000..5e1da8b
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/bar/private/src/bar.c
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/private/src/bar.c b/examples/services_example_c/bar/private/src/bar.c
new file mode 100644
index 0000000..5099201
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/bar/private/src/bar_activator.c
----------------------------------------------------------------------
diff --git a/examples/services_example_c/bar/private/src/bar_activator.c b/examples/services_example_c/bar/private/src/bar_activator.c
new file mode 100644
index 0000000..0fa7889
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/foo1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo1/CMakeLists.txt b/examples/services_example_c/foo1/CMakeLists.txt
new file mode 100644
index 0000000..0d1b93c
--- /dev/null
+++ b/examples/services_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_bundle(foo1
+    SYMBOLIC_NAME foo1
+    VERSION 1.0.0
+    SOURCES
+        private/src/foo1_activator
+        private/src/foo1.c
+)
+
+IF(APPLE)
+    target_link_libraries(foo1 celix_framework -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(foo1 -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
+    else()
+        target_link_libraries(foo1 -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/1b25a0a8/examples/services_example_c/foo1/private/include/foo1.h
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo1/private/include/foo1.h b/examples/services_example_c/foo1/private/include/foo1.h
new file mode 100644
index 0000000..f556b44
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/foo1/private/src/foo1.c
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo1/private/src/foo1.c b/examples/services_example_c/foo1/private/src/foo1.c
new file mode 100644
index 0000000..ba8ce19
--- /dev/null
+++ b/examples/services_example_c/foo1/private/src/foo1.c
@@ -0,0 +1,99 @@
+/**
+ *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) {
+    self->running = true;
+    pthread_create(&self->thread, NULL, foo1_thread, self);
+    return OK;
+}
+
+int foo1_stop(foo1_t *self) {
+    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) {
+    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(10000000);
+    }
+    return NULL;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/1b25a0a8/examples/services_example_c/foo1/private/src/foo1_activator.c
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo1/private/src/foo1_activator.c b/examples/services_example_c/foo1/private/src/foo1_activator.c
new file mode 100644
index 0000000..f94888b
--- /dev/null
+++ b/examples/services_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/1b25a0a8/examples/services_example_c/foo2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo2/CMakeLists.txt b/examples/services_example_c/foo2/CMakeLists.txt
new file mode 100644
index 0000000..1096c6c
--- /dev/null
+++ b/examples/services_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_bundle(foo2
+    SYMBOLIC_NAME foo2
+    VERSION 1.0.0
+    SOURCES
+        private/src/foo2_activator
+        private/src/foo2.c
+)
+
+IF(APPLE)
+    target_link_libraries(foo2 celix_framework -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(foo2 -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive celix_framework)
+    else()
+        target_link_libraries(foo2 -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/1b25a0a8/examples/services_example_c/foo2/private/include/foo2.h
----------------------------------------------------------------------
diff --git a/examples/services_example_c/foo2/private/include/foo2.h b/examples/services_example_c/foo2/private/include/foo2.h
new file mode 100644
index 0000000..9f09276
--- /dev/null
+++ b/examples/services_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


Mime
View raw message