From a1d7ab43b461841b390be3171c4f4f77ffea0357 Mon Sep 17 00:00:00 2001 From: Sergey Polyakov Date: Sun, 10 Apr 2016 13:21:06 +0200 Subject: [PATCH 1/2] Free memory allocated for previous system interrupt handler --- hal/src/stm32/system_interrupts.cpp | 4 +++- wiring/src/spark_wiring_interrupts.cpp | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hal/src/stm32/system_interrupts.cpp b/hal/src/stm32/system_interrupts.cpp index 7f9969c26f..03d85bc21f 100644 --- a/hal/src/stm32/system_interrupts.cpp +++ b/hal/src/stm32/system_interrupts.cpp @@ -21,8 +21,10 @@ uint8_t HAL_Set_System_Interrupt_Handler(hal_irq_t irq, const HAL_InterruptCallb *previous = cb; if (callback) cb = *callback; - else + else { cb.handler = 0; + cb.data = 0; + } return true; } diff --git a/wiring/src/spark_wiring_interrupts.cpp b/wiring/src/spark_wiring_interrupts.cpp index a40565a559..ff5e7e6c7e 100644 --- a/wiring/src/spark_wiring_interrupts.cpp +++ b/wiring/src/spark_wiring_interrupts.cpp @@ -150,7 +150,10 @@ bool attachSystemInterrupt(hal_irq_t irq, wiring_interrupt_handler_t handler) callback.handler = call_wiring_interrupt_handler; wiring_interrupt_handler_t& h = handler; callback.data = new wiring_interrupt_handler_t(h); - return HAL_Set_System_Interrupt_Handler(irq, &callback, NULL, NULL); + HAL_InterruptCallback prev = { 0 }; + const bool ok = HAL_Set_System_Interrupt_Handler(irq, &callback, &prev, NULL); + delete (wiring_interrupt_handler_t*)prev.data; + return ok; } /** @@ -160,5 +163,8 @@ bool attachSystemInterrupt(hal_irq_t irq, wiring_interrupt_handler_t handler) */ bool detachSystemInterrupt(hal_irq_t irq) { - return HAL_Set_System_Interrupt_Handler(irq, NULL, NULL, NULL); + HAL_InterruptCallback prev = { 0 }; + const bool ok = HAL_Set_System_Interrupt_Handler(irq, NULL, &prev, NULL); + delete (wiring_interrupt_handler_t*)prev.data; + return ok; } From d623ab89ebc1da80d2a4d1f5a67a6888e12f44b6 Mon Sep 17 00:00:00 2001 From: Sergey Polyakov Date: Wed, 13 Apr 2016 00:57:08 +0200 Subject: [PATCH 2/2] Unit test --- user/tests/wiring/no_fixture/interrupts.cpp | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/user/tests/wiring/no_fixture/interrupts.cpp b/user/tests/wiring/no_fixture/interrupts.cpp index 3de53aa866..84a284bc7e 100644 --- a/user/tests/wiring/no_fixture/interrupts.cpp +++ b/user/tests/wiring/no_fixture/interrupts.cpp @@ -36,3 +36,46 @@ test(interrupts_atomic_section) assertMore(end_millis, start_millis); } + +namespace +{ + +class TestHandler +{ +public: + TestHandler() + { + ++count; + } + + TestHandler(const TestHandler&) + { + ++count; + } + + ~TestHandler() + { + --count; + } + + void operator()() + { + } + + static int count; +}; + +} // namespace + +int TestHandler::count = 0; + +test(interrupts_detached_handler_is_destroyed) +{ + assertEqual(TestHandler::count, 0); + attachSystemInterrupt(SysInterrupt_SysTick, TestHandler()); + assertEqual(TestHandler::count, 1); + attachSystemInterrupt(SysInterrupt_SysTick, TestHandler()); // Override current handler + assertEqual(TestHandler::count, 1); // Previous handler has been destroyed + detachSystemInterrupt(SysInterrupt_SysTick); + assertEqual(TestHandler::count, 0); +}