mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:58:11 +00:00
Kernel: Handle removal of Process from list before unref
This makes the following scenario impossible with an SMP setup: 1) CPU A enters unref() and decrements the link count to 0. 2) CPU B sees the process in the process list and ref()s it. 3) CPU A removes the process from the list and continues destructing. 4) CPU B is now holding a destructed Process object. By holding the process list lock before doing anything with it, we ensure that other CPUs can't find this process in the middle of it being destructed.
This commit is contained in:
parent
2830a0ecda
commit
18f260b78b
2 changed files with 19 additions and 5 deletions
|
@ -295,11 +295,23 @@ Process::~Process()
|
|||
VERIFY(!m_alarm_timer);
|
||||
|
||||
PerformanceManager::add_process_exit_event(*this);
|
||||
}
|
||||
|
||||
if (m_list_node.is_in_list())
|
||||
processes().with_exclusive([&](auto& list) {
|
||||
list.remove(*this);
|
||||
});
|
||||
bool Process::unref() const
|
||||
{
|
||||
// NOTE: We need to obtain the process list lock before doing anything,
|
||||
// because otherwise someone might get in between us lowering the
|
||||
// refcount and acquiring the lock.
|
||||
return processes().with_exclusive([&](auto& list) {
|
||||
auto new_ref_count = deref_base();
|
||||
if (new_ref_count > 0)
|
||||
return false;
|
||||
|
||||
if (m_list_node.is_in_list())
|
||||
list.remove(*const_cast<Process*>(this));
|
||||
delete this;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure the compiler doesn't "optimize away" this function:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue