celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject celix git commit: CELIX-452: Improves the service listener locking. The retain/release on service listener now first check if service listener matches
Date Tue, 17 Jul 2018 10:08:42 GMT
Repository: celix
Updated Branches:
  refs/heads/develop d85590363 -> 02ee6c4e5


CELIX-452: Improves the service listener locking. The retain/release on service listener now
first check if service listener matches


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

Branch: refs/heads/develop
Commit: 02ee6c4e5abd06a6756e33f79db45ab5e50f2e7a
Parents: d855903
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Tue Jul 17 12:06:40 2018 +0200
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Tue Jul 17 12:06:40 2018 +0200

----------------------------------------------------------------------
 cmake/cmake_celix/ContainerPackaging.cmake |  23 ++--
 cmake/cmake_celix/OCIPacking.cmake         | 156 ++++++++++++++++++++++++
 cmake/cmake_celix/runtime_common.sh.in     |   2 -
 libs/framework/src/bundle_cache.c          |   3 +
 libs/framework/src/framework.c             | 107 ++++++++--------
 5 files changed, 224 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/02ee6c4e/cmake/cmake_celix/ContainerPackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/ContainerPackaging.cmake b/cmake/cmake_celix/ContainerPackaging.cmake
index b39cdae..e9452fb 100644
--- a/cmake/cmake_celix/ContainerPackaging.cmake
+++ b/cmake/cmake_celix/ContainerPackaging.cmake
@@ -273,21 +273,24 @@ function(celix_container_bundles_dir)
                         COMMENT "Copying (imported) bundle '${BUNDLE}' to '${CONTAINER_LOC}/${BD_DIR_NAME}'"
                     )
                     set(HANDLED TRUE)
