diff options
author | Jose <jose@zeroc.com> | 2009-12-04 06:51:23 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2009-12-04 06:51:23 +0100 |
commit | 0ad40835182795b5f9bedeea10aeb6f07c666e7d (patch) | |
tree | 5dff55b02aefb5854a972eb2cef128d1537d5c47 /cpp | |
parent | Bug 4408 - plugin does not work with x64 only installation (diff) | |
download | ice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.tar.bz2 ice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.tar.xz ice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.zip |
4089 - IceGrid database corruption.
Diffstat (limited to 'cpp')
31 files changed, 851 insertions, 13 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py index 9a663154e90..ac7b4a71d6d 100755 --- a/cpp/allTests.py +++ b/cpp/allTests.py @@ -31,6 +31,7 @@ tests = [ ("IceUtil/inputUtil", ["once"]), ("IceUtil/uuid", ["once", "noappverifier"]), # This test is very slow with appverifier. ("IceUtil/timer", ["once"]), + ("IceUtil/fileLock", ["once"]), ("Slice/errorDetection", ["once"]), ("Slice/keyword", ["once"]), ("Ice/proxy", ["core"]), @@ -67,6 +68,7 @@ tests = [ ("Freeze/dbmap", ["once", "novc6"]), ("Freeze/complex", ["once", "novc6"]), ("Freeze/evictor", ["core", "novc6"]), + ("Freeze/fileLock", ["core", "novc6"]), ("IceStorm/single", ["service", "novc6", "noappverifier"]), # This test doensn't work with appverifier is sensitive to timeouts. ("IceStorm/federation", ["service", "novc6"]), ("IceStorm/federation2", ["service", "novc6"]), @@ -77,6 +79,7 @@ tests = [ ("FreezeScript/dbmap", ["once", "novc6"]), ("FreezeScript/evictor", ["once", "novc6"]), ("IceGrid/simple", ["service", "novc6"]), + ("IceGrid/fileLock", ["service", "nobcc", "novc6"]), ("IceGrid/deployer", ["service", "nobcc", "novc6"]), ("IceGrid/session", ["service", "nobcc", "novc6"]), ("IceGrid/update", ["service", "nobcc", "novc6"]), diff --git a/cpp/include/IceUtil/Exception.h b/cpp/include/IceUtil/Exception.h index e545594c608..afd59ed48e7 100644 --- a/cpp/include/IceUtil/Exception.h +++ b/cpp/include/IceUtil/Exception.h @@ -98,6 +98,27 @@ private: static const char* _name; }; +class ICE_UTIL_API FileLockException : public Exception +{ +public: + + FileLockException(const char*, int, int, const std::string&); + virtual ~FileLockException() throw(); + virtual std::string ice_name() const; + virtual void ice_print(std::ostream&) const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; + + std::string path() const; + int error() const; + +private: + + const int _error; + static const char* _name; + std::string _path; +}; + } #endif diff --git a/cpp/include/IceUtil/FileUtil.h b/cpp/include/IceUtil/FileUtil.h index 791985dcb39..3928f5ba413 100644 --- a/cpp/include/IceUtil/FileUtil.h +++ b/cpp/include/IceUtil/FileUtil.h @@ -11,6 +11,9 @@ #define ICE_FILE_UTIL_H #include <IceUtil/Config.h> +#include <IceUtil/Shared.h> +#include <IceUtil/Handle.h> + #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> @@ -72,6 +75,40 @@ ICE_UTIL_API int getcwd(std::string&); ICE_UTIL_API int unlink(const std::string&); ICE_UTIL_API int close(int); +// +// This class is used to implement process file locking. This class +// is not intended to do file locking within the same process. +// +class ICE_UTIL_API FileLock : public IceUtil::Shared, public IceUtil::noncopyable +{ +public: + // + // The constructor opens the given file (eventually creating it) + // and acquires a lock on the file or throws FileLockException if + // the file couldn't be locked. + // + // If the lock can be acquired, the process pid is written to the + // file. + // + FileLock(const std::string&); + + // + // The destructor releases the lock and removes the file. + // + virtual ~FileLock(); + +private: + +#ifdef _WIN32 + HANDLE _fd; +#else + int _fd; +#endif + std::string _path; +}; + +typedef IceUtil::Handle<FileLock> FileLockPtr; + class ICE_UTIL_API ifstream : public std::ifstream { public: @@ -118,6 +155,5 @@ private: #endif }; -}; - +} #endif diff --git a/cpp/src/Freeze/SharedDbEnv.cpp b/cpp/src/Freeze/SharedDbEnv.cpp index 764662d9386..5156b52aa00 100644 --- a/cpp/src/Freeze/SharedDbEnv.cpp +++ b/cpp/src/Freeze/SharedDbEnv.cpp @@ -482,6 +482,14 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, } #endif + string propertyPrefix = string("Freeze.DbEnv.") + envName; + string dbHome = properties->getPropertyWithDefault(propertyPrefix + ".DbHome", envName); + + // + // File lock to prevent multiple process open the same db env. + // + _fileLock = new ::IceUtilInternal::FileLock(dbHome + "/Freeze.lock"); + _trace = properties->getPropertyAsInt("Freeze.Trace.DbEnv"); try @@ -497,11 +505,8 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, out << "opening database environment \"" << envName << "\""; } - string propertyPrefix = string("Freeze.DbEnv.") + envName; - - _env->set_errpfx(reinterpret_cast<char*>(this)); - + _env->set_errcall(dbErrCallback); #ifdef _WIN32 @@ -552,9 +557,6 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, // Threading // flags |= DB_THREAD; - - string dbHome = properties->getPropertyWithDefault( - propertyPrefix + ".DbHome", envName); _env->open(Ice::nativeToUTF8(_communicator, dbHome).c_str(), flags, FREEZE_DB_MODE); diff --git a/cpp/src/Freeze/SharedDbEnv.h b/cpp/src/Freeze/SharedDbEnv.h index 9d249bea6b5..573a537a18a 100644 --- a/cpp/src/Freeze/SharedDbEnv.h +++ b/cpp/src/Freeze/SharedDbEnv.h @@ -11,6 +11,7 @@ #define FREEZE_SHARED_DB_ENV_H #include <Freeze/Map.h> +#include <IceUtil/FileUtil.h> #include <Ice/Ice.h> #include <db_cxx.h> #include <map> @@ -96,6 +97,7 @@ private: SharedDbMap _sharedDbMap; IceUtil::Mutex _mutex; + IceUtilInternal::FileLockPtr _fileLock; }; inline DbEnv* diff --git a/cpp/src/IceDB/SqlTypes.cpp b/cpp/src/IceDB/SqlTypes.cpp index 829e49b0c50..1f288621d7e 100644 --- a/cpp/src/IceDB/SqlTypes.cpp +++ b/cpp/src/IceDB/SqlTypes.cpp @@ -170,6 +170,14 @@ DatabaseCache::DatabaseCache(const Ice::CommunicatorPtr& communicator, bool requiresBlob) { Ice::PropertiesPtr properties = communicator->getProperties(); + + // + // File lock to prevent multiple process open the same db env. + // + if(type == "QSQLITE") + { + _fileLock = new IceUtilInternal::FileLock(name + ".lock"); + } _connection = QSqlDatabase::addDatabase(type.c_str(), IceUtil::generateUUID().c_str()); _connection.setDatabaseName(name.c_str()); diff --git a/cpp/src/IceDB/SqlTypes.h b/cpp/src/IceDB/SqlTypes.h index a2b5600e475..b6613f95f35 100644 --- a/cpp/src/IceDB/SqlTypes.h +++ b/cpp/src/IceDB/SqlTypes.h @@ -14,6 +14,7 @@ #include <IceUtil/Handle.h> #include <IceUtil/Thread.h> +#include <IceUtil/FileUtil.h> #include <Ice/CommunicatorF.h> #include <Ice/Initialize.h> // For ThreadHook @@ -122,6 +123,10 @@ protected: QSqlDatabase _connection; ThreadDatabaseMap _cache; + +private: + + IceUtilInternal::FileLockPtr _fileLock; }; typedef IceUtil::Handle<DatabaseCache> DatabaseCachePtr; diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp index 6ce81a17c23..7f33bc497a4 100644 --- a/cpp/src/IceUtil/Exception.cpp +++ b/cpp/src/IceUtil/Exception.cpp @@ -401,3 +401,52 @@ IceUtil::SyscallException::error() const { return _error; } + + +IceUtil::FileLockException::FileLockException(const char* file, int line, int err, const string& path): + Exception(file, line), + _error(err), + _path(path) +{ +} + +IceUtil::FileLockException::~FileLockException() throw() +{ +} + +const char* IceUtil::FileLockException::_name = "IceUtil::FileLockedException"; + +string +IceUtil::FileLockException::ice_name() const +{ + return _name; +} + +void +IceUtil::FileLockException::ice_print(ostream& os) const +{ + Exception::ice_print(os); + os << ":\ncould not lock file: `" << _path << "'"; + if(_error != 0) + { + os << "\nsyscall exception: " << IceUtilInternal::errorToString(_error); + } +} + +IceUtil::Exception* +IceUtil::FileLockException::ice_clone() const +{ + return new FileLockException(*this); +} + +void +IceUtil::FileLockException::ice_throw() const +{ + throw *this; +} + +int +IceUtil::FileLockException::error() const +{ + return _error; +} diff --git a/cpp/src/IceUtil/FileUtil.cpp b/cpp/src/IceUtil/FileUtil.cpp index 67f1569fdc0..22628852541 100644 --- a/cpp/src/IceUtil/FileUtil.cpp +++ b/cpp/src/IceUtil/FileUtil.cpp @@ -10,7 +10,13 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/FileUtil.h> #include <IceUtil/Unicode.h> +#include <IceUtil/Exception.h> #include <climits> +#include <string.h> + +#ifdef _WIN32 +# include <process.h> +#endif #ifdef _WIN32 # include <io.h> @@ -19,6 +25,7 @@ #ifdef __BCPLUSPLUS__ # include <dir.h> #endif + using namespace std; // @@ -172,6 +179,37 @@ IceUtilInternal::close(int fd) #endif } +IceUtilInternal::FileLock::FileLock(const std::string& path) : + _fd(INVALID_HANDLE_VALUE), + _path(path) +{ + _fd = ::CreateFileW(IceUtil::stringToWstring(path).c_str(), GENERIC_WRITE, 0, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + _path = path; + + if(_fd == INVALID_HANDLE_VALUE) + { + throw IceUtil::FileLockException(__FILE__, __LINE__, GetLastError(), _path); + } + + if(::LockFile(_fd, 0, 0, 0, 0) == 0) + { + ::CloseHandle(_fd); + throw IceUtil::FileLockException(__FILE__, __LINE__, GetLastError(), _path); + } + // + // In Windows implementation we don't write the process pid to the file, as is + // not posible to read the file from other process while it is locked here. + // +} + +IceUtilInternal::FileLock::~FileLock() +{ + assert(_fd != INVALID_HANDLE_VALUE); + CloseHandle(_fd); + unlink(_path); +} + #ifdef _STLP_BEGIN_NAMESPACE namespace { @@ -407,6 +445,60 @@ IceUtilInternal::close(int fd) return ::close(fd); } +IceUtilInternal::FileLock::FileLock(const std::string& path) : + _fd(-1), + _path(path) +{ + _fd = ::open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if(_fd < 0) + { + throw IceUtil::FileLockException(__FILE__, __LINE__, errno, _path); + } + + struct ::flock lock; + lock.l_type = F_WRLCK; // Write lock + lock.l_whence = SEEK_SET; // Begining of file + lock.l_start = 0; + lock.l_len = 0; + + // + // F_SETLK tells fcntl to not block if it cannot + // acquire the lock, if the lock cannot be acquired + // it returns -1 without wait. + // + if(::fcntl(_fd, F_SETLK, &lock) == -1) + { + IceUtil::FileLockException ex(__FILE__, __LINE__, errno, _path); + close(_fd); + throw ex; + } + + // + // If there is an error after here, we close the fd, + // to release the lock. + // + + // + // Now that we have acquire an excluxive write lock, + // write the process pid there. + // + ostringstream os; + os << getpid(); + + if(write(_fd, os.str().c_str(), os.str().size()) == -1) + { + IceUtil::FileLockException ex(__FILE__, __LINE__, errno, _path); + close(_fd); + throw ex; + } +} + +IceUtilInternal::FileLock::~FileLock() +{ + assert(_fd > -1); + unlink(_path); +} + IceUtilInternal::ifstream::ifstream() { } diff --git a/cpp/test/Freeze/Makefile b/cpp/test/Freeze/Makefile index ad720dc8087..45417cc1e3b 100644 --- a/cpp/test/Freeze/Makefile +++ b/cpp/test/Freeze/Makefile @@ -11,7 +11,7 @@ top_srcdir = ../.. include $(top_srcdir)/config/Make.rules -SUBDIRS = dbmap complex evictor +SUBDIRS = dbmap complex evictor fileLock $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/Freeze/Makefile.mak b/cpp/test/Freeze/Makefile.mak index 23c19c6403f..842f559f9ba 100644 --- a/cpp/test/Freeze/Makefile.mak +++ b/cpp/test/Freeze/Makefile.mak @@ -13,7 +13,8 @@ top_srcdir = ..\.. SUBDIRS = dbmap \
complex \
- evictor
+ evictor \
+ fileLock
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cpp/test/Freeze/fileLock/.depend b/cpp/test/Freeze/fileLock/.depend new file mode 100644 index 00000000000..7ed9c7fce30 --- /dev/null +++ b/cpp/test/Freeze/fileLock/.depend @@ -0,0 +1 @@ +Client$(OBJEXT): Client.cpp $(includedir)/IceUtil/IceUtil.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/AbstractMutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Exception.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/Cache.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/IceUtil/CountDownLatch.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/CtrlCHandler.h $(includedir)/IceUtil/Functional.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/MutexPtrLock.h $(includedir)/IceUtil/RWRecMutex.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/RecMutex.h $(includedir)/IceUtil/StaticMutex.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/UUID.h $(includedir)/IceUtil/Unicode.h $(includedir)/Freeze/Freeze.h $(includedir)/Freeze/Initialize.h $(includedir)/Ice/Ice.h $(includedir)/Ice/Initialize.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/Stream.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Properties.h $(includedir)/Ice/Outgoing.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Stats.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/ObjectFactory.h $(includedir)/Ice/ObjectAdapter.h $(includedir)/Ice/FacetMap.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ServantLocator.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Process.h $(includedir)/Ice/Application.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Functional.h $(includedir)/Ice/ImplicitContext.h $(includedir)/Ice/Locator.h $(includedir)/Ice/FactoryTableInit.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/ProcessF.h $(includedir)/Ice/Router.h $(includedir)/Ice/DispatchInterceptor.h $(includedir)/Ice/IconvStringConverter.h $(includedir)/Freeze/EvictorF.h $(includedir)/Freeze/ConnectionF.h $(includedir)/Freeze/Index.h $(includedir)/Freeze/DB.h $(includedir)/Freeze/Transaction.h $(includedir)/Freeze/BackgroundSaveEvictor.h $(includedir)/Freeze/Evictor.h $(includedir)/Freeze/Exception.h $(includedir)/Freeze/TransactionalEvictor.h $(includedir)/Freeze/Map.h $(includedir)/Freeze/Connection.h $(includedir)/Freeze/TransactionHolder.h $(includedir)/Freeze/Catalog.h $(includedir)/Freeze/CatalogData.h ../../include/TestCommon.h diff --git a/cpp/test/Freeze/fileLock/.gitignore b/cpp/test/Freeze/fileLock/.gitignore new file mode 100644 index 00000000000..e58e5b6b798 --- /dev/null +++ b/cpp/test/Freeze/fileLock/.gitignore @@ -0,0 +1,6 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +client +clientFail +db/* diff --git a/cpp/test/Freeze/fileLock/Client.cpp b/cpp/test/Freeze/fileLock/Client.cpp new file mode 100644 index 00000000000..4ec7180863b --- /dev/null +++ b/cpp/test/Freeze/fileLock/Client.cpp @@ -0,0 +1,91 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/IceUtil.h> +#include <Freeze/Freeze.h> +#include <TestCommon.h> + +using namespace std; +using namespace Ice; +using namespace Freeze; + +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32) && !defined(__BCPLUSPLUS__) +int +wmain(int argc, wchar_t* argv[]) + +#else + +int +main(int argc, char* argv[]) + +#endif +{ + int status = EXIT_SUCCESS; + Ice::CommunicatorPtr communicator; + + string envName = "db"; + + communicator = Ice::initialize(argc, argv); + if(argc != 1) + { +#if defined(_WIN32) && !defined(__BCPLUSPLUS__) + envName = IceUtil::wstringToString(argv[1]); +#else + envName = argv[1]; +#endif + envName += "/db"; + } + + { + Freeze::ConnectionPtr connection; + try + { + connection = Freeze::createConnection(communicator, envName); + test(true); + } + catch(const exception& ex) + { + cerr << "excetpion:\n" << ex.what() << endl; + test(false); + } + catch(...) + { + test(false); + } + + cout << "File lock acquired.\n" + << "Enter some input and press enter, to release the lock and terminate the program." << endl; + // + // Block the test waiting for IO, so the file lock is preserved. + // + string foo; + cin >> foo; + + // + // Clean up. + // + if(connection) + { + connection->close(); + } + } + cout << "File lock released." << endl; + + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + return status; +} diff --git a/cpp/test/Freeze/fileLock/ClientFail.cpp b/cpp/test/Freeze/fileLock/ClientFail.cpp new file mode 100644 index 00000000000..caeefff91f6 --- /dev/null +++ b/cpp/test/Freeze/fileLock/ClientFail.cpp @@ -0,0 +1,80 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/IceUtil.h> +#include <Freeze/Freeze.h> +#include <TestCommon.h> + +using namespace std; +using namespace Ice; +using namespace Freeze; + +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32) && !defined(__BCPLUSPLUS__) +int +wmain(int argc, wchar_t* argv[]) + +#else + +int +main(int argc, char* argv[]) + +#endif +{ + int status = EXIT_SUCCESS; + Ice::CommunicatorPtr communicator; + + string envName = "db"; + + communicator = Ice::initialize(argc, argv); + if(argc != 1) + { +#if defined(_WIN32) && !defined(__BCPLUSPLUS__) + envName = IceUtil::wstringToString(argv[1]); +#else + envName = argv[1]; +#endif + envName += "/db"; + } + + { + Freeze::ConnectionPtr connection; + try + { + connection = Freeze::createConnection(communicator, envName); + test(false); + } + catch(const IceUtil::FileLockException&) + { + cout << "File lock not acquired." << endl; + test(true); + } + catch(const exception& ex) + { + cerr << "excetpion:\n" << ex.what() << endl; + test(false); + } + catch(...) + { + test(false); + } + } + + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + + return status; +} diff --git a/cpp/test/Freeze/fileLock/Makefile b/cpp/test/Freeze/fileLock/Makefile new file mode 100644 index 00000000000..d0b4e282dbc --- /dev/null +++ b/cpp/test/Freeze/fileLock/Makefile @@ -0,0 +1,41 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client +CLIENTF = clientFail + +TARGETS = $(CLIENT) $(CLIENTF) + +OBJS = Client.o + +OBJFS = ClientFail.o + +SRCS = $(OBJS:.o=.cpp) + +GENPIC = no + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include $(CPPFLAGS) + +$(CLIENT): $(OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(DB_RPATH_LINK) -lFreeze $(LIBS) + +$(CLIENTF): $(OBJFS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJFS) $(DB_RPATH_LINK) -lFreeze $(LIBS) + + +clean:: + -rm -f db/* + +include .depend diff --git a/cpp/test/Freeze/fileLock/Makefile.mak b/cpp/test/Freeze/fileLock/Makefile.mak new file mode 100644 index 00000000000..19c4a16c85c --- /dev/null +++ b/cpp/test/Freeze/fileLock/Makefile.mak @@ -0,0 +1,44 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+CLIENTF = clientFail.exe
+TARGETS = $(CLIENT) $(CLIENTF)
+
+OBJS = Client.obj
+
+OBJFS = ClientFail.obj
+
+SRCS = $(OBJS:.obj=.cpp)
+
+!include $(top_srcdir)\config\Make.rules.mak
+
+CPPFLAGS = -I. -I..\..\include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+!endif
+
+$(CLIENT): $(OBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) freeze$(LIBSUFFIX).lib
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+$(CLIENTF): $(OBJFS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(OBJFS) $(PREOUT)$@ $(PRELIBS)$(LIBS) freeze$(LIBSUFFIX).lib
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+
+clean::
+ del /q db/*
+
+!include .depend
diff --git a/cpp/test/Freeze/fileLock/db/.gitignore b/cpp/test/Freeze/fileLock/db/.gitignore new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cpp/test/Freeze/fileLock/db/.gitignore diff --git a/cpp/test/Freeze/fileLock/run.py b/cpp/test/Freeze/fileLock/run.py new file mode 100755 index 00000000000..a01c758ea11 --- /dev/null +++ b/cpp/test/Freeze/fileLock/run.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +print "testing Freeze file lock...", +sys.stdout.flush() + +client = os.path.join(os.getcwd(), "client") + +clientExe = TestUtil.startClient(client, "", None, None, False) +clientExe.expect('File lock acquired.\.*') + +clientFail = os.path.join(os.getcwd(), "clientFail") +clientFailExe = TestUtil.startClient(clientFail, "", None, None, False) +clientFailExe.expect('File lock not acquired') + +# send some output to client to terminate it. +clientExe.sendline('go') +clientExe.expect('File lock released.') + +# The lock is gone try to acquire it again. +clientExe = TestUtil.startClient(client, "", None, None, False) +clientExe.expect('File lock acquired.\.*') +clientExe.sendline('go') +clientExe.expect('File lock released.') + +print "ok"
\ No newline at end of file diff --git a/cpp/test/IceGrid/fileLock/.gitignore b/cpp/test/IceGrid/fileLock/.gitignore new file mode 100644 index 00000000000..65eef93d691 --- /dev/null +++ b/cpp/test/IceGrid/fileLock/.gitignore @@ -0,0 +1 @@ +db diff --git a/cpp/test/IceGrid/fileLock/db/.gitignore b/cpp/test/IceGrid/fileLock/db/.gitignore new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/cpp/test/IceGrid/fileLock/db/.gitignore diff --git a/cpp/test/IceGrid/fileLock/run.py b/cpp/test/IceGrid/fileLock/run.py new file mode 100755 index 00000000000..b580890bce1 --- /dev/null +++ b/cpp/test/IceGrid/fileLock/run.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +def runIceGridRegistry(testdir): + iceGrid = "" + if TestUtil.isBCC2010() or TestUtil.isVC6(): + iceGrid = os.path.join(TestUtil.getServiceDir(), "icegridregistry") + else: + iceGrid = os.path.join(TestUtil.getCppBinDir(), "icegridregistry") + + command = ' --nowarn ' + IceGridAdmin.registryOptions + + name = "registry" + + dataDir = os.path.join(testdir, "db", name) + if not os.path.exists(dataDir): + os.mkdir(dataDir) + + cmd = command + ' ' + TestUtil.getQtSqlOptions('IceGrid') + \ + r' --Ice.ProgramName=' + name + \ + r' --IceGrid.Registry.Client.Endpoints="default -p ' + str(IceGridAdmin.iceGridPort) + '" ' + \ + r' --IceGrid.Registry.Data=' + dataDir + + driverConfig = TestUtil.DriverConfig("server") + driverConfig.lang = "cpp" + + cmd = TestUtil.getCommandLine(iceGrid, driverConfig) + ' ' + cmd + proc = TestUtil.spawn(cmd) + return proc + +IceGridAdmin.cleanDbDir("./db/registry") + +print "testing IceGrid file lock...", +iceGrid1 = runIceGridRegistry(".") +iceGrid1.expect("[^\n]+ ready\n") + +iceGrid2 = runIceGridRegistry(".") +iceGrid2.expect(".*IceUtil::FileLockedException.*") +print "ok" + +IceGridAdmin.iceGridAdmin("registry shutdown") +IceGridAdmin.cleanDbDir("./db/registry") diff --git a/cpp/test/IceUtil/Makefile b/cpp/test/IceUtil/Makefile index ca30b95fc00..45e93399373 100644 --- a/cpp/test/IceUtil/Makefile +++ b/cpp/test/IceUtil/Makefile @@ -18,7 +18,8 @@ SUBDIRS = condvar \ uuid \ ctrlCHandler \ timer \ - priority + priority \ + fileLock $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/IceUtil/Makefile.mak b/cpp/test/IceUtil/Makefile.mak index b7363ea211a..78956cbf380 100644 --- a/cpp/test/IceUtil/Makefile.mak +++ b/cpp/test/IceUtil/Makefile.mak @@ -18,7 +18,8 @@ SUBDIRS = condvar \ uuid \
ctrlCHandler \
timer \
- priority
+ priority \
+ fileLock
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cpp/test/IceUtil/fileLock/.depend b/cpp/test/IceUtil/fileLock/.depend new file mode 100644 index 00000000000..d7e10d3f336 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/.depend @@ -0,0 +1 @@ +Client$(OBJEXT): Client.cpp $(includedir)/IceUtil/FileUtil.h $(includedir)/IceUtil/Config.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h ../../include/TestCommon.h diff --git a/cpp/test/IceUtil/fileLock/.gitignore b/cpp/test/IceUtil/fileLock/.gitignore new file mode 100644 index 00000000000..9e130277026 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/.gitignore @@ -0,0 +1,6 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +client +clientFail +run.pid diff --git a/cpp/test/IceUtil/fileLock/Client.cpp b/cpp/test/IceUtil/fileLock/Client.cpp new file mode 100644 index 00000000000..025eafd7e5d --- /dev/null +++ b/cpp/test/IceUtil/fileLock/Client.cpp @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/FileUtil.h> +#include <IceUtil/Exception.h> +#include <TestCommon.h> + +using namespace IceUtil; +using namespace std; + +int +main(int argc, char** argv) +{ + { + IceUtilInternal::FileLockPtr lock; + try + { + lock = new IceUtilInternal::FileLock("file.lock"); + test(true); + } + catch(const exception& ex) + { + cerr << "exception:\n" << ex.what() << endl; + test(false); + } + catch(...) + { + test(false); + } + + cout << "File lock acquired.\n" + << "Enter some input and press enter, to release the lock and terminate the program." << endl; + // + // Block the test waiting for IO, so the file lock is preserved. + // + string dummy; + cin >> dummy; + } + cout << "File lock released." << endl; + return EXIT_SUCCESS; +} diff --git a/cpp/test/IceUtil/fileLock/ClientFail.cpp b/cpp/test/IceUtil/fileLock/ClientFail.cpp new file mode 100644 index 00000000000..6af48475f31 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/ClientFail.cpp @@ -0,0 +1,57 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/FileUtil.h> +#include <IceUtil/Exception.h> +#include <TestCommon.h> + +using namespace IceUtil; +using namespace std; + +int +main(int argc, char** argv) +{ + IceUtilInternal::FileLockPtr lock; + try + { + lock = new IceUtilInternal::FileLock("file.lock"); + test(false); + } + catch(const IceUtil::FileLockException&) + { + cout << "File lock not acquired." << endl; +// +// Try to read the pid of the lock owner from +// the lock file. +// +// In windows we don't write pid to lock files. +// +#ifndef _WIN32 + IceUtilInternal::ifstream is(string("file.lock")); + if(!is.good()) + { + test(false); + } + string pid; + is >> pid; + test(pid.size() != 0); + cout << "Lock owned by: " << pid << endl; +#endif + } + catch(const exception& ex) + { + cerr << "exception:\n" << ex.what() << endl; + test(false); + } + catch(...) + { + test(false); + } + return EXIT_SUCCESS; +} diff --git a/cpp/test/IceUtil/fileLock/Makefile b/cpp/test/IceUtil/fileLock/Makefile new file mode 100644 index 00000000000..92c950c4b30 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/Makefile @@ -0,0 +1,38 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client +CLIENTF = clientFail + +TARGETS = $(CLIENT) $(CLIENTF) + +OBJS = Client.o +OBJFS = ClientFail.o + +SRCS = $(OBJS:.o=.cpp) + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include $(CPPFLAGS) + +$(CLIENT): $(OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(BASELIBS) + + +$(CLIENTF): $(OBJFS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJFS) $(BASELIBS) + +clean:: + -rm -f run.pid + +include .depend diff --git a/cpp/test/IceUtil/fileLock/Makefile.mak b/cpp/test/IceUtil/fileLock/Makefile.mak new file mode 100644 index 00000000000..3d1fe8e05c3 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/Makefile.mak @@ -0,0 +1,43 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+CLIENTF = clientFail.exe
+
+TARGETS = $(CLIENT) $(CLIENTF)
+
+OBJS = Client.obj
+OBJFS = ClientFail.obj
+
+SRCS = $(OBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+!endif
+
+$(CLIENT): $(OBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(BASELIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+$(CLIENTF): $(OBJFS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(OBJFS) $(PREOUT)$@ $(PRELIBS)$(BASELIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q run.pid
+
+!include .depend
\ No newline at end of file diff --git a/cpp/test/IceUtil/fileLock/run.py b/cpp/test/IceUtil/fileLock/run.py new file mode 100755 index 00000000000..67cf14acc21 --- /dev/null +++ b/cpp/test/IceUtil/fileLock/run.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +print "testing process file lock...", +sys.stdout.flush() + +client = os.path.join(os.getcwd(), "client") +clientFail = os.path.join(os.getcwd(), "clientFail") + +clientExe = TestUtil.startClient(client, "", None, None, False) +clientExe.expect('File lock acquired.\.*') + +# +# Ensure that the file lock exists. +# +assert(os.path.exists("file.lock")); + +clientFailExe = TestUtil.startClient(clientFail, "", None, None, False) +clientFailExe.expect('File lock not acquired.') + +# send some output to client to terminate it. +clientExe.sendline('go') +clientExe.expect('File lock released.') + +# +# Ensure that the file lock was removed. +# +assert(not os.path.exists("file.lock")); + +# The lock is gone try to acquire it again. +clientExe = TestUtil.startClient(client, "", None, None, False) +clientExe.expect('File lock acquired.\.*') +clientExe.sendline('go') +clientExe.expect('File lock released.') + +print "ok"
\ No newline at end of file |