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/07 17:19:50 UTC
svn commit: r702513 - in /incubator/qpid/trunk/qpid/cpp/src: ./ qpid/
qpid/broker/ qpid/sys/ qpid/sys/posix/ qpid/sys/windows/
Author: shuston
Date: Tue Oct 7 08:19:50 2008
New Revision: 702513
URL: http://svn.apache.org/viewvc?rev=702513&view=rev
Log:
Abstract native file-locking and directory detection/creation to portable classes LockFile and FileSysDir; resolves QPID-1148
Added:
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h (with props)
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp (with props)
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp (with props)
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/FileSysDir.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp (with props)
Removed:
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.h
Modified:
incubator/qpid/trunk/qpid/cpp/src/Makefile.am
incubator/qpid/trunk/qpid/cpp/src/qpid/DataDir.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/sys/LockFile.h
Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=702513&r1=702512&r2=702513&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Tue Oct 7 08:19:50 2008
@@ -71,6 +71,8 @@
qpid/sys/posix/IOHandle.cpp \
qpid/sys/posix/Socket.cpp \
qpid/sys/posix/AsynchIO.cpp \
+ qpid/sys/posix/FileSysDir.cpp \
+ qpid/sys/posix/LockFile.cpp \
qpid/sys/posix/Time.cpp \
qpid/sys/posix/Thread.cpp \
qpid/sys/posix/Shlib.cpp \
@@ -85,7 +87,6 @@
qpid/sys/posix/PrivatePosix.h \
qpid/sys/posix/Mutex.h \
qpid/sys/posix/Fork.h \
- qpid/sys/posix/LockFile.h \
qpid/sys/posix/PollableCondition.h \
qpid/sys/posix/IntegerTypes.h
@@ -593,6 +594,7 @@
qpid/sys/ConnectionOutputHandlerPtr.h \
qpid/sys/DeletionManager.h \
qpid/sys/Dispatcher.h \
+ qpid/sys/FileSysDir.h \
qpid/sys/IntegerTypes.h \
qpid/sys/IOHandle.h \
qpid/sys/LockPtr.h \
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/DataDir.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/DataDir.cpp?rev=702513&r1=702512&r2=702513&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/DataDir.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/DataDir.cpp Tue Oct 7 08:19:50 2008
@@ -21,12 +21,7 @@
#include "Exception.h"
#include "DataDir.h"
#include "qpid/log/Statement.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <cerrno>
-#include <unistd.h>
+#include "qpid/sys/FileSysDir.h"
namespace qpid {
@@ -40,16 +35,9 @@
return;
}
- const char *cpath = dirPath.c_str ();
- struct stat s;
- if (::stat(cpath, &s)) {
- if (errno == ENOENT) {
- if (::mkdir(cpath, 0755))
- throw Exception ("Can't create data directory: " + path);
- }
- else
- throw Exception ("Data directory not found: " + path);
- }
+ sys::FileSysDir dir(dirPath);
+ if (!dir.exists())
+ dir.mkdir();
std::string lockFileName(path);
lockFileName += "/lock";
lockFile = std::auto_ptr<sys::LockFile>(new sys::LockFile(lockFileName, true));
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp?rev=702513&r1=702512&r2=702513&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp Tue Oct 7 08:19:50 2008
@@ -168,22 +168,14 @@
LockFile lf(lockFile, true);
/*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
- /*
* Write the PID to the lockfile.
*/
- pid_t pid = getpid();
- int desired_write = sizeof(pid_t);
- if ( desired_write > ::write(lf.fd, & pid, desired_write) ) {
- throw Exception("Cannot write lock file "+lockFile);
- }
+ lf.writePid();
/*
* Write the port number to the parent.
*/
- desired_write = sizeof(uint16_t);
+ int desired_write = sizeof(uint16_t);
if ( desired_write > ::write(pipeFds[1], & port, desired_write) ) {
throw Exception("Error writing to parent." );
}
@@ -198,16 +190,7 @@
pid_t Daemon::getPid(string _pidDir, uint16_t port) {
string name = pidFile(_pidDir, port);
LockFile lf(name, false);
- pid_t pid;
-
- /*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
- int desired_read = sizeof(pid_t);
- if ( desired_read > ::read(lf.fd, & pid, desired_read) ) {
- throw Exception("Cannot read lock file " + name);
- }
+ pid_t pid = lf.readPid();
if (kill(pid, 0) < 0 && errno != EPERM) {
unlink(name.c_str());
throw Exception("Removing stale lock file "+name);
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h?rev=702513&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h Tue Oct 7 08:19:50 2008
@@ -0,0 +1,62 @@
+#ifndef QPID_SYS_FILESYSDIR_H
+#define QPID_SYS_FILESYSDIR_H
+
+/*
+ * 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 <string>
+
+namespace qpid {
+namespace sys {
+
+/**
+ * @class FileSysDir
+ *
+ * Represents a filesystem directory accessible from the local host.
+ * This class simply checks existence of, and creates, a directory. It could
+ * be added to later to list contents, etc.
+ */
+class FileSysDir
+{
+ const std::string dirPath;
+
+ public:
+
+ FileSysDir (std::string path) : dirPath(path) {}
+ ~FileSysDir () {}
+
+ /**
+ * Check to see if the directory exists and is a directory. Throws an
+ * exception if there is an error checking existence or if the path
+ * exists but is not a directory.
+ *
+ * @retval true if the path exists and is a directory.
+ * @retval false if the path does not exist.
+ */
+ bool exists (void) const;
+
+ void mkdir(void);
+
+ std::string getPath () { return dirPath; }
+};
+
+}} // namespace qpid::sys
+
+#endif /*!QPID_SYS_FILESYSDIR_H*/
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/FileSysDir.h
------------------------------------------------------------------------------
svn:executable = *
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/LockFile.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/LockFile.h?rev=702513&r1=702512&r2=702513&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/LockFile.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/LockFile.h Tue Oct 7 08:19:50 2008
@@ -19,7 +19,60 @@
*
*/
-#include "posix/LockFile.h"
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+#include "IntegerTypes.h"
+
+namespace qpid {
+namespace sys {
+
+class LockFilePrivate;
+
+/**
+ * @class LockFile
+ *
+ * LockFile represents a locked file suitable for a coarse-grain system
+ * lock. For example, the broker uses this to ensure that only one broker
+ * runs. A common usage idiom is to store the current "owner" process ID
+ * in the lock file - if the lock file exists, but the stored process ID
+ * doesn't, the old owner has probably died without cleaning up the lock
+ * file.
+ */
+class LockFile : private boost::noncopyable
+{
+ boost::shared_ptr<LockFilePrivate> impl;
+
+ std::string path;
+ bool created;
+
+public:
+ LockFile(const std::string& path_, bool create);
+ ~LockFile();
+
+ /**
+ * Read the process ID from the lock file. This method assumes that
+ * if there is a process ID in the file, it was written there by
+ * writePid(); thus, it's at the start of the file.
+ *
+ * Throws an exception if there is an error reading the file.
+ *
+ * @returns The stored process ID. No validity check is done on it.
+ */
+ pid_t readPid(void) const;
+
+ /**
+ * Write the current process's ID to the lock file. It's written at
+ * the start of the file and will overwrite any other content that
+ * may be in the file.
+ *
+ * Throws an exception if the write fails.
+ */
+ void writePid(void);
+};
+
+}} /* namespace qpid::sys */
#endif /*!_sys_LockFile_h*/
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp?rev=702513&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp Tue Oct 7 08:19:50 2008
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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/sys/FileSysDir.h"
+#include "qpid/sys/StrError.h"
+#include "qpid/Exception.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cerrno>
+#include <unistd.h>
+
+namespace qpid {
+namespace sys {
+
+bool FileSysDir::exists (void) const
+{
+ const char *cpath = dirPath.c_str ();
+ struct stat s;
+ if (::stat(cpath, &s)) {
+ if (errno == ENOENT) {
+ return false;
+ }
+ throw qpid::Exception (strError(errno) +
+ ": Can't check directory: " + dirPath);
+ }
+ if (S_ISDIR(s.st_mode))
+ return true;
+ throw qpid::Exception(dirPath + " is not a directory");
+}
+
+void FileSysDir::mkdir(void)
+{
+ if (::mkdir(dirPath.c_str(), 0755))
+ throw Exception ("Can't create directory: " + dirPath);
+}
+
+}} // namespace qpid::sys
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/FileSysDir.cpp
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp?rev=702513&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp Tue Oct 7 08:19:50 2008
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright (c) 2008 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/sys/LockFile.h"
+
+#include <string>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "check.h"
+
+namespace qpid {
+namespace sys {
+
+class LockFilePrivate {
+ friend class LockFile;
+
+ int fd;
+
+public:
+ LockFilePrivate(int f) : fd(f) {}
+};
+
+LockFile::LockFile(const std::string& path_, bool create)
+ : path(path_), created(create) {
+
+ errno = 0;
+ int flags=create ? O_WRONLY|O_CREAT|O_NOFOLLOW : O_RDWR;
+ int fd = ::open(path.c_str(), flags, 0644);
+ if (fd < 0) throw ErrnoException("Cannot open " + path, errno);
+ if (::lockf(fd, F_TLOCK, 0) < 0) {
+ ::close(fd);
+ throw ErrnoException("Cannot lock " + path, errno);
+ }
+ impl.reset(new LockFilePrivate(fd));
+}
+
+LockFile::~LockFile() {
+ if (impl) {
+ int f = impl->fd;
+ if (f >= 0) {
+ (void) ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
+ ::close(f);
+ impl->fd = -1;
+ }
+ }
+}
+
+pid_t LockFile::readPid(void) const {
+ if (!impl)
+ throw Exception("Lock file not open");
+
+ pid_t pid;
+ int desired_read = sizeof(pid_t);
+ if (desired_read > ::read(impl->fd, &pid, desired_read) ) {
+ throw Exception("Cannot read lock file " + path);
+ }
+ return pid;
+}
+
+void LockFile::writePid(void) {
+ if (!impl)
+ throw Exception("Lock file not open");
+
+ pid_t pid = getpid();
+ int desired_write = sizeof(pid_t);
+ if (desired_write > ::write(impl->fd, &pid, desired_write)) {
+ throw Exception("Cannot write lock file " + path);
+ }
+}
+
+}} /* namespace qpid::sys */
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/FileSysDir.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/FileSysDir.cpp?rev=702513&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/FileSysDir.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/FileSysDir.cpp Tue Oct 7 08:19:50 2008
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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/sys/FileSysDir.h"
+#include "qpid/sys/StrError.h"
+#include "qpid/Exception.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <direct.h>
+#include <errno.h>
+
+namespace qpid {
+namespace sys {
+
+bool FileSysDir::exists (void) const
+{
+ const char *cpath = dirPath.c_str ();
+ struct _stat s;
+ if (::_stat(cpath, &s)) {
+ if (errno == ENOENT) {
+ return false;
+ }
+ throw qpid::Exception (strError(errno) +
+ ": Can't check directory: " + dirPath);
+ }
+ if (s.st_mode & _S_IFDIR)
+ return true;
+ throw qpid::Exception(dirPath + " is not a directory");
+}
+
+void FileSysDir::mkdir(void)
+{
+ if (::_mkdir(dirPath.c_str()) == -1)
+ throw Exception ("Can't create directory: " + dirPath);
+}
+
+}} // namespace qpid::sys
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp?rev=702513&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp Tue Oct 7 08:19:50 2008
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright (c) 2008 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/sys/LockFile.h"
+#include "check.h"
+
+#include <windows.h>
+
+namespace qpid {
+namespace sys {
+
+class LockFilePrivate {
+ friend class LockFile;
+
+ HANDLE fd;
+
+public:
+ LockFilePrivate(HANDLE f) : fd(f) {}
+};
+
+LockFile::LockFile(const std::string& path_, bool create)
+ : path(path_), created(create) {
+
+ HANDLE h = CreateFile(path.c_str(),
+ GENERIC_READ|GENERIC_WRITE,
+ 0, /* Disable opens by any other attempter */
+ 0, /* Default security */
+ OPEN_ALWAYS, /* Create if needed */
+ FILE_FLAG_DELETE_ON_CLOSE, /* Delete file when closed */
+ NULL);
+ QPID_WINDOWS_CHECK_NOT(h, INVALID_HANDLE_VALUE);
+ impl.reset(new LockFilePrivate(h));
+}
+
+LockFile::~LockFile() {
+ if (impl) {
+ if (impl->fd != INVALID_HANDLE_VALUE) {
+ CloseHandle(impl->fd);
+ }
+ }
+}
+
+pid_t LockFile::readPid(void) const {
+ if (!impl)
+ throw Exception("Lock file not open");
+
+ pid_t pid;
+ DWORD desired_read = sizeof(pid_t);
+ DWORD actual_read = 0;
+ if (!ReadFile(impl->fd, &pid, desired_read, &actual_read, 0)) {
+ throw Exception("Cannot read lock file " + path);
+ }
+ return pid;
+}
+
+void LockFile::writePid(void) {
+ if (!impl)
+ throw Exception("Lock file not open");
+
+ pid_t pid = GetCurrentProcessId();
+ DWORD desired_write = sizeof(pid_t);
+ DWORD written = 0;
+ if (!WriteFile(impl->fd, &pid, desired_write, &written, 0)) {
+ throw Exception("Cannot write lock file " + path);
+ }
+}
+
+}} /* namespace qpid::sys */
Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/windows/LockFile.cpp
------------------------------------------------------------------------------
svn:executable = *