You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by sh...@apache.org on 2008/10/29 20:45:18 UTC

svn commit: r708991 - in /incubator/qpid/trunk/qpid/cpp/src: Makefile.am posix/ posix/QpiddBroker.cpp qpidd.cpp qpidd.h windows/

Author: shuston
Date: Wed Oct 29 12:45:18 2008
New Revision: 708991

URL: http://svn.apache.org/viewvc?rev=708991&view=rev
Log:
Split platform-specific qpidd code out to posix/QpiddBroker.cpp; allows Windows port code to come in. Related to QPID-1338

Added:
    incubator/qpid/trunk/qpid/cpp/src/posix/
    incubator/qpid/trunk/qpid/cpp/src/posix/QpiddBroker.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpidd.h
    incubator/qpid/trunk/qpid/cpp/src/windows/
Modified:
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am
    incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=708991&r1=708990&r2=708991&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Wed Oct 29 12:45:18 2008
@@ -64,8 +64,10 @@
   libqpidbroker.la				\
   libqpidcommon.la
 
+posix_qpidd_src = posix/QpiddBroker.cpp
+
 sbin_PROGRAMS = qpidd
-qpidd_SOURCES = qpidd.cpp
+qpidd_SOURCES = qpidd.cpp $(posix_qpidd_src)
 
 posix_plat_src = \
   qpid/log/posix/SinkOptions.cpp \

Added: incubator/qpid/trunk/qpid/cpp/src/posix/QpiddBroker.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/posix/QpiddBroker.cpp?rev=708991&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/posix/QpiddBroker.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/posix/QpiddBroker.cpp Wed Oct 29 12:45:18 2008
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "qpidd.h"
+#include "qpid/Exception.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/broker/Daemon.h"
+#include "qpid/broker/SignalHandler.h"
+#include "qpid/log/Logger.h"
+
+#include <iostream>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+using namespace std;
+using namespace qpid;
+using qpid::broker::Broker;
+using qpid::broker::Daemon;
+
+BootstrapOptions::BootstrapOptions(const char* argv0)
+  : qpid::Options("Options"),
+    common("", CONF_FILE),
+    module(MODULE_DIR),
+    log(argv0)
+{
+    add(common);
+    add(module);
+    add(log);
+}
+
+struct DaemonOptions : public qpid::Options {
+    bool daemon;
+    bool quit;
+    bool check;
+    int wait;
+    std::string piddir;
+    std::string transport;
+
+    DaemonOptions() : qpid::Options("Daemon options"), daemon(false), quit(false), check(false), wait(10)
+    {
+        char *home = ::getenv("HOME");
+
+        if (home == 0)
+            piddir += "/tmp";
+        else
+            piddir += home;
+        piddir += "/.qpidd";
+
+        addOptions()
+            ("daemon,d", optValue(daemon), "Run as a daemon. --log-output defaults to syslog in this mode.")
+            ("transport", optValue(transport, "TRANSPORT"), "The transport for which to return the port")
+            ("pid-dir", optValue(piddir, "DIR"), "Directory where port-specific PID file is stored")
+            ("wait,w", optValue(wait, "SECONDS"), "Sets the maximum wait time to initialize the daemon. If the daemon fails to initialize, prints an error and returns 1")
+            ("check,c", optValue(check), "Prints the daemon's process ID to stdout and returns 0 if the daemon is running, otherwise returns 1")
+            ("quit,q", optValue(quit), "Tells the daemon to shut down");
+    }
+};
+
+struct QpiddPosixOptions : public QpiddOptionsPrivate {
+    DaemonOptions daemon;
+    QpiddOptions *parent;
+
+    QpiddPosixOptions(QpiddOptions *parent_) : parent(parent_) {
+        parent->add(daemon);
+    }
+};
+
+QpiddOptions::QpiddOptions(const char* argv0)
+  : qpid::Options("Options"),
+    common("", CONF_FILE),
+    module(MODULE_DIR),
+    log(argv0)
+{
+    add(common);
+    add(module);
+    add(broker);
+    add(log);
+
+    platform.reset(new QpiddPosixOptions(this));
+    qpid::Plugin::addOptions(*this);
+}
+
+void QpiddOptions::usage() const {
+    cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl;
+}
+
+struct QpiddDaemon : public Daemon {
+    QpiddPosixOptions *options;
+  
+    QpiddDaemon(std::string pidDir, QpiddPosixOptions *opts)
+      : Daemon(pidDir), options(opts) {}
+
+    /** Code for parent process */
+    void parent() {
+        uint16_t port = wait(options->daemon.wait);
+        if (options->parent->broker.port == 0 || !options->daemon.transport.empty())
+            cout << port << endl; 
+    }
+
+    /** Code for forked child process */
+    void child() {
+        boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->parent->broker));
+        qpid::broker::SignalHandler::setBroker(brokerPtr);
+        uint16_t port=brokerPtr->getPort(options->daemon.transport);
+        ready(port);            // Notify parent.
+        brokerPtr->run();
+    }
+};
+
+int QpiddBroker::execute (QpiddOptions *options) {
+    // Options that affect a running daemon.
+    QpiddPosixOptions *myOptions =
+      static_cast<QpiddPosixOptions *>(options->platform.get());
+    if (myOptions == 0)
+        throw Exception("Internal error obtaining platform options");
+
+    if (myOptions->daemon.check || myOptions->daemon.quit) {
+        pid_t pid = Daemon::getPid(myOptions->daemon.piddir,
+                                   options->broker.port);
+        if (pid < 0) 
+            return 1;
+        if (myOptions->daemon.check)
+            cout << pid << endl;
+        if (myOptions->daemon.quit && kill(pid, SIGINT) < 0)
+          throw Exception("Failed to stop daemon: " + qpid::sys::strError(errno));
+        return 0;
+    }
+
+    // Starting the broker.
+    if (myOptions->daemon.daemon) {
+        // For daemon mode replace default stderr with syslog.
+        options->log.sinkOptions->detached();
+        qpid::log::Logger::instance().configure(options->log);
+        // Fork the daemon
+        QpiddDaemon d(myOptions->daemon.piddir, myOptions);
+        d.fork();           // Broker is stared in QpiddDaemon::child()
+    }
+    else {                  // Non-daemon broker.
+        boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker));
+        broker::SignalHandler::setBroker(brokerPtr);
+        if (options->broker.port == 0 || !myOptions->daemon.transport.empty())
+            cout << uint16_t(brokerPtr->getPort(myOptions->daemon.transport)) << endl;
+        brokerPtr->run();
+    }
+    return 0;
+}

