Skip to content

Commit 31f11b6

Browse files
committed
Merge pull request #951 from spark/feature/interrupt_handler_leak
Free memory allocated for previous system interrupt handler
2 parents 4d84046 + d623ab8 commit 31f11b6

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

hal/src/stm32/system_interrupts.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ uint8_t HAL_Set_System_Interrupt_Handler(hal_irq_t irq, const HAL_InterruptCallb
2121
*previous = cb;
2222
if (callback)
2323
cb = *callback;
24-
else
24+
else {
2525
cb.handler = 0;
26+
cb.data = 0;
27+
}
2628

2729
return true;
2830
}

user/tests/wiring/no_fixture/interrupts.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,46 @@ test(interrupts_atomic_section)
3636

3737
assertMore(end_millis, start_millis);
3838
}
39+
40+
namespace
41+
{
42+
43+
class TestHandler
44+
{
45+
public:
46+
TestHandler()
47+
{
48+
++count;
49+
}
50+
51+
TestHandler(const TestHandler&)
52+
{
53+
++count;
54+
}
55+
56+
~TestHandler()
57+
{
58+
--count;
59+
}
60+
61+
void operator()()
62+
{
63+
}
64+
65+
static int count;
66+
};
67+
68+
} // namespace
69+
70+
int TestHandler::count = 0;
71+
72+
test(interrupts_detached_handler_is_destroyed)
73+
{
74+
assertEqual(TestHandler::count, 0);
75+
attachSystemInterrupt(SysInterrupt_SysTick, TestHandler());
76+
assertEqual(TestHandler::count, 1);
77+
attachSystemInterrupt(SysInterrupt_SysTick, TestHandler()); // Override current handler
78+
assertEqual(TestHandler::count, 1); // Previous handler has been destroyed
79+
detachSystemInterrupt(SysInterrupt_SysTick);
80+
assertEqual(TestHandler::count, 0);
81+
}

wiring/src/spark_wiring_interrupts.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ bool attachSystemInterrupt(hal_irq_t irq, wiring_interrupt_handler_t handler)
150150
callback.handler = call_wiring_interrupt_handler;
151151
wiring_interrupt_handler_t& h = handler;
152152
callback.data = new wiring_interrupt_handler_t(h);
153-
return HAL_Set_System_Interrupt_Handler(irq, &callback, NULL, NULL);
153+
HAL_InterruptCallback prev = { 0 };
154+
const bool ok = HAL_Set_System_Interrupt_Handler(irq, &callback, &prev, NULL);
155+
delete (wiring_interrupt_handler_t*)prev.data;
156+
return ok;
154157
}
155158

156159
/**
@@ -160,5 +163,8 @@ bool attachSystemInterrupt(hal_irq_t irq, wiring_interrupt_handler_t handler)
160163
*/
161164
bool detachSystemInterrupt(hal_irq_t irq)
162165
{
163-
return HAL_Set_System_Interrupt_Handler(irq, NULL, NULL, NULL);
166+
HAL_InterruptCallback prev = { 0 };
167+
const bool ok = HAL_Set_System_Interrupt_Handler(irq, NULL, &prev, NULL);
168+
delete (wiring_interrupt_handler_t*)prev.data;
169+
return ok;
164170
}

0 commit comments

Comments
 (0)