diff options
Diffstat (limited to 'cpp/src/qpid/DataDir.cpp')
-rw-r--r-- | cpp/src/qpid/DataDir.cpp | 42 |
1 files changed, 16 insertions, 26 deletions
diff --git a/cpp/src/qpid/DataDir.cpp b/cpp/src/qpid/DataDir.cpp index e9c6aaad53..879f4de202 100644 --- a/cpp/src/qpid/DataDir.cpp +++ b/cpp/src/qpid/DataDir.cpp @@ -23,6 +23,7 @@ #include "qpid/log/Statement.h" #include <sys/types.h> #include <sys/stat.h> +#include <sys/file.h> #include <fcntl.h> #include <cerrno> @@ -30,7 +31,8 @@ namespace qpid { DataDir::DataDir (std::string path) : enabled (!path.empty ()), - dirPath (path) + dirPath (path), + dirFd(-1) { if (!enabled) { @@ -40,7 +42,6 @@ DataDir::DataDir (std::string path) : const char *cpath = dirPath.c_str (); struct stat s; - if (::stat(cpath, &s)) { if (errno == ENOENT) { if (::mkdir(cpath, 0755)) @@ -49,34 +50,23 @@ DataDir::DataDir (std::string path) : else throw Exception ("Data directory not found: " + path); } - - std::string lockFile (path); - lockFile = lockFile + "/lock"; - int fd = ::open (lockFile.c_str (), O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd == -1) - { - if (errno == EEXIST) - throw Exception ("Data directory is locked by another process: " + path); - if (errno == EACCES) - throw Exception ("Insufficient privileges for data directory: " + path); - throw Exception( - QPID_MSG("Error locking " << lockFile << ": " << strError(errno))); + int dirFd = ::open(path.c_str(), 0); + if (dirFd == -1) + throw Exception(QPID_MSG("Can't open data directory: " << dirPath << ": " << strError(errno))); + int result = ::flock(dirFd, LOCK_EX | LOCK_NB); + if (result != 0) { + if (errno == EWOULDBLOCK) + throw Exception(QPID_MSG("Data directory locked by another process: " << path)); + throw Exception(QPID_MSG("Cannot lock data directory: " << strError(errno))); } - QPID_LOG (info, "Locked data directory: " << dirPath); } -DataDir::~DataDir () -{ - if (dirPath.empty ()) - return; - - std::string lockFile (dirPath); - lockFile = lockFile + "/lock"; - - ::unlink (lockFile.c_str ()); - QPID_LOG (info, "Unlocked data directory: " << dirPath); +DataDir::~DataDir () { + if (dirFd != -1) { + ::close(dirFd); // Closing the fd unlocks the directory. + QPID_LOG (info, "Unlocked data directory: " << dirPath); + } } } // namespace qpid |