Allow parallel action execution
authorKonrad Kuchciak <k.kuchciak@samsung.com>
Thu, 27 Jun 2019 11:25:05 +0000 (13:25 +0200)
committerKonrad Kuchciak <k.kuchciak@samsung.com>
Fri, 28 Jun 2019 08:55:36 +0000 (10:55 +0200)
data_source module can now run default action, even if another action
(of the same process) is in progress.

Moreover, added refcounting mechanism for proc_info structure.

Change-Id: I4e5bf3d931e7b7ab5056373ee49817b0053142cb

src/action.c
src/data_source.h
src/process.c
src/process.h

index d432195..fb05b76 100644 (file)
@@ -103,8 +103,9 @@ static void action_finish(struct action_data *ad)
                              limit_type_to_string(ad->lt),
                              ad->ds->param_name);
 
-    ad->ds->process->action_in_progress = 0;
+    ad->ds->action_in_progress = 0;
 
+    process_unref(ad->ds->process);
     close(ad->stdout_fd);
     close(ad->stderr_fd);
     free(ad->report_path);
@@ -217,9 +218,9 @@ int action_run_default(struct data_source *ds, enum limit_type lt)
     struct action_data *ad;
     struct smpl_container *sc = process_is_foreground(ds->process) ? &ds->data_fg : &ds->data_bg;
 
-    if (ds->process->action_in_progress)
+    if (ds->action_in_progress)
         return 0;
-    ds->process->action_in_progress = 1;
+    ds->action_in_progress = 1;
 
     _D_PROC(ds->process, "Running default action");
 
@@ -241,6 +242,7 @@ int action_run_default(struct data_source *ds, enum limit_type lt)
         ad->allowed_value = sample_to_gvariant(&ds->limit.peak);
     }
 
+    process_ref(ds->process);
     g_timeout_add(0, action_run, ad);
 
     return 0;
index be9a323..69257e0 100644 (file)
@@ -42,6 +42,8 @@ struct data_source {
     struct smpl_container data_bg;
     void                  *extra_data;
 
+    int                   action_in_progress;
+
     int (*update)(struct data_source *ds,
                   struct raw_data_item *rd_global,
                   struct raw_data_item *rd_pid);
index a9c5bdb..7cbc858 100644 (file)
@@ -36,7 +36,7 @@
 
 /* List of all processes and their current state */
 static struct list_head process_table[HASH_TABLE_SIZE];
-
+static void process_cleanup(struct proc_info *process);
 
 static int hash(int pid)
 {
@@ -108,11 +108,14 @@ int process_create_info(int pid, int ppid, struct proc_info **process)
     INIT_LIST_HEAD(&p->node);
 
     ret = process_update_info(p, NULL);
-    if (ret)
+    if (ret) {
+        process_cleanup(p);
         return ret;
+    }
 
     process_table_add(p);
     *process = p;
+    process_ref(p);
 
     if (p->monitor)
         _D_PROC(p, "Created process");
@@ -287,12 +290,12 @@ int process_update_info(struct proc_info *process, int *status)
 
     ret = process_get_appid(process);
     if (ret == -ENOMEM) {
-        goto cleanup;
+        goto finish;
     }
 
     ret = process_get_exe(process);
     if (ret) {
-        goto cleanup;
+        goto finish;
     }
 
     if (process->appid) {
@@ -301,13 +304,13 @@ int process_update_info(struct proc_info *process, int *status)
         ret = process_get_apptype(process);
         if (ret) {
             _E("Unable to get process' app type");
-            goto cleanup;
+            goto finish;
         }
 
         ret = process_get_component(process);
         if (ret) {
             _E("Unable to get process' component type");
-            goto cleanup;
+            goto finish;
         }
 
     } else {
@@ -324,14 +327,13 @@ int process_update_info(struct proc_info *process, int *status)
         ret = config_read_per_process(process);
         if (ret) {
             _E("Unable to read limits for process");
-            goto cleanup;
+            goto finish;
         }
     }
 
     return 0;
 
-cleanup:
-    process_cleanup(process);
+finish:
     return ret;
 }
 
@@ -490,26 +492,24 @@ void process_remove_deads(void)
 {
     struct proc_info *process, *next;
 
-    for (int i = 0; i < HASH_TABLE_SIZE; i++) {
-        list_for_each_entry_safe(process, next, &process_table[i], node) {
-            if (!process->still_alive && !process->action_in_progress) {
-                process_cleanup(process);
-                continue;
+    for (int i = 0; i < HASH_TABLE_SIZE; i++)
+        list_for_each_entry_safe(process, next, &process_table[i], node)
+            switch (process->still_alive) {
+            case 0:
+                process->still_alive = -1;
+                process_unref(process);
+                break;
+            case 1:
+                process->still_alive = 0;
+                break;
             }
-
-            process->still_alive = 0;
-        }
-    }
 }
 
-void process_cleanup(struct proc_info *process)
+static void process_cleanup(struct proc_info *process)
 {
     struct data_source *ds;
     struct sample_s *sample, *sample_next;
 
-    if (process->monitor)
-        _D_PROC(process, "Removed process");
-
     free(process->exe);
     free(process->appid);
     free(process->apptype);
@@ -543,6 +543,19 @@ void process_cleanup_all(void)
 
     for (int i = 0; i < HASH_TABLE_SIZE; i++) {
         list_for_each_entry_safe(process, next, &process_table[i], node)
-            process_cleanup(process);
+            process_unref(process);
     }
 }
+
+void process_unref(struct proc_info *process) {
+    process->ref_count--;
+    if (process->ref_count <= 0) {
+        if (process->monitor)
+            _D_PROC(process, "Removing process");
+        process_cleanup(process);
+    }
+}
+
+void process_ref(struct proc_info *process) {
+    process->ref_count++;
+}
\ No newline at end of file
index a0a160c..329c3b5 100644 (file)
@@ -53,7 +53,6 @@ struct proc_info {
     enum proc_class     class;
 
     int                 still_alive;
-    int                 action_in_progress;
 
     int                 monitor;
     int                 kill;
@@ -66,6 +65,7 @@ struct proc_info {
     struct data_source  *data_sources;
 
     struct list_head    node;
+    int                 ref_count;
 };
 
 void process_table_init();
@@ -78,8 +78,8 @@ const char *process_class_to_string(int class);
 void process_check_limits(struct proc_info *process);
 void process_print_current_state(struct proc_info *process);
 void process_remove_deads(void);
-void process_cleanup(struct proc_info *process);
 void process_cleanup_all(void);
-
+void process_ref(struct proc_info *process);
+void process_unref(struct proc_info *process);
 
 #endif /* PROCESS_H */
\ No newline at end of file