summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorInkyun Kil <inkyun.kil@samsung.com>2019-09-18 17:31:31 +0900
committerInkyun Kil <inkyun.kil@samsung.com>2019-09-18 18:36:28 +0900
commit2a114905a9f7fb31701214942fbe9c1fe27d6df6 (patch)
treedd3781f809e80da4bf45444ba39d84b4ff1ceda1
parent990babc93119b3f5551bc591f82836b262e5cac9 (diff)
downloadalarm-manager-2a114905a9f7fb31701214942fbe9c1fe27d6df6.tar.gz
alarm-manager-2a114905a9f7fb31701214942fbe9c1fe27d6df6.tar.bz2
alarm-manager-2a114905a9f7fb31701214942fbe9c1fe27d6df6.zip
Handle zombie alarm
- If G_DBUS_ERROR_SERVICE_UNKNOWN error occurs, exclude it from alarm schedule list. Change-Id: I6d68207282e3d6f9e44c11c44c3f9ef3bc101d81 Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
-rw-r--r--include/alarm-internal.h1
-rw-r--r--server/alarm-manager-dbus.c118
-rw-r--r--server/alarm-manager-schedule.c14
3 files changed, 127 insertions, 6 deletions
diff --git a/include/alarm-internal.h b/include/alarm-internal.h
index 8744ce3..d8959ff 100644
--- a/include/alarm-internal.h
+++ b/include/alarm-internal.h
@@ -126,6 +126,7 @@ typedef struct {
long requested_interval;
int is_ref;
bool global;
+ bool zombie_mode;
} __alarm_info_t;
typedef struct {
diff --git a/server/alarm-manager-dbus.c b/server/alarm-manager-dbus.c
index 0da088a..b12bd9f 100644
--- a/server/alarm-manager-dbus.c
+++ b/server/alarm-manager-dbus.c
@@ -33,6 +33,11 @@
extern __alarm_server_context_t alarm_context;
extern GSList *g_expired_alarm_list;
+struct watch_info_t {
+ int watch_id;
+ alarm_id_t alarm_id;
+};
+
static GDBusNodeInfo *introspection_data;
static const gchar introspection_xml[] =
"<node name='/org/tizen/alarm/manager'>"
@@ -288,11 +293,118 @@ static gboolean __send_noti_to_session_bus(char *service_name,
return TRUE;
}
+static void __on_name_appeared(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ SECURE_LOGW("alarm sender name appeared : %s %s", name, name_owner);
+
+ struct watch_info_t *watch_info = (struct watch_info_t *)user_data;
+ GSList *gs_iter;
+ __alarm_info_t *entry;
+ alarm_id_t alarm_id = watch_info->alarm_id;
+
+ g_bus_unwatch_name(watch_info->watch_id);
+ free(watch_info);
+
+ for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) {
+ entry = gs_iter->data;
+ if (alarm_id == entry->alarm_id) {
+ entry->zombie_mode = false;
+
+ _alarm_disable_timer(alarm_context);
+ _clear_scheduled_alarm_list();
+ _alarm_schedule();
+ _rtc_set();
+
+ return;
+ }
+ }
+}
+
+static void __alarm_send_noti_to_application_reply(
+ GObject *source_object, GAsyncResult *res, gpointer user_data) {
+
+ GVariant *message;
+ GDBusConnection *conn;
+ GError *error = NULL;
+ alarm_id_t *reply_alarm_id = (alarm_id_t *)user_data;
+ char *service_name = NULL;
+ char *app_unique_name = NULL;
+ struct watch_info_t *watch_info;
+ char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,};
+
+ GSList *gs_iter;
+ __alarm_info_t *entry;
+ bool is_existed = false;
+
+ conn = G_DBUS_CONNECTION(source_object);
+ message = g_dbus_connection_call_finish(conn, res, &error);
+
+ if (error != NULL && error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) {
+ for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter) ) {
+ entry = gs_iter->data;
+
+ if (*reply_alarm_id == entry->alarm_id) {
+ is_existed = true;
+
+ app_unique_name = entry->app_unique_name;
+
+ if (entry->dst_service_name == NULL)
+ service_name = entry->app_service_name_mod;
+ else
+ service_name = entry->dst_service_name_mod;
+
+ break;
+ }
+ }
+
+
+ LOGW("failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]",
+ error->code, error->message, *reply_alarm_id,
+ app_unique_name, service_name);
+
+ snprintf(log_message, sizeof(log_message),
+ "failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]",
+ error->code, error->message, *reply_alarm_id, app_unique_name, service_name);
+ _save_module_log("EXPIRED_FAIL", log_message);
+
+ g_error_free(error);
+
+ if (is_existed) {
+ entry->zombie_mode = true;
+ watch_info = (struct watch_info_t *)calloc(1, sizeof(struct watch_info_t));
+ watch_info->alarm_id = entry->alarm_id;
+ watch_info->watch_id = g_bus_watch_name_on_connection(
+ alarm_context.connection,
+ service_name,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ __on_name_appeared,
+ NULL,
+ watch_info,
+ NULL);
+
+ alarm_context.c_due_time = -1;
+ _alarm_disable_timer(alarm_context);
+ _clear_scheduled_alarm_list();
+ _alarm_schedule();
+ _rtc_set();
+ }
+ } else {
+ g_variant_unref(message);
+ }
+
+ free(reply_alarm_id);
+
+}
+
void _alarm_send_noti_to_application_by_dbus(const char *app_service_name,
alarm_id_t alarm_id, int msec, uid_t uid)
{
char service_name[MAX_SERVICE_NAME_LEN] = {0,};
gboolean ret;
+ alarm_id_t *reply_alarm_id;
if (app_service_name == NULL || strlen(app_service_name) == 0) {
LOGE("This alarm destination is invalid.");
@@ -312,6 +424,8 @@ void _alarm_send_noti_to_application_by_dbus(const char *app_service_name,
LOGE("failed to send alarm expired noti for %d, %s",
alarm_id, service_name);
} else {
+ reply_alarm_id = (alarm_id_t *)calloc(1, sizeof(alarm_id_t));
+ *reply_alarm_id = alarm_id;
g_dbus_connection_call(alarm_context.connection,
service_name,
"/org/tizen/alarm/client",
@@ -322,8 +436,8 @@ void _alarm_send_noti_to_application_by_dbus(const char *app_service_name,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
- NULL,
- NULL);
+ __alarm_send_noti_to_application_reply,
+ reply_alarm_id);
}
}
diff --git a/server/alarm-manager-schedule.c b/server/alarm-manager-schedule.c
index a353e00..68b9180 100644
--- a/server/alarm-manager-schedule.c
+++ b/server/alarm-manager-schedule.c
@@ -470,8 +470,10 @@ static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time)
double interval = 0;
- SECURE_LOGD("alarm[%d] with duetime(%ld) at current(%ld)\n",
- entry->alarm_id, due_time, current_time);
+ SECURE_LOGD("alarm[%d] with duetime(%ld) at current(%ld) - (%s) z:%d",
+ entry->alarm_id, due_time, current_time,
+ entry->app_unique_name, (int)entry->zombie_mode);
+
if (due_time == 0) /*0 means this alarm has been disabled*/ {
continue;
}
@@ -479,7 +481,8 @@ static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time)
interval = difftime(due_time, current_time);
if (interval < 0) /*When the alarm expires, it may makes an error.*/ {
- LOGW("The duetime of alarm(%d) is OVER.", entry->alarm_id);
+ LOGW("The duetime of alarm(%d) is OVER.(z:%d)",
+ entry->alarm_id, entry->zombie_mode);
_alarm_set_next_duetime(entry);
if (entry->due_time < current_time) {
@@ -501,6 +504,9 @@ static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time)
}
+ if (entry->zombie_mode)
+ continue;
+
interval = difftime(due_time, min_time);
if ((interval < 0) || min_time == -1)
@@ -528,7 +534,7 @@ void _alarm_schedule()
entry = (__alarm_info_t *)iter->data;
due_time = entry->due_time;
- if (due_time == min_time)
+ if (due_time == min_time && entry->zombie_mode == false)
_add_to_scheduled_alarm_list(entry);
}