static void refresh_list (ProcData *procdata, const pid_t* pid_list, const guint n) { typedef std::list<ProcInfo*> ProcList; ProcList addition; GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree)); 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[info->pid] = info; addition.push_back(info); } update_info (procdata, info); } // Remove dead processes from the process list and from the // tree. children are queued to be readded at the right place // in the tree. const std::set<pid_t> pids(pid_list, pid_list + n); ProcInfo::Iterator it(ProcInfo::begin()); while (it != ProcInfo::end()) { ProcInfo * const info = it->second; ProcInfo::Iterator next(it); ++next; if (pids.find(info->pid) == pids.end()) { procman_debug("ripping %d", info->pid); remove_info_from_tree(procdata, model, info, addition); addition.remove(info); ProcInfo::all.erase(it); delete info; } it = next; } // INVARIANT // pid_list == ProcInfo::all + addition if (procdata->config.show_tree) { // insert process in the tree. walk through the addition list // (new process + process that have a new parent). This loop // handles the dependencies because we cannot insert a process // until its parent is in the tree. std::set<pid_t> in_tree(pids); for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it) in_tree.erase((*it)->pid); while (not addition.empty()) { procman_debug("looking for %d parents", int(addition.size())); ProcList::iterator it(addition.begin()); while (it != addition.end()) { procman_debug("looking for %d's parent with ppid %d", int((*it)->pid), int((*it)->ppid)); // inserts the process in the treeview if : // - it is init // - its parent is already in tree // - its parent is unreachable // // rounds == 2 means that addition contains processes with // unreachable parents // // FIXME: this is broken if the unreachable parent becomes active // i.e. it gets active or changes ower // so we just clear the tree on __each__ update // see proctable_update_list (ProcData * const procdata) if ((*it)->ppid == 0 or in_tree.find((*it)->ppid) != in_tree.end()) { insert_info_to_tree(*it, procdata); in_tree.insert((*it)->pid); it = addition.erase(it); continue; } ProcInfo *parent = ProcInfo::find((*it)->ppid); // if the parent is unreachable if (not parent) { // or std::find(addition.begin(), addition.end(), parent) == addition.end()) { insert_info_to_tree(*it, procdata, true); in_tree.insert((*it)->pid); it = addition.erase(it); continue; } ++it; } } } else { // don't care of the tree for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it) insert_info_to_tree(*it, procdata); } for (ProcInfo::Iterator it(ProcInfo::begin()); it != ProcInfo::end(); ++it) update_info_mutable_cols(it->second); }
static void refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n) { typedef std::list<ProcInfo*> ProcList; ProcList addition; GtkTreeModel *model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER ( gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT ( gtk_tree_view_get_model (GTK_TREE_VIEW(app->tree)))))); guint i; // Add or update processes in the process list for(i = 0; i < n; ++i) { ProcInfo *info = app->processes.find(pid_list[i]); if (!info) { info = app->processes.add(pid_list[i]); addition.push_back(info); } update_info (app, info); } // Remove dead processes from the process list and from the // tree. children are queued to be readded at the right place // in the tree. const std::set<pid_t> pids(pid_list, pid_list + n); 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 = app->processes.erase(it); } else { ++it; } } // INVARIANT // pid_list == ProcInfo::all + addition if (app->settings->get_boolean (GSM_SETTING_SHOW_DEPENDENCIES)) { // insert process in the tree. walk through the addition list // (new process + process that have a new parent). This loop // handles the dependencies because we cannot insert a process // until its parent is in the tree. std::set<pid_t> in_tree(pids); for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it) in_tree.erase((*it)->pid); while (not addition.empty()) { procman_debug("looking for %d parents", int(addition.size())); ProcList::iterator it(addition.begin()); while (it != addition.end()) { procman_debug("looking for %d's parent with ppid %d", int((*it)->pid), int((*it)->ppid)); // inserts the process in the treeview if : // - it has no parent (ppid = -1), // ie it is for example the [kernel] on FreeBSD // - it is init // - its parent is already in tree // - its parent is unreachable // // rounds == 2 means that addition contains processes with // unreachable parents // // FIXME: this is broken if the unreachable parent becomes active // i.e. it gets active or changes ower // so we just clear the tree on __each__ update // see proctable_update (ProcData * const procdata) if ((*it)->ppid <= 0 or in_tree.find((*it)->ppid) != in_tree.end()) { insert_info_to_tree(*it, app); in_tree.insert((*it)->pid); it = addition.erase(it); continue; } ProcInfo *parent = app->processes.find((*it)->ppid); // if the parent is unreachable if (not parent) { // or std::find(addition.begin(), addition.end(), parent) == addition.end()) { insert_info_to_tree(*it, app, true); in_tree.insert((*it)->pid); it = addition.erase(it); continue; } ++it; } } } else { // don't care of the tree for (auto& v : addition) insert_info_to_tree(v, app); } for (auto& v : app->processes) update_info_mutable_cols(&v.second); }