[gnome-system-monitor] Moved process list into separate class, now owned by GsmApplication



commit 143a90702638bdd4d9827cc38a6172c8bf8d1adf
Author: Artem Vorotnikov <artem vorotnikov me>
Date:   Tue Dec 27 14:00:05 2016 +0300

    Moved process list into separate class, now owned by GsmApplication
    
    Signed-off-by: Artem Vorotnikov <artem vorotnikov me>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=776653

 src/application.h      |   42 +++++++++++--------
 src/lsof.cpp           |    2 +-
 src/openfiles.cpp      |    2 +-
 src/prettytable.cpp    |    2 +-
 src/procproperties.cpp |    2 +-
 src/proctable.cpp      |  106 +++++++++++++++++++++--------------------------
 6 files changed, 75 insertions(+), 81 deletions(-)
---
diff --git a/src/application.h b/src/application.h
index c2be9eb..b31e398 100644
--- a/src/application.h
+++ b/src/application.h
@@ -136,16 +136,6 @@ class ProcInfo
   public:
     ProcInfo& operator=(const ProcInfo&) = delete;
     ProcInfo(const ProcInfo&) = delete;
-    // TODO: use a set instead
-    // sorted by pid. The map has a nice property : it is sorted
-    // by pid so this helps a lot when looking for the parent node
-    // as ppid is nearly always < pid.
-    typedef std::map<pid_t, ProcInfo> List;
-    static List all;
-
-    static ProcInfo& find(pid_t pid);
-
-
     ProcInfo(pid_t pid);
     ~ProcInfo();
     // adds one more ref to icon
@@ -164,17 +154,32 @@ class ProcInfo
     const pid_t     pid;
     pid_t           ppid;
     guint           uid;
-
-// private:
-    // tracks cpu time per process keeps growing because if a
-    // ProcInfo is deleted this does not mean that the process is
-    // not going to be recreated on the next update.  For example,
-    // if dependencies + (My or Active), the proclist is cleared
-    // on each update.  This is a workaround
-    static std::map<pid_t, guint64> cpu_times;
 };
 
+class ProcList {
+    // TODO: use a set instead
+    // sorted by pid. The map has a nice property : it is sorted
+    // by pid so this helps a lot when looking for the parent node
+    // as ppid is nearly always < pid.
+    typedef std::map<pid_t, ProcInfo> List;
+    List data;
+    std::mutex data_lock;
+public:
+    std::map<pid_t, unsigned long> cpu_times;
+    typedef List::iterator Iterator;
+    Iterator begin() { return std::begin(data); }
+    Iterator end() { return std::end(data); }
+    Iterator erase(List::iterator it) {
+        std::lock_guard<std::mutex> lg(data_lock);
+        return data.erase(it);
+    }
+    std::pair<Iterator, bool> emplace(pid_t pid);
+    void clear() { return data.clear(); }
 
+    ProcInfo& find(pid_t pid) {
+        return data.at(pid);
+    }
+};
 
 class GsmApplication : public Gtk::Application, private procman::NonCopyable
 
@@ -195,6 +200,7 @@ public:
     void save_config();
     void shutdown();
 
+    ProcList         processes;
     GsmTreeView      *tree;
     GtkRevealer      *proc_actionbar_revealer;
     GtkMenu          *popup_menu;
diff --git a/src/lsof.cpp b/src/lsof.cpp
index d5ecec3..8c94bd2 100644
--- a/src/lsof.cpp
+++ b/src/lsof.cpp
@@ -142,7 +142,7 @@ namespace
 
                 unsigned count = 0;
 
