We have been using shared_ptrs pretty successfully throughout our application, but I have run across something that has just completely stumped me. BTW - this is a Windows .NET 2003 + Intel 8.1 compiler compiling in Debug mode on a multi-processor machine (dual Xeon Dell workstation). The code in question is: void Router::routeEnvelope(shared_ptr<Envelope> envelope) { if(!running || !envelope) return; GUID target = envelope->getTo(); if(target == guid) { // PATH 1 // check to see if it is a failure envelope shared_ptr<EnvelopeFailure> envelopeFailure = shared_dynamic_cast<EnvelopeFailure>(envelope); if(envelopeFailure) { // there was a problem sending the original envelope failedEnvelope(envelopeFailure->getFrom()); } // pass it on up the stack envelopeController.injectEnvelope(envelope); } else { // PATH 2 mutex::scoped_lock lock(envelopeQueueMonitor); envelopeQueue.push(envelope); envelopeReady.notify_all(); } } The first envelope that comes in has a guid that matches target, so it takes code path 1. If I comment out both code path 1 and code path 2, the envelope is released properly, and I can see its destructor get called. Here is where it gets strange--if I uncomment anything in code path 2, and only code path 2, I no longer see the envelope get released, even though that code path is not executed at all. I've been doing this testing on an SMP machine. On a UP machine, the program runs fine without any issues. I am at a complete loss. The original envelope object is created in the function that calls this function, and as far as I can tell , is not touched by any other thread in the application. Thanks for any advice. Cheers, tim
"Timothy Ritchey"
We have been using shared_ptrs pretty successfully throughout our application, but I have run across something that has just completely stumped me. BTW - this is a Windows .NET 2003 + Intel 8.1 compiler compiling in Debug mode on a multi-processor machine (dual Xeon Dell workstation).
The code in question is:
void Router::routeEnvelope(shared_ptr<Envelope> envelope) {
if(!running || !envelope) return;
GUID target = envelope->getTo(); if(target == guid) { // PATH 1
// check to see if it is a failure envelope shared_ptr<EnvelopeFailure> envelopeFailure = shared_dynamic_cast<EnvelopeFailure>(envelope); if(envelopeFailure) { // there was a problem sending the original envelope failedEnvelope(envelopeFailure->getFrom()); }
I'm not sure if this will help, but the following will limit the scope of 'envelopeFailure'. This may be important if your code is reentrant through 'envelopeController.injectEnvelope'. I'm not sure what 'shared_dynamic_cast' is above, but assume you meant 'dynamic_pointer_cast'? if( shared_ptr<EnvelopeFailure> envelopeFailure = dynamic_pointer_cast<EnvelopeFailure>(envelope) ) { failedEnvelope( envelopeFailure->getFrom() ); }
// pass it on up the stack envelopeController.injectEnvelope(envelope);
} else { // PATH 2 mutex::scoped_lock lock(envelopeQueueMonitor); envelopeQueue.push(envelope); envelopeReady.notify_all(); } }
Jeff Flinn
On Aug 10, 2005, at 8:35 AM, Jeff Flinn wrote:
I'm not sure if this will help, but the following will limit the scope of 'envelopeFailure'. This may be important if your code is reentrant through 'envelopeController.injectEnvelope'. I'm not sure what 'shared_dynamic_cast' is above, but assume you meant 'dynamic_pointer_cast'?
if( shared_ptr<EnvelopeFailure> envelopeFailure = dynamic_pointer_cast<EnvelopeFailure>(envelope) ) { failedEnvelope( envelopeFailure->getFrom() ); }
Thank you for the pointer - that is a good recommendation for me. I know there are several places where I can benefit from that layout. I upgraded my intel compiler to 8.1.025 and the problem has gone away. Regarding the shared_dynamic_cast - that is what I have been using all along to perform the equivalent of a dynamic_cast on shared_ptr objects. I've never seen your version :-) I just did a google on it, and found out pretty quickly that I am using a deprecated cast function. I now have two things to thank you for! Cheers, tim
participants (2)
-
Jeff Flinn
-
Timothy Ritchey