This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/scheduled_event_on_event_thread
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 5658cac5614c0f2aa4fc46afcf64c703a8d2db08
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sat Jun 17 15:37:03 2023 +0200

    Refactor service tracker to use celixThreadCondition_waitUntil
---
 libs/framework/src/service_tracker.c | 81 ++++++++++++++++--------------------
 1 file changed, 36 insertions(+), 45 deletions(-)

diff --git a/libs/framework/src/service_tracker.c 
b/libs/framework/src/service_tracker.c
index 7d342dc3..750f336b 100644
--- a/libs/framework/src/service_tracker.c
+++ b/libs/framework/src/service_tracker.c
@@ -697,6 +697,29 @@ void celix_serviceTracker_destroy(celix_service_tracker_t 
*tracker) {
     }
 }
 
+static celix_tracked_entry_t* 
celix_serviceTracker_findHighestRankingService(service_tracker_t *tracker, 
const char* serviceName) {
+    //precondition tracker->mutex locked
+    celix_tracked_entry_t* highest = NULL;
+    for (int i = 0; i < celix_arrayList_size(tracker->trackedServices); ++i) {
+        celix_tracked_entry_t* tracked = (celix_tracked_entry_t *) 
arrayList_get(tracker->trackedServices, i);
+        if (serviceName == NULL || (serviceName != NULL && 
tracked->serviceName != NULL &&
+                                    
celix_utils_stringEquals(tracked->serviceName, serviceName))) {
+            if (highest == NULL) {
+                highest = tracked;
+            } else {
+                int compare = celix_utils_compareServiceIdsAndRanking(
+                        tracked->serviceId, tracked->serviceRanking,
+                        highest->serviceId, highest->serviceRanking
+                );
+                if (compare < 0) {
+                    highest = tracked;
+                }
+            }
+        }
+    }
+    return highest;
+}
+
 bool celix_serviceTracker_useHighestRankingService(service_tracker_t *tracker,
                                                    const char *serviceName 
/*sanity*/,
                                                    double waitTimeoutInSeconds 
/*0 -> do not wait */,
@@ -704,59 +727,27 @@ bool 
celix_serviceTracker_useHighestRankingService(service_tracker_t *tracker,
                                                    void (*use)(void *handle, 
void *svc),
                                                    void 
(*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
                                                    void (*useWithOwner)(void 
*handle, void *svc, const celix_properties_t *props, const celix_bundle_t 
*owner)) {
-    bool called = false;
-    celix_tracked_entry_t *tracked = NULL;
-    celix_tracked_entry_t *highest = NULL;
-    unsigned int i;
-    struct timespec begin = celix_gettime(CLOCK_MONOTONIC);
-    double remaining = waitTimeoutInSeconds > INT_MAX ? INT_MAX : 
waitTimeoutInSeconds;
-    remaining = remaining < 0 ? 0 : remaining;
-    double elapsed = 0;
-    long seconds = remaining;
-    long nanoseconds = (remaining - seconds) * CELIX_NS_IN_SEC;
-
-    //first lock tracker and get highest tracked entry
+    //first lock tracker and get highest ranking tracked entry
     celixThreadMutex_lock(&tracker->mutex);
-    while (highest == NULL) {
-        unsigned int size = arrayList_size(tracker->trackedServices);
-
-        for (i = 0; i < size; i++) {
-            tracked = (celix_tracked_entry_t *) 
arrayList_get(tracker->trackedServices, i);
-            if (serviceName == NULL || (serviceName != NULL && 
tracked->serviceName != NULL &&
-                                        
celix_utils_stringEquals(tracked->serviceName, serviceName))) {
-                if (highest == NULL) {
-                    highest = tracked;
-                } else {
-                    int compare = celix_utils_compareServiceIdsAndRanking(
-                            tracked->serviceId, tracked->serviceRanking,
-                            highest->serviceId, highest->serviceRanking
-                    );
-                    if (compare < 0) {
-                        highest = tracked;
-                    }
-                }
-            }
-        }
-        if(highest == NULL && (seconds > 0 || nanoseconds > 0)) {
-            celixThreadCondition_timedwaitRelative(&tracker->condTracked, 
&tracker->mutex, seconds, nanoseconds);
-            elapsed  = celix_elapsedtime(CLOCK_MONOTONIC, begin);
-            remaining = remaining > elapsed ? (remaining - elapsed) : 0;
-            seconds = remaining;
-            nanoseconds = (remaining - seconds) * CELIX_NS_IN_SEC;
-        } else {
-            // highest found or timeout
+    struct timespec absTime = 
celixThreadCondition_getDelayedTime(waitTimeoutInSeconds);
+    celix_tracked_entry_t* highest = 
celix_serviceTracker_findHighestRankingService(tracker, serviceName);
+    while (highest == NULL && waitTimeoutInSeconds > 0) {
+        celix_status_t waitStatus = 
celixThreadCondition_waitUntil(&tracker->condTracked, &tracker->mutex, 
&absTime);
+        if (waitStatus == ETIMEDOUT) {
             break;
         }
+        highest = celix_serviceTracker_findHighestRankingService(tracker, 
serviceName);
     }
-    if (highest != NULL) {
-        //highest found lock tracked entry and increase use count
+    if (highest) {
+        // highest found, increase use count
         tracked_retain(highest);
     }
-    //unlock tracker so that the tracked entry can be removed from the 
trackedServices list if unregistered.
+    // unlock tracker so that the tracked entry can be removed from the 
trackedServices list if unregistered.
     celixThreadMutex_unlock(&tracker->mutex);
 
-    if (highest != NULL) {
-        //got service, call, decrease use count an signal useCond after.
+    bool called = false;
+    if (highest) {
+        //got service, call, decrease use count a signal useCond after.
         if (use != NULL) {
             use(callbackHandle, highest->service);
         }

Reply via email to