libcamera: signal: Disconnect signal automatically on slot deletion
When a signal is connected to a member function slot, the slot is not disconnected when the slot object is deleted. This can lead to calling a member function of a deleted object if the signal isn't disconnected manually by the slot object's destructor. Make signal handling easier by implementing a base Object class that tracks all connected signals and disconnects from them automatically when the object is deleted, using template specialization resolution in the Signal class. As inheriting from the Object class may to a too harsh requirement for Signal usage in applications, keep the existing behaviour working if the slot doesn't inherit from the Object class. We may reconsider this later and require all slot objects to inherit from the Object class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
parent
73a1bea709
commit
98bd9cb8c9
8 changed files with 210 additions and 36 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include <libcamera/object.h>
|
||||
#include <libcamera/signal.h>
|
||||
|
||||
#include "test.h"
|
||||
|
@ -22,6 +23,15 @@ static void slotStatic(int value)
|
|||
valueStatic_ = value;
|
||||
}
|
||||
|
||||
class SlotObject : public Object
|
||||
{
|
||||
public:
|
||||
void slot()
|
||||
{
|
||||
valueStatic_ = 1;
|
||||
}
|
||||
};
|
||||
|
||||
class SignalTest : public Test
|
||||
{
|
||||
protected:
|
||||
|
@ -139,6 +149,33 @@ protected:
|
|||
return TestFail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test automatic disconnection on object deletion. Connect the
|
||||
* slot twice to ensure all instances are disconnected.
|
||||
*/
|
||||
signalVoid_.disconnect();
|
||||
|
||||
SlotObject *slotObject = new SlotObject();
|
||||
signalVoid_.connect(slotObject, &SlotObject::slot);
|
||||
signalVoid_.connect(slotObject, &SlotObject::slot);
|
||||
delete slotObject;
|
||||
valueStatic_ = 0;
|
||||
signalVoid_.emit();
|
||||
if (valueStatic_ != 0) {
|
||||
cout << "Signal disconnection on object deletion test failed" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that signal deletion disconnects objects. This shall
|
||||
* not generate any valgrind warning.
|
||||
*/
|
||||
Signal<> *signal = new Signal<>();
|
||||
slotObject = new SlotObject();
|
||||
signal->connect(slotObject, &SlotObject::slot);
|
||||
delete signal;
|
||||
delete slotObject;
|
||||
|
||||
return TestPass;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue