mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:58:11 +00:00
Kernel: Fix GenericInterruptHandler problems with virtual functions
Because registering and unregistering interrupt handlers triggers calls to virtual functions, we can't do this in the constructor and destructor. Fixes #5539
This commit is contained in:
parent
183ebaee91
commit
32d9534c67
11 changed files with 112 additions and 39 deletions
|
@ -40,25 +40,50 @@ GenericInterruptHandler::GenericInterruptHandler(u8 interrupt_number, bool disab
|
|||
: m_interrupt_number(interrupt_number)
|
||||
, m_disable_remap(disable_remap)
|
||||
{
|
||||
// NOTE: We cannot register or unregister the handler while the object
|
||||
// is being constructed or deconstructed!
|
||||
}
|
||||
|
||||
void GenericInterruptHandler::will_be_destroyed()
|
||||
{
|
||||
// This will be called for RefCounted interrupt handlers before the
|
||||
// object is being destroyed. As soon as the destructor is invoked
|
||||
// it is no longer advisable to unregister the handler (which causes
|
||||
// calls to virtual functions), so let's do this right before
|
||||
// invoking it
|
||||
unregister_interrupt_handler();
|
||||
}
|
||||
|
||||
void GenericInterruptHandler::register_interrupt_handler()
|
||||
{
|
||||
if (m_registered)
|
||||
return;
|
||||
if (m_disable_remap)
|
||||
register_generic_interrupt_handler(m_interrupt_number, *this);
|
||||
else
|
||||
register_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(m_interrupt_number), *this);
|
||||
m_registered = true;
|
||||
}
|
||||
|
||||
GenericInterruptHandler::~GenericInterruptHandler()
|
||||
void GenericInterruptHandler::unregister_interrupt_handler()
|
||||
{
|
||||
if (!m_registered)
|
||||
return;
|
||||
if (m_disable_remap)
|
||||
unregister_generic_interrupt_handler(m_interrupt_number, *this);
|
||||
else
|
||||
unregister_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(m_interrupt_number), *this);
|
||||
m_registered = false;
|
||||
}
|
||||
|
||||
void GenericInterruptHandler::change_interrupt_number(u8 number)
|
||||
{
|
||||
VERIFY_INTERRUPTS_DISABLED();
|
||||
VERIFY(!m_disable_remap);
|
||||
unregister_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this);
|
||||
if (m_registered) {
|
||||
unregister_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this);
|
||||
m_registered = false;
|
||||
}
|
||||
m_interrupt_number = number;
|
||||
register_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue