From e570224156a2ee843026bea97a5128389a962d8b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 1 Jul 2010 18:59:20 +0000 Subject: Ensure broker is deleted in main thread, not by global destructors. Finish the fix of r959661 by making it exception safe. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@959746 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/src/posix/QpiddBroker.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'qpid/cpp/src') diff --git a/qpid/cpp/src/posix/QpiddBroker.cpp b/qpid/cpp/src/posix/QpiddBroker.cpp index b340e3e52b..bc45b27a2a 100644 --- a/qpid/cpp/src/posix/QpiddBroker.cpp +++ b/qpid/cpp/src/posix/QpiddBroker.cpp @@ -107,6 +107,17 @@ void QpiddOptions::usage() const { cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl; } +// Set the broker pointer on the signal handler, then reset at end of scope. +// This is to ensure that the signal handler doesn't keep a broker +// reference after main() has returned. +// +struct ScopedSetBroker { + ScopedSetBroker(const boost::intrusive_ptr& broker) { + qpid::broker::SignalHandler::setBroker(broker); + } + ~ScopedSetBroker() { qpid::broker::SignalHandler::setBroker(0); } +}; + struct QpiddDaemon : public Daemon { QpiddPosixOptions *options; @@ -123,12 +134,11 @@ struct QpiddDaemon : public Daemon { /** Code for forked child process */ void child() { boost::intrusive_ptr brokerPtr(new Broker(options->parent->broker)); - qpid::broker::SignalHandler::setBroker(brokerPtr); + ScopedSetBroker ssb(brokerPtr); brokerPtr->accept(); uint16_t port=brokerPtr->getPort(options->daemon.transport); ready(port); // Notify parent. brokerPtr->run(); - broker::SignalHandler::setBroker(0); // Delete broker in this thread. } }; @@ -170,12 +180,11 @@ int QpiddBroker::execute (QpiddOptions *options) { } else { // Non-daemon broker. boost::intrusive_ptr brokerPtr(new Broker(options->broker)); - broker::SignalHandler::setBroker(brokerPtr); + ScopedSetBroker ssb(brokerPtr); brokerPtr->accept(); if (options->broker.port == 0 || myOptions->daemon.transport != TCP) cout << uint16_t(brokerPtr->getPort(myOptions->daemon.transport)) << endl; brokerPtr->run(); - broker::SignalHandler::setBroker(0); // Delete broker in this thread. } return 0; } -- cgit v1.2.1