-                for (const auto& v : ProcInfo::all) {
+                for (const auto& v : app->processes) {
                     const auto& info = v.second;
                     MatchSet matches;
                     lsof.search(info, std::inserter(matches, matches.begin()));
diff --git a/src/openfiles.cpp b/src/openfiles.cpp
index 60baae6..1fce282 100644
--- a/src/openfiles.cpp
+++ b/src/openfiles.cpp
@@ -178,7 +178,7 @@ update_openfiles_dialog (GsmTreeView *tree)
 
     pid_t pid = GPOINTER_TO_UINT(static_cast<pid_t*>(g_object_get_data (G_OBJECT (tree), "selected_info")));
     try {
-        info = &ProcInfo::find(pid);
+        info = &GsmApplication::get()->processes.find(pid);
     } catch (const std::out_of_range&) { return; }
 
     model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
diff --git a/src/prettytable.cpp b/src/prettytable.cpp
index 2563f21..06e3b28 100644
--- a/src/prettytable.cpp
+++ b/src/prettytable.cpp
@@ -105,7 +105,7 @@ PrettyTable::register_application(pid_t pid, Glib::RefPtr<Gdk::Pixbuf> icon)
   /* If process already exists then set the icon. Otherwise put into hash
   ** table to be added later */
   try {
-    auto& info = ProcInfo::find(pid);
+    auto& info = GsmApplication::get()->processes.find(pid);
     {
       info.set_icon(icon);
       // move the ref to the map
diff --git a/src/procproperties.cpp b/src/procproperties.cpp
index c1862c1..7f2c461 100644
--- a/src/procproperties.cpp
+++ b/src/procproperties.cpp
@@ -108,7 +108,7 @@ update_procproperties_dialog (GtkTreeView *tree)
     ProcInfo *info;
 
     pid_t pid = GPOINTER_TO_UINT(static_cast<pid_t*>(g_object_get_data (G_OBJECT (tree), "selected_info")));
-    try { info = &ProcInfo::find(pid); } catch (const std::out_of_range&) { info = nullptr; }
+    try { info = &GsmApplication::get()->processes.find(pid); } catch (const std::out_of_range&) { info = 
nullptr; }
 
     fill_proc_properties(tree, info);
 }
diff --git a/src/proctable.cpp b/src/proctable.cpp
index 3de4d73..10eb328 100644
--- a/src/proctable.cpp
+++ b/src/proctable.cpp
@@ -63,15 +63,6 @@
 #include <gdk/gdkx.h>
 #endif
 
-ProcInfo::List ProcInfo::all;
-std::map<pid_t, guint64> ProcInfo::cpu_times;
-
-
-ProcInfo& ProcInfo::find(pid_t pid)
-{
-    return all.at(pid);
-}
-
 static void
 cb_save_tree_state(gpointer, gpointer data)
 {
@@ -198,7 +189,7 @@ cb_refresh_icons (GtkIconTheme *theme, gpointer data)
         g_source_remove (app->timeout);
     }
 
-    for (auto& v : ProcInfo::all) {
+    for (auto& v : app->processes) {
         app->pretty_table->set_icon(v.second);
     }
 
@@ -640,10 +631,45 @@ get_process_name (ProcInfo *info,
             g_free(basename);
         }
     }
-
     info->name = g_strdup (cmd);
 }
 
+std::pair<ProcList::Iterator, bool> ProcList::emplace(pid_t pid) {
+    std::lock_guard<std::mutex> lg(data_lock);
+    auto res = data.emplace(pid, pid);
+    if (res.second) {
+        auto& entry = res.first->second;
+        glibtop_proc_state procstate;
+        glibtop_proc_args procargs;
+        gchar** arguments;
+        glibtop_get_proc_state (&procstate, pid);
+        arguments = glibtop_get_proc_argv (&procargs, pid, 0);
+        /* FIXME : wrong. name and arguments may change with exec* */
+        get_process_name (&entry, procstate.cmd, static_cast<const GStrv>(arguments));
+        std::string tooltip = make_string(g_strjoinv(" ", arguments));
+        if (tooltip.empty())
+            tooltip = procstate.cmd;
+        entry.tooltip = g_markup_escape_text(tooltip.c_str(), -1);
+        entry.arguments = g_strescape(tooltip.c_str(), "\\\"");
+        g_strfreev(arguments);
+        get_process_selinux_context (&entry);
+        get_process_cgroup_info(entry);
+        get_process_systemd_info(&entry);
+        glibtop_proc_time proctime;
+        glibtop_get_proc_time (&proctime, pid);
+        guint64 cpu_time = proctime.rtime;
+        auto it = cpu_times.find(pid);
+        if (it != std::end(cpu_times))
+        {
+            if (proctime.rtime >= it->second)
+                cpu_time = it->second;
+        }
+        entry.cpu_time = cpu_time;
+        entry.start_time = proctime.start_time;
+    }
+    return res;
+}
+
 std::string
 ProcInfo::lookup_user(guint uid)
 {
@@ -785,7 +811,7 @@ insert_info_to_tree (ProcInfo *info, GsmApplication *app, bool forced = false)
         ProcInfo *parent = 0;
 
         if (not forced)
-            try { parent = &ProcInfo::find(info->ppid); } catch (const std::out_of_range&) { parent = 
nullptr; }
+            try { parent = &app->processes.find(info->ppid); } catch (const std::out_of_range&) { parent = 
nullptr; }
 
         if (parent) {
             GtkTreePath *parent_node = gtk_tree_model_get_path(model, &parent->node);
@@ -896,7 +922,7 @@ update_info (GsmApplication *app, ProcInfo *info)
     if (not app->config.solaris_mode)
         info->pcpu *= app->config.num_cpus;
 
-    ProcInfo::cpu_times[info->pid] = info->cpu_time = proctime.rtime;
+    app->processes.cpu_times[info->pid] = info->cpu_time = proctime.rtime;
     info->nice = procuid.nice;
 
     // set the ppid only if one can exist
@@ -925,44 +951,6 @@ ProcInfo::ProcInfo(pid_t pid)
       ppid(-1),
       uid(-1)
 {
-    ProcInfo * const info = this;
-    glibtop_proc_state procstate;
-    glibtop_proc_time proctime;
-    glibtop_proc_args procargs;
-    gchar** arguments;
-
-    glibtop_get_proc_state (&procstate, pid);
-    glibtop_get_proc_time (&proctime, pid);
-    arguments = glibtop_get_proc_argv (&procargs, pid, 0);
-
-    /* FIXME : wrong. name and arguments may change with exec* */
-    get_process_name (info, procstate.cmd, static_cast<const GStrv>(arguments));
-
-    std::string tooltip = make_string(g_strjoinv(" ", arguments));
-    if (tooltip.empty())
-        tooltip = procstate.cmd;
-
-    info->tooltip = g_markup_escape_text(tooltip.c_str(), -1);
-
-    info->arguments = g_strescape(tooltip.c_str(), "\\\"");
-    g_strfreev(arguments);
-
-    guint64 cpu_time = proctime.rtime;
-    std::map<pid_t, guint64>::iterator it(ProcInfo::cpu_times.find(pid));
-    if (it != ProcInfo::cpu_times.end())
-    {
-        if (proctime.rtime >= it->second)
-            cpu_time = it->second;
-    }
-    info->cpu_time = cpu_time;
-    info->start_time = proctime.start_time;
-
-    get_process_selinux_context (info);
-    info->cgroup_name = NULL;
-    get_process_cgroup_info(*info);
-
-    info->unit = info->session = info->seat = NULL;
-    get_process_systemd_info(info);
 }
 
 static void
@@ -980,9 +968,9 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
     for (i = 0; i < n; ++i) {
         ProcInfo* info;
         try {
-            info = &ProcInfo::find(pid_list[i]);
+            info = &app->processes.find(pid_list[i]);
         } catch (const std::out_of_range&) {
-            info = &ProcInfo::all.emplace(pid_list[i], pid_list[i]).first->second;
+            info = &app->processes.emplace(pid_list[i]).first->second;
             addition.push_back(info);
         }
 
@@ -996,14 +984,14 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
 
     const std::set<pid_t> pids(pid_list, pid_list + n);
 
-    auto it = std::begin(ProcInfo::all);
-    while (it != std::end(ProcInfo::all)) {
+    auto it = std::begin(app->processes);
+    while (it != std::end(app->processes)) {
         auto& info = it->second;
         if (pids.find(info.pid) == pids.end()) {
             procman_debug("ripping %d", info.pid);
             remove_info_from_tree(app, model, info, addition);
             addition.remove(&info);
-            it = ProcInfo::all.erase(it);
+            it = app->processes.erase(it);
         } else {
             ++it;
         }
@@ -1059,7 +1047,7 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
                 }
 
                 ProcInfo* parent;
-                try { parent = &ProcInfo::find((*it)->ppid); } catch (const std::out_of_range&) { parent = 
nullptr; }
+                try { parent = &app->processes.find((*it)->ppid); } catch (const std::out_of_range& e) { 
parent = nullptr; }
                 // if the parent is unreachable
                 if (not parent) {
                     // or std::find(addition.begin(), addition.end(), parent) == addition.end()) {
@@ -1079,7 +1067,7 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
     }
 
 
-    for (auto& v : ProcInfo::all) update_info_mutable_cols(&v.second);
+    for (auto& v : app->processes) update_info_mutable_cols(&v.second);
 }
 
 void
@@ -1151,7 +1139,7 @@ proctable_update (GsmApplication *app)
 void
 proctable_free_table (GsmApplication * const app)
 {
-    ProcInfo::all.clear();
+    app->processes.clear();
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]