Find roots when constructing process tree, fix #587

This commit is contained in:
wangqr 2017-09-01 21:27:24 +08:00
parent 9487bda330
commit 584a9bceab
1 changed files with 38 additions and 16 deletions

View File

@ -213,23 +213,45 @@ void ProcessList_sort(ProcessList* this) {
// Restore settings // Restore settings
this->settings->sortKey = sortKey; this->settings->sortKey = sortKey;
this->settings->direction = direction; this->settings->direction = direction;
// Take PID 1 as root and add to the new listing
int vsize = Vector_size(this->processes); int vsize = Vector_size(this->processes);
Process* init = (Process*) (Vector_take(this->processes, 0)); // Find all processes whose parent is not visible
if (!init) return; int size;
// This assertion crashes on hardened kernels. while ((size = Vector_size(this->processes))) {
// I wonder how well tree view works on those systems. int i;
// assert(init->pid == 1); for (i = 0; i < size; i++) {
init->indent = 0; Process* process = (Process*)(Vector_get(this->processes, i));
Vector_add(this->processes2, init); // Immediately consume not shown processes
// Recursively empty list if (!process->show) {
ProcessList_buildTree(this, init->pid, 0, 0, direction, true); process = (Process*)(Vector_take(this->processes, i));
// Add leftovers process->indent = 0;
while (Vector_size(this->processes)) { Vector_add(this->processes2, process);
Process* p = (Process*) (Vector_take(this->processes, 0)); ProcessList_buildTree(this, process->pid, 0, 0, direction, false);
p->indent = 0; break;
Vector_add(this->processes2, p); }
ProcessList_buildTree(this, p->pid, 0, 0, direction, p->showChildren); pid_t ppid = process->tgid == process->pid ? process->ppid : process->tgid;
// Bisect the process vector to find parent
int l = 0, r = size;
while (l < r) {
int c = (l + r) / 2;
pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;
if (ppid == pid)
break;
else if (ppid < pid)
r = c;
else
l = c + 1;
}
// If parent not found, then construct the tree with this root
if (l >= r) {
process = (Process*)(Vector_take(this->processes, i));
process->indent = 0;
Vector_add(this->processes2, process);
ProcessList_buildTree(this, process->pid, 0, 0, direction, process->showChildren);
break;
}
}
// There should be no loop in the process tree
assert(i < size);
} }
assert(Vector_size(this->processes2) == vsize); (void)vsize; assert(Vector_size(this->processes2) == vsize); (void)vsize;
assert(Vector_size(this->processes) == 0); assert(Vector_size(this->processes) == 0);