+	         else() #Assuming a bundle target (library or add_custom_target)
+			string(MAKE_C_IDENTIFIER ${BUNDLE} BUNDLE_ID) #Create id with no special chars (e.g. for
target like Celix::shell)
+			set(OUT "${CMAKE_BINARY_DIR}/celix/gen/containers/${CONTAINER_TARGET}/copy-bundle-for-target-${BUNDLE_ID}.timestamp")
+			set(DEST "${CONTAINER_LOC}/${BD_DIR_NAME}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
+			add_custom_command(OUTPUT ${OUT}
+				COMMAND ${CMAKE_COMMAND} -E touch ${OUT}
+				COMMAND ${CMAKE_COMMAND} -E make_directory ${CONTAINER_LOC}/${BD_DIR_NAME}
+				COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILE>"
${DEST}
+				COMMENT "Copying (target) bundle '${BUNDLE}' to '${CONTAINER_LOC}/${BD_DIR_NAME}'"
+				DEPENDS ${BUNDLE} $<TARGET_PROPERTY:${BUNDLE},BUNDLE_CREATE_BUNDLE_TARGET>
+				)
+                    set(HANDLED TRUE)
                 endif ()
             endif ()
         endif ()
 
         if (NOT HANDLED) #not a imported bundle target so (assuming) a future bundle target
-            string(MAKE_C_IDENTIFIER ${BUNDLE} BUNDLE_ID) #Create id with no special chars
(e.g. for target like Celix::shell)
-            set(OUT "${CMAKE_BINARY_DIR}/celix/gen/containers/${CONTAINER_TARGET}/copy-bundle-for-target-${BUNDLE_ID}.timestamp")
-            set(DEST "${CONTAINER_LOC}/${BD_DIR_NAME}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
-            add_custom_command(OUTPUT ${OUT}
-                COMMAND ${CMAKE_COMMAND} -E touch ${OUT}
-                COMMAND ${CMAKE_COMMAND} -E make_directory ${CONTAINER_LOC}/${BD_DIR_NAME}
-                COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILE>"
${DEST}
-                COMMENT "Copying (target) bundle '${BUNDLE}' to '${CONTAINER_LOC}/${BD_DIR_NAME}'"
-                DEPENDS ${BUNDLE} $<TARGET_PROPERTY:${BUNDLE},BUNDLE_CREATE_BUNDLE_TARGET>
-            )
+		message(FATAL_ERROR "Cannot add bundle in container ${CONTAINER_TARGET}. Provided bundle
is not a abs path to an existing file nor a cmake target (${BUNDLE}).")
         endif()
         list(APPEND DEPS "${OUT}")
     endforeach()

http://git-wip-us.apache.org/repos/asf/celix/blob/02ee6c4e/cmake/cmake_celix/OCIPacking.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/OCIPacking.cmake b/cmake/cmake_celix/OCIPacking.cmake
new file mode 100644
index 0000000..e67a6fa
--- /dev/null
+++ b/cmake/cmake_celix/OCIPacking.cmake
@@ -0,0 +1,156 @@
+# 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.
+
+##### setup bundles/container target
+if (NOT TARGET celix-oci-bundles)
+    add_custom_target(celix-oci-application-bundles ALL
+            DEPENDS $<TARGET_PROPERTY:celix-oci-bundles,OCI_APPLICATION_BUNDLES>
+    )
+    set_target_properties(celix-oci-application-bundles PROPERTIES "OCI_APPLICATION_BUNDLES"
"") #initial empty deps list
+if (NOT TARGET celix-containers)
+	add_custom_target(celix-containers ALL
+		DEPENDS $<TARGET_PROPERTY:celix-containers,CONTAINER_DEPLOYMENTS>
+	)
+	set_target_properties(celix-containers PROPERTIES "CONTAINER_DEPLOYMENTS" "") #initial empty
deps list
+endif ()
+
+
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_TARGET_DEPS" "") #target
deps for the container.
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_0" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_1" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_2" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_3" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_4" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_BUNDLES_LEVEL_5" "")
#bundles to deploy for the container for run level 0
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_COPY_BUNDLES" ${CONTAINER_COPY})
#copy bundles in bundle dir or link using abs paths. NOTE this cannot be changed after a add_deploy
command
+
+    #deploy specific
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_NAME" "${CONTAINER_NAME}")
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_GROUP" "${CONTAINER_GROUP}")
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_LOC" "${CONTAINER_LOC}")
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_PROPERTIES" "")
+    #set_target_properties(${CONTAINER_TARGET} PROPERTIES "CONTAINER_EMBEDDED_PROPERTIES"
"")
+    #####
+
+
+#Creates a OCI runtime bundle from a celix containers.
+#TODO align with add_celix_docker, make it possible to "inherit" from add_celix_container
+function (add_celix_oci_bundle_dir)
+        set(OPTIONS )
+        set(ONE_VAL_ARGS CELIX_CONTAINER OCI_NAME EXPORT)
+        set(MULTI_VAL_ARGS )
+        cmake_parse_arguments(OCI "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
+
+        if (NOT TARGET ${OCI_CELIX_CONTAINER})
+            message(FATAL_ERROR "Cannot create a OCI container from '${OCI_CELIX_CONTAINER}';
Specify a valid Celix container target with the CELIX_CONTAINER arguments")
+        endif ()
+
+        set(TARGET ${OCI_CELIX_CONTAINER}-oci-container)
+
+        add_custom_target(${TARGET} ALL)
+        get_target_property(DEPS celix-oci-application-bundles PROPERTY "OCI_APPLICATION_BUNDLES"
)
+        list(APPEND DEPS ${TARGET})
+        set_target_properties(celix-oci-application-bundles PROPERTIES "OCI_APPLICATION_BUNDLES"
"${DEPS}")
+
+
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_0>
LEVEL 0)
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_1>
LEVEL 1)
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_2>
LEVEL 2)
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_3>
LEVEL 3)
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_4>
LEVEL 4)
+        celix_oci_container_add_bundles(${OCI_CELIX_CONTAINER} $<TARGET_PROPERTY:${OCI_CELIX_CONTAINER},CONTAINER_BUNDLES_LEVEL_5>
LEVEL 5)
+endfunction ()
+
+#TODO combine with docker
+function (celix_oci_container_bundles)
+    #0 is docker TARGET
+    #1..n is bundles
+    list(GET ARGN 0 CONTAINER_TARGET)
+    list(REMOVE_AT ARGN 0)
+    set(TARGET ${CONTAINER_TARGET}-oci-container)
+
+    set(OPTIONS )
+    set(ONE_VAL_ARGS LEVEL)
+    set(MULTI_VAL_ARGS )
+    cmake_parse_arguments(BUNDLES "${OPTIONS}" "${ONE_VAL_ARGS}" "${MULTI_VAL_ARGS}" ${ARGN})
+    set(BUNDLES_LIST ${BUNDLES_UNPARSED_ARGUMENTS})
+
+    if (NOT BUNDLES_LEVEL)
+        set(BUNDLES_LEVEL 1)
+    endif ()
+
+    get_target_property(BUNDLES ${TARGET} "BUNDLES_LEVEL_${BUNDLES_LEVEL}")
+    get_target_property(BUNDLES_DIR ${TARGET} "BUNDLES_DIR")
+    get_target_property(LOC ${TARGET} "LOC")
+    get_target_property(DEPS ${TARGET} "DEPS")
+
+    foreach(BUNDLE IN ITEMS ${BUNDLES_LIST})
+        set(HANDLED FALSE)
+        if(IS_ABSOLUTE ${BUNDLE} AND EXISTS ${BUNDLE})
+            get_filename_component(BUNDLE_FILENAME ${BUNDLE} NAME)
+            set(OUT "${LOC}/${BUNDLES_DIR}/${BUNDLE_FILENAME}")
+            add_custom_command(OUTPUT ${OUT}
+                    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${BUNDLE} ${OUT}
+                    COMMENT "Copying (file) bundle '${BUNDLE}' to '${LOC}/${BUNDLES_DIR}'"
+                    DEPENDS ${BUNDLE}
+                    )
+            list(APPEND BUNDLES "${BUNDLES_DIR}/${BUNDLE_FILENAME}")
+            set(HANDLED TRUE)
+        elseif (TARGET ${BUNDLE})
+            get_target_property(TARGET_TYPE ${BUNDLE} TYPE)
+            if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
+                #ignore
+                set(HANDLED TRUE)
+            else ()
+                get_target_property(IMP ${BUNDLE} BUNDLE_IMPORTED)
+                if (IMP) #An imported bundle target -> handle target without DEPENDS
+                    string(MAKE_C_IDENTIFIER ${BUNDLE} BUNDLE_ID) #Create id with no special
chars (e.g. for target like Celix::shell)
+                    set(OUT "${CMAKE_BINARY_DIR}/celix/gen/docker/${DOCKER_TARGET}/copy-bundle-for-target-${BUNDLE_ID}.timestamp")
+                    set(DEST "${LOC}/${BUNDLES_DIR}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
+                    add_custom_command(OUTPUT ${OUT}
+                            COMMAND ${CMAKE_COMMAND} -E touch ${OUT}
+                            COMMAND ${CMAKE_COMMAND} -E make_directory ${LOC}/${BUNDLES_DIR}
+                            COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILE>"
${DEST}
+                            COMMENT "Copying (imported) bundle '${BUNDLE}' to '${LOC}/${BUNDLES_DIR}'"
+                            )
+                    list(APPEND BUNDLES "${BUNDLES_DIR}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
+                    set(HANDLED TRUE)
+                endif ()
+            endif ()
+        endif ()
+
+        if(NOT HANDLED) #assuming (future) bundle target
+            string(MAKE_C_IDENTIFIER ${BUNDLE} BUNDLE_ID) #Create id with no special chars
(e.g. for target like Celix::shell)
+            set(OUT "${CMAKE_BINARY_DIR}/celix/gen/docker/${DOCKER_TARGET}/copy-bundle-for-target-${BUNDLE_ID}.timestamp")
+            set(DEST "${LOC}/${BUNDLES_DIR}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
+            add_custom_command(OUTPUT ${OUT}
+                    COMMAND ${CMAKE_COMMAND} -E touch ${OUT}
+                    COMMAND ${CMAKE_COMMAND} -E make_directory ${LOC}/${BUNDLES_DIR}
+                    COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILE>"
${DEST}
+                    COMMENT "Copying (target) bundle '${BUNDLE}' to '${LOC}/${BUNDLES_DIR}'"
+                    DEPENDS ${BUNDLE} $<TARGET_PROPERTY:${BUNDLE},BUNDLE_CREATE_BUNDLE_TARGET>
+                    )
+            list(APPEND BUNDLES "${BUNDLES_DIR}/$<TARGET_PROPERTY:${BUNDLE},BUNDLE_FILENAME>")
+        endif()
+        list(APPEND DEPS "${OUT}")
+    endforeach()
+
+    set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_BUNDLES_LEVEL_${BUNDLES_LEVEL}"
"${BUNDLES}")
+    set_target_properties(${DOCKER_TARGET} PROPERTIES "DOCKER_DEPS" "${DEPS}")
+endfunction ()
+
+    #TODO install_celix_oci_containers_targets

http://git-wip-us.apache.org/repos/asf/celix/blob/02ee6c4e/cmake/cmake_celix/runtime_common.sh.in
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/runtime_common.sh.in b/cmake/cmake_celix/runtime_common.sh.in
index de0c955..7c4be1d 100644
--- a/cmake/cmake_celix/runtime_common.sh.in
+++ b/cmake/cmake_celix/runtime_common.sh.in
@@ -36,8 +36,6 @@ KILL_OPTS="${KILL_OPTS:--2}" #default is -2, e.g. SIGINT
 PATIENCE="${PATIENCE:-5}" #in seconds
 
 PIDS=""
-
-=""
 RUNTIME_STARTTIME=$(date +"%s")
 trap stop_all INT
 

http://git-wip-us.apache.org/repos/asf/celix/blob/02ee6c4e/libs/framework/src/bundle_cache.c
----------------------------------------------------------------------
diff --git a/libs/framework/src/bundle_cache.c b/libs/framework/src/bundle_cache.c
index 39875b5..6de8ab7 100644
--- a/libs/framework/src/bundle_cache.c
+++ b/libs/framework/src/bundle_cache.c
@@ -149,6 +149,9 @@ celix_status_t bundleCache_getArchives(bundle_cache_pt cache, array_list_pt
*arc
 	}
 
 	framework_logIfError(logger, status, NULL, "Failed to get bundle archives");
+	if (status != CELIX_SUCCESS) {
+		perror("\t");
+	}
 
 	return status;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/02ee6c4e/libs/framework/src/framework.c
----------------------------------------------------------------------
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 39622e4..fcfe07f 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -1757,18 +1757,19 @@ void fw_serviceChanged(framework_pt framework, celix_service_event_type_t
eventT
     unsigned int i;
     celix_fw_service_listener_entry_t *entry;
 
-    celix_array_list_t* copy = celix_arrayList_create();
+    celix_array_list_t* retainedEntries = celix_arrayList_create();
+    celix_array_list_t* matchedEntries = celix_arrayList_create();
 
     celixThreadMutex_lock(&framework->serviceListenersLock);
     for (i = 0; i < celix_arrayList_size(framework->serviceListeners); i++) {
         entry = (celix_fw_service_listener_entry_t *) celix_arrayList_get(framework->serviceListeners,
i);
-        celix_arrayList_add(copy, entry);
+        celix_arrayList_add(retainedEntries, entry);
         listener_retain(entry); //ensure that use count > 0, so that the listener cannot
be destroyed until all pending event are handled.
     }
     celixThreadMutex_unlock(&framework->serviceListenersLock);
 
-    for (i = 0; i < celix_arrayList_size(copy); ++i) {
-        entry = (celix_fw_service_listener_entry_t *) celix_arrayList_get(copy, i);
+    for (i = 0; i < celix_arrayList_size(retainedEntries); ++i) {
+        entry = (celix_fw_service_listener_entry_t *) celix_arrayList_get(retainedEntries,
i);
         int matched = 0;
         properties_pt props = NULL;
         bool matchResult = false;
@@ -1778,67 +1779,63 @@ void fw_serviceChanged(framework_pt framework, celix_service_event_type_t
eventT
         }
         matched = (entry->filter == NULL) || matchResult;
         if (matched) {
-            service_reference_pt reference = NULL;
-            celix_service_event_t *event;
-
-            event = malloc(sizeof(*event));
-
-            serviceRegistry_getServiceReference(framework->registry, entry->bundle,
registration, &reference);
-
-            //NOTE: that you are never sure that the UNREGISTERED event will by handle by
an service_listener. listener could be gone
-            //Every reference retained is therefore stored and called when a service listener
is removed from the framework.
-            if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
-                serviceRegistry_retainServiceReference(framework->registry, entry->bundle,
reference);
-                celixThreadMutex_lock(&entry->mutex);
-                arrayList_add(entry->retainedReferences, reference); //TODO improve by
using set (or hashmap) instead of list
-                celixThreadMutex_unlock(&entry->mutex);
-            }
-
-            event->type = eventType;
-            event->reference = reference;
-
-            entry->listener->serviceChanged(entry->listener, event);
-
-            serviceRegistry_ungetServiceReference(framework->registry, entry->bundle,
reference);
+            celix_arrayList_add(matchedEntries, entry);
+        } else {
+            listener_release(entry); //Not a match -> release entry
+        }
+    }
+    celix_arrayList_destroy(retainedEntries);
+
+    /*
+     * TODO FIXME, A deadlock can happen when (e.g.) a service is deregistered, triggering
this fw_serviceChanged and
+     * one of the matching service listener callback tries to remove an other matched service
listener.
+     * The remove service listener will call the listener_waitForDestroy and the fw_serviceChanged
part keeps the
+     * usageCount on > 0.
+     *
+     * Not sure how to prevent/handle this.
+     */
+    for (i = 0; i < celix_arrayList_size(matchedEntries); ++i) {
+        entry = (celix_fw_service_listener_entry_t *) celix_arrayList_get(matchedEntries,
i);
+
+        service_reference_pt reference = NULL;
+        celix_service_event_t event;
+
+        serviceRegistry_getServiceReference(framework->registry, entry->bundle, registration,
&reference);
+
+        //NOTE: that you are never sure that the UNREGISTERED event will by handle by an
service_listener. listener could be gone
+        //Every reference retained is therefore stored and called when a service listener
is removed from the framework.
+        if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
+            serviceRegistry_retainServiceReference(framework->registry, entry->bundle,
reference);
+            celixThreadMutex_lock(&entry->mutex);
+            arrayList_add(entry->retainedReferences, reference); //TODO improve by using
set (or hashmap) instead of list
+            celixThreadMutex_unlock(&entry->mutex);
+        }
 
-            if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
-                //if service listener was active when service was registered, release the
retained reference
-                celixThreadMutex_lock(&entry->mutex);
-                bool removed = arrayList_removeElement(entry->retainedReferences, reference);
-                celixThreadMutex_unlock(&entry->mutex);
-                if (removed) {
-                    serviceRegistry_ungetServiceReference(framework->registry, entry->bundle,
reference); // decrease retain counter
-                }
+        event.type = eventType;
+        event.reference = reference;
 
-            }
+        entry->listener->serviceChanged(entry->listener, &event);
 
-            free(event);
+        serviceRegistry_ungetServiceReference(framework->registry, entry->bundle, reference);
 
-        } else if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED) {
-            bool matchResult = false;
-            int matched = 0;
-            if (entry->filter != NULL) {
-                filter_match(entry->filter, oldprops, &matchResult);
+        if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
+            //if service listener was active when service was registered, release the retained
reference
+            celixThreadMutex_lock(&entry->mutex);
+            bool removed = arrayList_removeElement(entry->retainedReferences, reference);
+            celixThreadMutex_unlock(&entry->mutex);
+            if (removed) {
+                serviceRegistry_ungetServiceReference(framework->registry, entry->bundle,
+                                                      reference); // decrease retain counter
             }
-            matched = (entry->filter == NULL) || matchResult;
-            if (matched) {
-                service_reference_pt reference = NULL;
-                celix_service_event_t *endmatch = malloc(sizeof(*endmatch));
 
-                serviceRegistry_getServiceReference(framework->registry, entry->bundle,
registration, &reference);
-
-                endmatch->reference = reference;
-                endmatch->type = OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH;
-                entry->listener->serviceChanged(entry->listener, endmatch);
-
-                serviceRegistry_ungetServiceReference(framework->registry, entry->bundle,
reference);
-                free(endmatch);
+        }
 
-            }
+        if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED) {
+            entry->listener->serviceChanged(entry->listener, &event);
         }
         listener_release(entry); //decrease usage, so that the listener can be destroyed
(if use count is now 0)
     }
-    celix_arrayList_destroy(copy);
+    celix_arrayList_destroy(matchedEntries);
 }
 
 //celix_status_t fw_isServiceAssignable(framework_pt fw, bundle_pt requester, service_reference_pt
reference, bool *assignable) {


Mime
View raw message