]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Use the default scheduler for short-term events
authorTobias Brunner <tobias@strongswan.org>
Sat, 2 May 2020 07:20:59 +0000 (09:20 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 2 Jun 2020 12:07:06 +0000 (14:07 +0200)
Using AlarmManager has quite some overhead, so we use our regular
scheduler for events that are to be executed in the near future.

src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_scheduler.c
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_scheduler.h
src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c

index 5a901fe1503b2ec0b20011a1b276d871b85f81d9..3252082bb91a46baf8c6d320eba330c84b928d22 100644 (file)
 #include <processing/jobs/callback_job.h>
 #include <threading/mutex.h>
 
+/**
+ * Threshold in milliseconds up to which the default scheduler is used.
+ * This includes the roaming events (100 ms) and initial retransmits.
+ */
+#define DEFAULT_SCHEDULER_THRESHOLD 3000
+
 typedef struct private_scheduler_t private_scheduler_t;
 
 /**
@@ -52,6 +58,11 @@ struct private_scheduler_t {
         * Mutex to safely access the scheduled jobs.
         */
        mutex_t *mutex;
+
+       /**
+        * Default scheduler used for short-term events.
+        */
+       scheduler_t *default_scheduler;
 };
 
 /**
@@ -137,6 +148,14 @@ METHOD(scheduler_t, schedule_job_ms, void,
        entry_t *entry = NULL;
        jstring jid;
 
+       /* use the default scheduler for short-term events */
+       if (ms <= DEFAULT_SCHEDULER_THRESHOLD)
+       {
+               this->default_scheduler->schedule_job_ms(this->default_scheduler,
+                                                                                                job, ms);
+               return;
+       }
+
        androidjni_attach_thread(&env);
        jid = allocate_id(this, env);
        if (!jid)
@@ -213,6 +232,8 @@ METHOD(scheduler_t, flush, void,
        JNIEnv *env;
        jmethodID method_id;
 
+       this->default_scheduler->flush(this->default_scheduler);
+
        this->mutex->lock(this->mutex);
        this->jobs->destroy_function(this->jobs, destroy_entry);
        this->jobs = hashtable_create(hashtable_hash_str, hashtable_equals_str, 16);
@@ -247,6 +268,7 @@ METHOD(scheduler_t, destroy, void,
                (*env)->DeleteGlobalRef(env, this->cls);
        }
        androidjni_detach_thread();
+       this->default_scheduler->destroy(this->default_scheduler);
        this->mutex->destroy(this->mutex);
        this->jobs->destroy(this->jobs);
        free(this);
@@ -255,7 +277,7 @@ METHOD(scheduler_t, destroy, void,
 /*
  * Described in header
  */
-scheduler_t *android_scheduler_create(jobject context)
+scheduler_t *android_scheduler_create(jobject context, scheduler_t *scheduler)
 {
        private_scheduler_t *this;
        JNIEnv *env;
@@ -272,6 +294,7 @@ scheduler_t *android_scheduler_create(jobject context)
                        .flush = _flush,
                        .destroy = _destroy,
                },
+               .default_scheduler = scheduler,
                .jobs = hashtable_create(hashtable_hash_str, hashtable_equals_str, 16),
                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
        );
index a27491084ddf7acee7c4afec2db70a26bc1aa64e..eea011211532328b2e9a2f79db82add1d3c62ffe 100644 (file)
 /**
  * Create an Android-specific scheduler_t implementation.
  *
+ * The given scheduler is used for short-term events. We can't destroy it anyway
+ * because of the scheduler job operating on it, and this way we can use it to
+ * avoid the overhead of broadcasts for some events.
+ *
  * @param context      Context object
+ * @param scheduler    the default scheduler used as fallback
  * @return                     scheduler_t instance
  */
-scheduler_t *android_scheduler_create(jobject context);
+scheduler_t *android_scheduler_create(jobject context, scheduler_t *scheduler);
 
 #endif /** ANDROID_SCHEDULER_H_ @}*/
index a459f9f3aa4c78948cf674ccc67da2d53365ef84..bb8bdba82b4651931ac7e827e23ac4e0486528e4 100644 (file)
@@ -94,11 +94,6 @@ struct private_charonservice_t {
         * Sockets that were bypassed and we keep track for
         */
        linked_list_t *sockets;
-
-       /**
-        * Default scheduler if we don't use it
-        */
-       scheduler_t *default_scheduler;
 };
 
 /**
@@ -580,15 +575,6 @@ static void charonservice_init(JNIEnv *env, jobject service, jobject builder,
        );
        charonservice = &this->public;
 
-       if (android_sdk_version >= ANDROID_MARSHMALLOW)
-       {
-               /* use a custom scheduler so the app is woken when jobs have to run.
-                * we can't destroy the default scheduler here due to the scheduler
-                * job that's operating on it, so we stash it away until later */
-               this->default_scheduler = lib->scheduler;
-               lib->scheduler = android_scheduler_create(service);
-       }
-
        lib->plugins->add_static_features(lib->plugins, "androidbridge", features,
                                                                          countof(features), TRUE, NULL, NULL);
 
@@ -615,7 +601,6 @@ static void charonservice_deinit(JNIEnv *env)
 {
        private_charonservice_t *this = (private_charonservice_t*)charonservice;
 
-       DESTROY_IF(this->default_scheduler);
        this->network_manager->destroy(this->network_manager);
        this->sockets->destroy(this->sockets);
        this->builder->destroy(this->builder);
@@ -661,6 +646,12 @@ JNI_METHOD(CharonVpnService, initializeCharon, jboolean,
                return FALSE;
        }
 
+       if (android_sdk_version >= ANDROID_MARSHMALLOW)
+       {
+               /* use a custom scheduler so the app is woken when jobs have to run */
+               lib->scheduler = android_scheduler_create(this, lib->scheduler);
+       }
+
        /* set options before initializing other libraries that might read them */
        logfile = androidjni_convert_jstring(env, jlogfile);