1 #include <libsyscommon/list.h>
4 #include "shared/log.h"
5 #include "shared/device-notifier.h"
6 #include "shared/common.h"
8 #include "sleep-wait.h"
10 #define MAX_WAIT_SECOND 5 /* second */
23 static GList *proc_list;
24 static GList *sleep_waiting;
26 static int max_wait_timer;
28 static void sleep_wait_done(void)
31 g_source_remove(max_wait_timer);
35 device_notify(DEVICE_NOTIFIER_POWER_SLEEP_WAIT_DONE, NULL);
38 static gboolean max_wait_expired_cb(void *data)
40 struct sleep_wait *sw;
42 GList *elem, *elem_next;
46 SYS_G_LIST_FOREACH_SAFE(sleep_waiting, elem, elem_next, sw) {
47 if (kill(sw->pi->pid, 0) != 0)
50 _E("pid=%d(%s) hasn't confirmed sleep wait", sw->pi->pid, sw->pi->comm);
51 sleep_waiting = g_list_remove_link(sleep_waiting, elem);
56 SYS_G_LIST_FOREACH_SAFE(proc_list, elem, elem_next, pi) {
58 _D("Clean up not existing pid=%d(%s) from sleep wait", pi->pid, pi->comm);
59 proc_list = g_list_remove_link(proc_list, elem);
65 _D("Maximum sleep wait expired, timeout=%ds", MAX_WAIT_SECOND);
66 device_notify(DEVICE_NOTIFIER_POWER_SLEEP_WAIT_DONE, NULL);
68 return G_SOURCE_REMOVE;
71 int add_sleep_wait(pid_t pid)
76 SYS_G_LIST_FOREACH(proc_list, elem, pi) {
81 pi = calloc(1, sizeof(struct proc_info));
86 get_command(pid, pi->comm, sizeof(pi->comm));
87 SYS_G_LIST_APPEND(proc_list, pi);
92 void remove_sleep_wait(pid_t pid)
94 struct sleep_wait *sw;
96 GList *elem, *elem_next;
98 SYS_G_LIST_FOREACH_SAFE(sleep_waiting, elem, elem_next, sw) {
99 if (sw->pi->pid == pid) {
100 sleep_waiting = g_list_remove_link(sleep_waiting, elem);
106 SYS_G_LIST_FOREACH_SAFE(proc_list, elem, elem_next, pi) {
107 if (pi->pid == pid) {
108 sleep_waiting = g_list_remove_link(sleep_waiting, elem);
115 int confirm_sleep_wait(pid_t pid, int id)
117 struct sleep_wait *sw;
118 GList *elem, *elem_next;
120 SYS_G_LIST_FOREACH_SAFE(sleep_waiting, elem, elem_next, sw) {
121 if (sw->pi->pid == pid && sw->id == id) {
122 _D("pid=%d(%s) confirmed sleep id=%d", sw->pi->pid, sw->pi->comm, sw->id);
123 sleep_waiting = g_list_remove_link(sleep_waiting, elem);
127 if (SYS_G_LIST_LENGTH(sleep_waiting) == 0) {
128 /* all sleep-waits are checked */
138 int start_sleep_wait(int id)
140 struct proc_info *pi;
141 struct sleep_wait *sw;
145 /* create sleep_wait for every pid of proc_list */
146 SYS_G_LIST_FOREACH(proc_list, elem, pi) {
147 sw = calloc(1, sizeof(struct sleep_wait));
153 SYS_G_LIST_APPEND(sleep_waiting, sw);
156 n_sleep_wait = SYS_G_LIST_LENGTH(sleep_waiting);
157 if (n_sleep_wait == 0)
162 g_source_remove(max_wait_timer);
164 _D("Sleep wait is triggered, expected number of confirmation=%d", n_sleep_wait);
165 max_wait_timer = g_timeout_add_seconds(MAX_WAIT_SECOND, max_wait_expired_cb, NULL);
170 void stop_sleep_wait(void)
172 struct sleep_wait *sw;
173 GList *elem, *elem_next;
175 if (max_wait_timer) {
176 g_source_remove(max_wait_timer);
180 SYS_G_LIST_FOREACH_SAFE(sleep_waiting, elem, elem_next, sw) {
181 sleep_waiting = g_list_remove_link(sleep_waiting, elem);