libcamera: bound_method: Manage BoundMethodPack through std::shared_ptr

The bound method arguments pack will need to be accessed by the method
invoker in order to retrieve the method return value when using a
blocking connection type. We thus can't delete the pack unconditionally
in the bound method target thread. We also can't delete it
unconditionally in the invoker's thread, as for queued connections the
pack will be used in the target thread after the invoker completes.

This shows that ownership of the arguments pack is shared between two
contexts. As a result, manage it using std::shared_ptr<>.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Laurent Pinchart 2020-01-04 04:18:05 +02:00
parent 621edb2367
commit b0135a1522
5 changed files with 43 additions and 27 deletions

View file

@ -48,7 +48,8 @@ namespace libcamera {
* deadlock will occur.
*/
void BoundMethodBase::activatePack(void *pack, bool deleteMethod)
void BoundMethodBase::activatePack(std::shared_ptr<BoundMethodPackBase> pack,
bool deleteMethod)
{
ConnectionType type = connectionType_;
if (type == ConnectionTypeAuto) {
@ -61,7 +62,7 @@ void BoundMethodBase::activatePack(void *pack, bool deleteMethod)
switch (type) {
case ConnectionTypeDirect:
default:
invokePack(pack);
invokePack(pack.get());
if (deleteMethod)
delete this;
break;

View file

@ -48,7 +48,8 @@ private:
class InvokeMessage : public Message
{
public:
InvokeMessage(BoundMethodBase *method, void *pack,
InvokeMessage(BoundMethodBase *method,
std::shared_ptr<BoundMethodPackBase> pack,
Semaphore *semaphore = nullptr,
bool deleteMethod = false);
~InvokeMessage();
@ -59,7 +60,7 @@ public:
private:
BoundMethodBase *method_;
void *pack_;
std::shared_ptr<BoundMethodPackBase> pack_;
Semaphore *semaphore_;
bool deleteMethod_;
};

View file

@ -123,7 +123,8 @@ Message::Type Message::registerMessageType()
* \param[in] deleteMethod True to delete the \a method when the message is
* destroyed
*/
InvokeMessage::InvokeMessage(BoundMethodBase *method, void *pack,
InvokeMessage::InvokeMessage(BoundMethodBase *method,
std::shared_ptr<BoundMethodPackBase> pack,
Semaphore *semaphore, bool deleteMethod)
: Message(Message::InvokeMessage), method_(method), pack_(pack),
semaphore_(semaphore), deleteMethod_(deleteMethod)
@ -148,7 +149,7 @@ InvokeMessage::~InvokeMessage()
*/
void InvokeMessage::invoke()
{
method_->invokePack(pack_);
method_->invokePack(pack_.get());
}
/**