Modified: incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp?rev=708991&r1=708990&r2=708991&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp Wed Oct 29 12:45:18 2008
@@ -18,166 +18,19 @@
  * under the License.
  *
  */
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/SignalHandler.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/broker/Daemon.h"
-#include "qpid/log/Statement.h"
-#include "qpid/log/Options.h"
-#include "qpid/log/Logger.h"
+
+#include "qpidd.h"
 #include "qpid/Plugin.h"
 #include "qpid/Version.h"
+#include "qpid/log/Logger.h"
 #include "qpid/sys/Shlib.h"
-#include "config.h"
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+
 #include <iostream>
-#include <fstream>
-#include <signal.h>
-#include <unistd.h>
-
-using namespace qpid;
-using namespace qpid::broker;
-using namespace qpid::sys;
-using namespace qpid::log;
+#include <memory>
 using namespace std;
-namespace fs=boost::filesystem;
-
-struct ModuleOptions : public qpid::Options {
-    string         loadDir;
-    vector<string> load;
-    bool           noLoad;
-    ModuleOptions() : qpid::Options("Module options"), loadDir(MODULE_DIR), noLoad(false)
-    {
-        addOptions()
-            ("module-dir",    optValue(loadDir, "DIR"),  "Load all .so modules in this directory")
-            ("load-module",   optValue(load,    "FILE"), "Specifies additional module(s) to be loaded")
-            ("no-module-dir", optValue(noLoad),          "Don't load modules from module directory");
-    }
-};
-
-
-struct DaemonOptions : public qpid::Options {
-    bool daemon;
-    bool quit;
-    bool check;
-    int wait;
-    std::string piddir;
-    std::string transport;
-
-    DaemonOptions() : qpid::Options("Daemon options"), daemon(false), quit(false), check(false), wait(10)
-    {
-        char *home = ::getenv("HOME");
-
-        if (home == 0)
-            piddir += "/tmp";
-        else
-            piddir += home;
-        piddir += "/.qpidd";
-
-        addOptions()
-            ("daemon,d", optValue(daemon), "Run as a daemon. --log-output defaults to syslog in this mode.")
-            ("transport", optValue(transport, "TRANSPORT"), "The transport for which to return the port")
-            ("pid-dir", optValue(piddir, "DIR"), "Directory where port-specific PID file is stored")
-            ("wait,w", optValue(wait, "SECONDS"), "Sets the maximum wait time to initialize the daemon. If the daemon fails to initialize, prints an error and returns 1")
-            ("check,c", optValue(check), "Prints the daemon's process ID to stdout and returns 0 if the daemon is running, otherwise returns 1")
-            ("quit,q", optValue(quit), "Tells the daemon to shut down");
-    }
-};
-
-
-struct QpiddOptions : public qpid::Options {
-    CommonOptions common;
-    ModuleOptions module;
-    Broker::Options broker;
-    DaemonOptions daemon;
-    qpid::log::Options log;
-    
-    QpiddOptions(const char* argv0) : qpid::Options("Options"), common("", CONF_FILE), log(argv0) {
-        add(common);
-        add(module);
-        add(broker);
-        add(daemon);
-        add(log);
-        Plugin::addOptions(*this);
-    }
-
-    void usage() const {
-        cout << "Usage: qpidd [OPTIONS]" << endl << endl << *this << endl;
-    };
-};
-
-// BootstrapOptions is a minimal subset of options used for a pre-parse
-// of the command line to discover which plugin modules need to be loaded.
-// The pre-parse is necessary because plugin modules may supply their own
-// set of options.  CommonOptions is needed to properly support loading
-// from a configuration file.
-struct BootstrapOptions : public qpid::Options {
-    CommonOptions common;
-    ModuleOptions module;
-    qpid::log::Options log;     
-
-    BootstrapOptions(const char* argv0) : qpid::Options("Options"), common("", CONF_FILE), log(argv0) {
-        add(common);
-        add(module);
-        add(log);
-    }
-};
 
 auto_ptr<QpiddOptions> options;
 
-struct QpiddDaemon : public Daemon {
-    QpiddDaemon(std::string pidDir) : Daemon(pidDir) {}
-
-    /** Code for parent process */
-    void parent() {
-        uint16_t port = wait(options->daemon.wait);
-        if (options->broker.port == 0 || !options->daemon.transport.empty())
-            cout << port << endl; 
-    }
-
-    /** Code for forked child process */
-    void child() {
-        boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker));
-        broker::SignalHandler::setBroker(brokerPtr);
-        uint16_t port=brokerPtr->getPort(options->daemon.transport);
-        ready(port);            // Notify parent.
-        brokerPtr->run();
-    }
-};
-
-void tryShlib(const char* libname, bool noThrow) {
-    try {
-        Shlib shlib(libname);
-        QPID_LOG (info, "Loaded Module: " << libname);
-    }
-    catch (const exception& e) {
-        if (!noThrow)
-            throw;
-    }
-}
-
-void loadModuleDir (string dirname, bool isDefault)
-{
-    fs::path dirPath (dirname, fs::native);
-
-    if (!fs::exists (dirPath))
-    {
-        if (isDefault)
-            return;
-        throw Exception ("Directory not found: " + dirname);
-    }
-
-    fs::directory_iterator endItr;
-    for (fs::directory_iterator itr (dirPath); itr != endItr; ++itr)
-    {
-        if (!fs::is_directory(*itr) &&
-            itr->string().find (".so") == itr->string().length() - 3)
-            tryShlib (itr->string().data(), true);
-    }
-}
-  
-
 int main(int argc, char* argv[])
 {
     try
@@ -185,20 +38,21 @@
         {
             BootstrapOptions bootOptions(argv[0]);
             string           defaultPath (bootOptions.module.loadDir);
-            // Parse only the common, load, and log options to see which modules need
-            // to be loaded.  Once the modules are loaded, the command line will
-            // be re-parsed with all of the module-supplied options.
+            // Parse only the common, load, and log options to see which
+            // modules need to be loaded.  Once the modules are loaded,
+            // the command line will be re-parsed with all of the
+            // module-supplied options.
             bootOptions.parse (argc, argv, bootOptions.common.config, true);
             qpid::log::Logger::instance().configure(bootOptions.log);
 
             for (vector<string>::iterator iter = bootOptions.module.load.begin();
                  iter != bootOptions.module.load.end();
                  iter++)
-                tryShlib (iter->data(), false);
+                qpid::tryShlib (iter->data(), false);
 
             if (!bootOptions.module.noLoad) {
                 bool isDefault = defaultPath == bootOptions.module.loadDir;
-                loadModuleDir (bootOptions.module.loadDir, isDefault);
+                qpid::loadModuleDir (bootOptions.module.loadDir, isDefault);
             }
         }
 
@@ -207,7 +61,7 @@
         options->parse(argc, argv, options->common.config);
 
         // Options that just print information.
-        if(options->common.help || options->common.version) {
+        if (options->common.help || options->common.version) {
             if (options->common.version) 
                 cout << "qpidd (" << qpid::product << ") version "
                      << qpid::version << endl;
@@ -216,35 +70,10 @@
             return 0;
         }
 
-        // Options that affect a running daemon.
-        if (options->daemon.check || options->daemon.quit) {
-            pid_t pid = Daemon::getPid(options->daemon.piddir, options->broker.port);
-            if (pid < 0) 
-                return 1;
-            if (options->daemon.check)
-                cout << pid << endl;
-            if (options->daemon.quit && kill(pid, SIGINT) < 0)
-                throw Exception("Failed to stop daemon: " + strError(errno));
-            return 0;
-        }
-
-        // Starting the broker.
-        if (options->daemon.daemon) {
-            // For daemon mode replace default stderr with syslog.
-            options->log.sinkOptions->detached();
-            qpid::log::Logger::instance().configure(options->log);
-            // Fork the daemon
-            QpiddDaemon d(options->daemon.piddir);
-            d.fork();           // Broker is stared in QpiddDaemon::child()
-        } 
-        else {                  // Non-daemon broker.
-            boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker));
-            broker::SignalHandler::setBroker(brokerPtr);
-            if (options->broker.port == 0 || !options->daemon.transport.empty())
-                cout << uint16_t(brokerPtr->getPort(options->daemon.transport)) << endl; 
-            brokerPtr->run();
-        }
-        return 0;
+        // Everything else is driven by the platform-specific broker
+        // logic.
+        QpiddBroker broker;
+        return broker.execute(options.get());
     }
     catch(const exception& e) {
         cerr << e.what() << endl;

Added: incubator/qpid/trunk/qpid/cpp/src/qpidd.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpidd.h?rev=708991&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpidd.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpidd.h Wed Oct 29 12:45:18 2008
@@ -0,0 +1,70 @@
+#ifndef QPID_H
+#define QPID_H
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "qpid/Modules.h"
+#include "qpid/Options.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/log/Options.h"
+
+#include <memory>
+
+// BootstrapOptions is a minimal subset of options used for a pre-parse
+// of the command line to discover which plugin modules need to be loaded.
+// The pre-parse is necessary because plugin modules may supply their own
+// set of options.  CommonOptions is needed to properly support loading
+// from a configuration file.
+struct BootstrapOptions : public qpid::Options {
+    qpid::CommonOptions common;
+    qpid::ModuleOptions module;
+    qpid::log::Options log;     
+
+    BootstrapOptions(const char *argv0);
+};
+
+// Each platform derives an options struct from QpiddOptionsPrivate, adding
+// platform-specific option types. QpiddOptions needs to allocation one of
+// these derived structs from its constructor.
+struct QpiddOptions;
+struct QpiddOptionsPrivate {
+    QpiddOptions *options;
+    QpiddOptionsPrivate(QpiddOptions *parent) : options(parent) {}
+    virtual ~QpiddOptionsPrivate() {}
+protected:
+    QpiddOptionsPrivate() {}
+};
+
+struct QpiddOptions : public qpid::Options {
+    qpid::CommonOptions common;
+    qpid::ModuleOptions module;
+    qpid::broker::Broker::Options broker;
+    qpid::log::Options log;
+    std::auto_ptr<QpiddOptionsPrivate> platform;
+
+    QpiddOptions(const char *argv0);
+    void usage() const;
+};
+
+class QpiddBroker {
+public:
+    int execute (QpiddOptions *options);
+};
+
+#endif  /*!QPID_H*/