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);
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");
ad->allowed_value = sample_to_gvariant(&ds->limit.peak);
}
+ process_ref(ds->process);
g_timeout_add(0, action_run, ad);
return 0;
/* 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)
{
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");
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) {
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 {
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;
}
{
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);
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
enum proc_class class;
int still_alive;
- int action_in_progress;
int monitor;
int kill;
struct data_source *data_sources;
struct list_head node;
+ int ref_count;
};
void process_table_init();
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