Re: Openmama Documentation for subscription onDestroy
Duane Pauls <Duane.Pauls@...>
I’ll add a bit of clarification to the problem with the CPP interface if the middleware bridge queues an event to call the onDestroy callback.
When an application destructs a MamaSubscription object, the application onDestroy is called inline, and the MamaSubscription object is freed, but the corresponding MamaSubscriptionImpl object is not freed. So far so good – it is the MamaSubscriptionImpl object pointer that is the closure to the C-layer and this is still valid, unfreed memory. However, at this point the MamaSubscriptionImpl object’s mCallback pointer still points to the application’s MamaSubscriptionCallback object. The application may have freed this memory since MamaSubscriptionCallback::onDestroy() has been called.
If we look at MamdaSubscription as an example, it in fact does not implement MamaSubscriptionCallback::onDestroy at all. It will always destroy the callback (MamdaSubscription::mImpl) immediately after destroying the underlying MamaSubscription. This happens to occur after onDestroy is called since it is called inline with MamaSubscription::~MamaSubscription. But nevertheless, it is freed immediately after onDestroy is called inline with the call to MamaSubscription::~MamaSubscription().
Now, sometime later, the C-layer onDestroy is called. This calls the static MamaSubscription::onSubscriptionDestroy which calls MamaSubscriptionImpl::InvokeDestroy(). This checks if MamaSubscriptionImpl::mCallback is NULL (it is not – in the case of a MamdaSubscription it is still pointing to a freed MamdaSubscriptionImpl object) and tries to invoke the onDestroy() method. If the vtable pointer is no longer valid, a core here is quite likely.
Even if a core does not occur, the application would see onDestroy() twice – once inline with when the destroy was started and a second time when the lower layer destroy was completed. It seems the design intent here is to decouple the MamaSubscriptionImpl from everything above it when the MamaSubscription is destroyed. To do this, it seems the right thing to do in the C++ layer would be to set MamaSubscriptionImpl::mCallback to NULL when setting MamaSubscriptionImpl::mFreed to true (or alternatively include mFreed in the tests that check mCallback == NULL).
Should a bug be raised for this issue? Or should a middleware bridge in fact NOT enqueue the onDestroy callback as stated in the OpenMAMA Bridge Documentation Wiki and instead invoke onDestroy inline? If the intent is to always invoke the callback inline, it seems the benefit of having a callback in the first place is diminished.
From: Christopher Morgan
Sent: Thursday, January 28, 2016 10:30 AM
Subject: Openmama Documentation for subscription onDestroy
I’m with solace dev for the openmama middle bridge and I have question about mamaSubscription onDestroy with the CPP openmama. On the openmama Developer Wiki under Bridge Documentation for myMiddlewareBridgeMamaSubscription_destroy () it states “…the destroy method adds an event to the queue to invokes the destroy callback, which notifies the client application of the successful destroy of the subscription.” Our Bridge currently does this but in the CPP API for openmama the MamaSubscription seems to do an inline onDestroy as a part of the destructor. This does not work well with the enqueuerd onDestroy callback (potential for causing segmentation faults). I’ve also compared to the Qpid bridge which seems to do an inline onDestroy callback as a part their MiddlewareBridgeMamaSubscription_destroy(). Should the onDestroy callback be inline the MiddlewareBridgeMamaSubscription_destroy() like the Qpid to work with the CPP API? Or Is there a problem with the CPP API?