Commit 35d69c72 authored by Artem Vorotnikov's avatar Artem Vorotnikov Committed by Robert Roth

ProcInfos owned by ProcInfo::all, ProcInfo::find returns references now

Signed-off-by: Artem Vorotnikov's avatarArtem Vorotnikov <artem@vorotnikov.me>

https://bugzilla.gnome.org/show_bug.cgi?id=776653
parent e9173fbc
......@@ -142,10 +142,10 @@ class ProcInfo
// 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;
typedef std::map<pid_t, ProcInfo> List;
static List all;
static ProcInfo* find(pid_t pid);
static ProcInfo& find(pid_t pid);
ProcInfo(pid_t pid);
......
......@@ -143,7 +143,7 @@ namespace
unsigned count = 0;
for (const auto& v : ProcInfo::all) {
const auto& info = *v.second;
const auto& info = v.second;
MatchSet matches;
lsof.search(info, std::inserter(matches, matches.begin()));
count += matches.size();
......
......@@ -177,10 +177,9 @@ update_openfiles_dialog (GsmTreeView *tree)
guint i;
pid_t pid = GPOINTER_TO_UINT(static_cast<pid_t*>(g_object_get_data (G_OBJECT (tree), "selected_info")));
info = ProcInfo::find(pid);
if (!info)
return;
try {
info = &ProcInfo::find(pid);
} catch (const std::out_of_range&) { return; }
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
......
......@@ -104,13 +104,15 @@ 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 */
if (ProcInfo* info = ProcInfo::find(pid))
try {
auto& info = ProcInfo::find(pid);
{
info->set_icon(icon);
info.set_icon(icon);
// move the ref to the map
this->apps[pid] = icon;
procman_debug("WNCK OK for %u", unsigned(pid));
}
} catch (const std::out_of_range& e) {}
}
......
......@@ -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")));
info = ProcInfo::find(pid);
try { info = &ProcInfo::find(pid); } catch (const std::out_of_range&) { info = nullptr; }
fill_proc_properties(tree, info);
}
......
......@@ -67,9 +67,9 @@ ProcInfo::List ProcInfo::all;
std::map<pid_t, guint64> ProcInfo::cpu_times;
ProcInfo* ProcInfo::find(pid_t pid)
ProcInfo& ProcInfo::find(pid_t pid)
{
try { return all.at(pid); } catch (const std::out_of_range& e) { return nullptr; }
return all.at(pid);
}
static void
......@@ -199,7 +199,7 @@ cb_refresh_icons (GtkIconTheme *theme, gpointer data)
}
for (auto& v : ProcInfo::all) {
app->pretty_table->set_icon(*v.second);
app->pretty_table->set_icon(v.second);
}
cb_timeout(app);
......@@ -785,7 +785,7 @@ insert_info_to_tree (ProcInfo *info, GsmApplication *app, bool forced = false)
ProcInfo *parent = 0;
if (not forced)
parent = ProcInfo::find(info->ppid);
try { parent = &ProcInfo::find(info->ppid); } catch (const std::out_of_range&) { parent = nullptr; }
if (parent) {
GtkTreePath *parent_node = gtk_tree_model_get_path(model, &parent->node);
......@@ -834,33 +834,33 @@ insert_info_to_tree (ProcInfo *info, GsmApplication *app, bool forced = false)
template<typename List>
static void
remove_info_from_tree (GsmApplication *app, GtkTreeModel *model,
ProcInfo *current, List &orphans, unsigned lvl = 0)
ProcInfo& current, List &orphans, unsigned lvl = 0)
{
GtkTreeIter child_node;
if (std::find(orphans.begin(), orphans.end(), current) != orphans.end()) {
procman_debug("[%u] %d already removed from tree", lvl, int(current->pid));
if (std::find(orphans.begin(), orphans.end(), &current) != orphans.end()) {
procman_debug("[%u] %d already removed from tree", lvl, int(current.pid));
return;
}
procman_debug("[%u] pid %d, %d children", lvl, int(current->pid),
gtk_tree_model_iter_n_children(model, &current->node));
procman_debug("[%u] pid %d, %d children", lvl, int(current.pid),
gtk_tree_model_iter_n_children(model, &current.node));
// it is not possible to iterate&erase over a treeview so instead we
// just pop one child after another and recursively remove it and
// its children
while (gtk_tree_model_iter_children(model, &child_node, &current->node)) {
while (gtk_tree_model_iter_children(model, &child_node, &current.node)) {
ProcInfo *child = 0;
gtk_tree_model_get(model, &child_node, COL_POINTER, &child, -1);
remove_info_from_tree(app, model, child, orphans, lvl + 1);
remove_info_from_tree(app, model, *child, orphans, lvl + 1);
}
g_assert(not gtk_tree_model_iter_has_child(model, &current->node));
g_assert(not gtk_tree_model_iter_has_child(model, &current.node));
orphans.push_back(current);
gtk_tree_store_remove(GTK_TREE_STORE(model), &current->node);
procman::poison(current->node, 0x69);
orphans.push_back(&current);
gtk_tree_store_remove(GTK_TREE_STORE(model), &current.node);
procman::poison(current.node, 0x69);
}
......@@ -977,13 +977,12 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
guint i;
// Add or update processes in the process list
for(i = 0; i < n; ++i) {
ProcInfo *info = ProcInfo::find(pid_list[i]);
if (!info) {
info = new ProcInfo(pid_list[i]);
ProcInfo::all.erase(info->pid);
ProcInfo::all.insert({info->pid, info});
for (i = 0; i < n; ++i) {
ProcInfo* info;
try {
info = &ProcInfo::find(pid_list[i]);
} catch (const std::out_of_range&) {
info = &ProcInfo::all.emplace(pid_list[i], pid_list[i]).first->second;
addition.push_back(info);
}
......@@ -997,19 +996,18 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
const std::set<pid_t> pids(pid_list, pid_list + n);
ProcInfo::List new_set;
for (const auto& v : ProcInfo::all) {
auto& info = v.second;
if (pids.find(info->pid) == pids.end()) {
procman_debug("ripping %d", info->pid);
auto it = std::begin(ProcInfo::all);
while (it != std::end(ProcInfo::all)) {
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);
delete info;
addition.remove(&info);
it = ProcInfo::all.erase(it);
} else {
new_set.insert({info->pid, info});
++it;
}
}
ProcInfo::all = new_set;
// INVARIANT
// pid_list == ProcInfo::all + addition
......@@ -1060,7 +1058,8 @@ refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
continue;
}
ProcInfo *parent = ProcInfo::find((*it)->ppid);
ProcInfo* parent;
try { parent = &ProcInfo::find((*it)->ppid); } catch (const std::out_of_range&) { parent = nullptr; }
// if the parent is unreachable
if (not parent) {
// or std::find(addition.begin(), addition.end(), parent) == addition.end()) {
......@@ -1080,7 +1079,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 : ProcInfo::all) update_info_mutable_cols(&v.second);
}
void
......@@ -1152,9 +1151,6 @@ proctable_update (GsmApplication *app)
void
proctable_free_table (GsmApplication * const app)
{
for (auto& v : ProcInfo::all)
delete v.second;
ProcInfo::all.clear();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment