mirror of https://github.com/xzeldon/htop.git
Find roots when constructing process tree, fix #587
This commit is contained in:
parent
9487bda330
commit
584a9bceab
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue