summaryrefslogtreecommitdiff
path: root/cpp/src/windows
diff options
context:
space:
mode:
authorAndrew Stitcher <astitcher@apache.org>2009-12-15 18:24:02 +0000
committerAndrew Stitcher <astitcher@apache.org>2009-12-15 18:24:02 +0000
commitfaf8a3a3a9f2355ec7044144d63ef869788eebb3 (patch)
treef8f1d22ceb1a04d44f2353fcc352fdeafeafbbad /cpp/src/windows
parenta66973a94f41bc034d98d39028e13cbbff805b93 (diff)
downloadqpid-python-faf8a3a3a9f2355ec7044144d63ef869788eebb3.tar.gz
QPID-1951: Removed need for Windows versions of ssize_t and pid_t
- Trivially removed Windows uses of ssize_t - Rearchitected how the Windows port finds an existing qpidd to stop it - Split Posix Lockfile functionality using pids into a new PidFile class git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@890929 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/windows')
-rw-r--r--cpp/src/windows/QpiddBroker.cpp191
1 files changed, 119 insertions, 72 deletions
diff --git a/cpp/src/windows/QpiddBroker.cpp b/cpp/src/windows/QpiddBroker.cpp
index fc4f9f8a92..15380dda0b 100644
--- a/cpp/src/windows/QpiddBroker.cpp
+++ b/cpp/src/windows/QpiddBroker.cpp
@@ -34,7 +34,6 @@ const char *QPIDD_MODULE_DIR = ".";
#include "qpid/Options.h"
#include "qpid/Plugin.h"
#include "qpid/sys/IntegerTypes.h"
-#include "qpid/sys/LockFile.h"
#include "qpid/sys/windows/check.h"
#include "qpid/broker/Broker.h"
@@ -59,74 +58,68 @@ namespace {
const std::string TCP = "tcp";
-std::string brokerPidFile(std::string piddir, uint16_t port)
-{
- std::ostringstream path;
- path << piddir << "\\broker_" << port << ".pid";
- return path.str();
-}
-
// ShutdownEvent maintains an event that can be used to ask the broker
// to stop. Analogous to sending SIGTERM/SIGINT to the posix broker.
// The signal() method signals the event.
class ShutdownEvent {
public:
- ShutdownEvent(pid_t other = 0);
+ ShutdownEvent(int port);
~ShutdownEvent();
+ void create();
+ void open();
void signal();
+ private:
+ std::string eventName;
+
protected:
- std::string eventName(pid_t pid);
HANDLE event;
};
class ShutdownHandler : public ShutdownEvent, public qpid::sys::Runnable {
public:
- ShutdownHandler(const boost::intrusive_ptr<Broker>& b)
- : ShutdownEvent() { broker = b; }
+ ShutdownHandler(int port, const boost::intrusive_ptr<Broker>& b)
+ : ShutdownEvent(port) { broker = b; }
private:
virtual void run(); // Inherited from Runnable
boost::intrusive_ptr<Broker> broker;
};
-ShutdownEvent::ShutdownEvent(pid_t other) : event(NULL) {
- // If given a pid, open an event assumedly created by that pid. If there's
- // no pid, create a new event using the current process id.
- if (other == 0) {
- std::string name = eventName(GetCurrentProcessId());
- // Auto-reset event in case multiple processes try to signal a
- // broker that doesn't respond for some reason. Initially not signaled.
- event = CreateEvent(NULL, false, false, name.c_str());
- }
- else {
- std::string name = eventName(other);
- event = OpenEvent(EVENT_MODIFY_STATE, false, name.c_str());
- }
+ShutdownEvent::ShutdownEvent(int port) : event(NULL) {
+ std::ostringstream name;
+ name << "qpidd_" << port << std::ends;
+ eventName = name.str();
+}
+
+void ShutdownEvent::create() {
+ // Auto-reset event in case multiple processes try to signal a
+ // broker that doesn't respond for some reason. Initially not signaled.
+ event = ::CreateEvent(NULL, false, false, eventName.c_str());
+ QPID_WINDOWS_CHECK_NULL(event);
+}
+
+void ShutdownEvent::open() {
+ // TODO: Might need to search Global\\ name if unadorned name fails
+ event = ::OpenEvent(EVENT_MODIFY_STATE, false, eventName.c_str());
QPID_WINDOWS_CHECK_NULL(event);
}
ShutdownEvent::~ShutdownEvent() {
- CloseHandle(event);
+ ::CloseHandle(event);
event = NULL;
}
void ShutdownEvent::signal() {
- QPID_WINDOWS_CHECK_NOT(SetEvent(event), 0);
-}
-
-std::string ShutdownEvent::eventName(pid_t pid) {
- std::ostringstream name;
- name << "qpidd_" << pid << std::ends;
- return name.str();
+ QPID_WINDOWS_CHECK_NOT(::SetEvent(event), 0);
}
void ShutdownHandler::run() {
if (event == NULL)
return;
- WaitForSingleObject(event, INFINITE);
+ ::WaitForSingleObject(event, INFINITE);
if (broker.get()) {
broker->shutdown();
broker = 0; // Release the broker reference
@@ -134,19 +127,89 @@ void ShutdownHandler::run() {
}
// Console control handler to properly handle ctl-c.
+int ourPort;
BOOL CtrlHandler(DWORD ctl)
{
- ShutdownEvent shutter; // no pid specified == shut me down
+ ShutdownEvent shutter(ourPort); // We have to have set up the port before interrupting
+ shutter.open();
shutter.signal();
return ((ctl == CTRL_C_EVENT || ctl == CTRL_CLOSE_EVENT) ? TRUE : FALSE);
}
+template <typename T>
+class NamedSharedMemory {
+ std::string name;
+ HANDLE memory;
+ T* data;
+
+public:
+ NamedSharedMemory(const std::string&);
+ ~NamedSharedMemory();
+
+ T& create();
+ T& get();
+};
+
+template <typename T>
+NamedSharedMemory<T>::NamedSharedMemory(const std::string& n) :
+ name(n),
+ memory(NULL),
+ data(0)
+{};
+
+template <typename T>
+NamedSharedMemory<T>::~NamedSharedMemory() {
+ if (data)
+ ::UnmapViewOfFile(data);
+ if (memory != NULL)
+ ::CloseHandle(memory);
+};
+
+template <typename T>
+T& NamedSharedMemory<T>::create() {
+ assert(memory == NULL);
+
+ // Create named shared memory file
+ memory = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(T), name.c_str());
+ QPID_WINDOWS_CHECK_NULL(memory);
+
+ // Map file into memory
+ data = static_cast<T*>(::MapViewOfFile(memory, FILE_MAP_WRITE, 0, 0, 0));
+ QPID_WINDOWS_CHECK_NULL(data);
+
+ return *data;
+}
+
+template <typename T>
+T& NamedSharedMemory<T>::get() {
+ if (memory == NULL) {
+ // TODO: Might need to search Global\\ name if unadorned name fails
+ memory = ::OpenFileMapping(FILE_MAP_WRITE, FALSE, name.c_str());
+ QPID_WINDOWS_CHECK_NULL(memory);
+
+ data = static_cast<T*>(::MapViewOfFile(memory, FILE_MAP_WRITE, 0, 0, 0));
+ QPID_WINDOWS_CHECK_NULL(data);
+ }
+
+ return *data;
+}
+
+std::string brokerInfoName(uint16_t port)
+{
+ std::ostringstream path;
+ path << "qpidd_info_" << port;
+ return path.str();
+}
+
+struct BrokerInfo {
+ DWORD pid;
+};
+
}
struct ProcessControlOptions : public qpid::Options {
bool quit;
bool check;
- std::string piddir;
//std::string transport; No transport options yet - TCP is it.
ProcessControlOptions()
@@ -154,18 +217,9 @@ struct ProcessControlOptions : public qpid::Options {
quit(false),
check(false) //, transport(TCP)
{
- const DWORD pathLen = MAX_PATH + 1;
- char tempDir[pathLen];
- if (GetTempPath(pathLen, tempDir) == 0)
- piddir = "C:\\WINDOWS\\TEMP\\";
- else
- piddir = tempDir;
- piddir += "qpidd";
-
// Only have TCP for now, so don't need this...
// ("transport", optValue(transport, "TRANSPORT"), "The transport for which to return the port")
addOptions()
- ("pid-dir", qpid::optValue(piddir, "DIR"), "Directory where port-specific PID file is stored")
("check,c", qpid::optValue(check), "Prints the broker's process ID to stdout and returns 0 if the broker is running, otherwise returns 1")
("quit,q", qpid::optValue(quit), "Tells the broker to shut down");
}
@@ -207,57 +261,50 @@ int QpiddBroker::execute (QpiddOptions *options) {
if (myOptions->control.check || myOptions->control.quit) {
// Relies on port number being set via --port or QPID_PORT env variable.
- qpid::sys::LockFile getPid (brokerPidFile(myOptions->control.piddir,
- options->broker.port),
- false);
- pid_t pid = getPid.readPid();
+ NamedSharedMemory<BrokerInfo> info(brokerInfoName(options->broker.port));
+ int pid = info.get().pid;
if (pid < 0)
return 1;
if (myOptions->control.check)
std::cout << pid << std::endl;
if (myOptions->control.quit) {
- ShutdownEvent shutter(pid);
- HANDLE brokerHandle = OpenProcess(SYNCHRONIZE, false, pid);
- QPID_WINDOWS_CHECK_NULL(brokerHandle);
+ ShutdownEvent shutter(options->broker.port);
+ shutter.open();
shutter.signal();
- WaitForSingleObject(brokerHandle, INFINITE);
- CloseHandle(brokerHandle);
+ HANDLE brokerHandle = ::OpenProcess(SYNCHRONIZE, false, pid);
+ QPID_WINDOWS_CHECK_NULL(brokerHandle);
+ ::WaitForSingleObject(brokerHandle, INFINITE);
+ ::CloseHandle(brokerHandle);
}
return 0;
}
boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker));
- // Make sure the pid directory exists, creating if needed. LockFile
- // will throw an exception that makes little sense if it can't create
- // the file.
- if (!CreateDirectory(myOptions->control.piddir.c_str(), 0)) {
- DWORD err = GetLastError();
- if (err != ERROR_ALREADY_EXISTS)
- throw qpid::Exception(QPID_MSG("Can't create pid-dir " +
- myOptions->control.piddir +
- ": " +
- qpid::sys::strError(err)));
- }
// Need the correct port number to use in the pid file name.
if (options->broker.port == 0)
options->broker.port = brokerPtr->getPort("");
- qpid::sys::LockFile myPid(brokerPidFile(myOptions->control.piddir,
- options->broker.port),
- true);
- myPid.writePid();
+
+ BrokerInfo info;
+ info.pid = ::GetCurrentProcessId();
+
+ NamedSharedMemory<BrokerInfo> sharedInfo(brokerInfoName(options->broker.port));
+ sharedInfo.create() = info;
// Allow the broker to receive a shutdown request via a qpidd --quit
// command. Note that when the broker is run as a service this operation
// should not be allowed.
-
- ShutdownHandler waitShut(brokerPtr);
+ ourPort = options->broker.port;
+ ShutdownHandler waitShut(ourPort, brokerPtr);
+ waitShut.create();
qpid::sys::Thread waitThr(waitShut); // Wait for shutdown event
- SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
+ ::SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
brokerPtr->accept();
std::cout << options->broker.port << std::endl;
brokerPtr->run();
waitShut.signal(); // In case we shut down some other way
waitThr.join();
+
+ // CloseHandle(h);
return 0;
}