android: Use the default scheduler for short-term events
Using AlarmManager has quite some overhead, so we use our regular scheduler for events that are to be executed in the near future.
This commit is contained in:
parent
1b4c4123c2
commit
d67a5b0c4d
|
@ -21,6 +21,12 @@
|
|||
#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),
|
||||
);
|
||||
|
|
|
@ -28,9 +28,14 @@
|
|||
/**
|
||||
* 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_ @}*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue