diff options
Diffstat (limited to 'cpp')
30 files changed, 906 insertions, 132 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index a4f4c564177..bc9d442f3d4 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -1,6 +1,10 @@ Changes since version 3.2.X (binary incompatible) ------------------------------------------------- +- While resolving replica group endpoints, the IceGrig locator + implementation does not wait anymore for adapter activation if + another adapter is already active. + - Fixed a bug in FreezeScript that caused a failure when a script attempted to access the 'length' member of a string value. diff --git a/cpp/config/Make.rules.mak.icesl b/cpp/config/Make.rules.mak.icesl new file mode 100644 index 00000000000..bc859fdb443 --- /dev/null +++ b/cpp/config/Make.rules.mak.icesl @@ -0,0 +1,107 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +# +# Select an installation base directory. The directory will be created +# if it does not exist. +# +prefix = C:\IceSL-$(VERSION) + +# +# Define OPTIMIZE as yes if you want to build with +# optimization. Otherwise build with debug information. +# +OPTIMIZE = yes + +# +# Specify your C++ compiler. Supported values are: +# VC80, VC80_EXPRESS +# +!if "$(CPP_COMPILER)" == "" +CPP_COMPILER = VC80 +!endif + +# +# For VC80 and VC80 Express it is necessary to set the location of the +# manifest tool. This must be the 6.x version of mt.exe, not the 5.x +# version! +# +# For VC80 Express mt.exe 6.x is provided by the Windows Platform SDK. +# It is necessary to set the location of the Platform SDK through the +# PDK_HOME environment variable (see INSTALL.WINDOWS for details). +# +!if "$(CPP_COMPILER)" == "VC80" +MT = "$(VS80COMNTOOLS)bin\mt.exe" +!elseif "$(CPP_COMPILER)" == "VC80_EXPRESS" +MT = "$(PDK_HOME)\bin\mt.exe" +!endif + + +# ---------------------------------------------------------------------- +# Don't change anything below this line! +# ---------------------------------------------------------------------- + +STATICLIBS = yes + +SHELL = /bin/sh + +bindir = $(top_srcdir)\bin +libdir = $(top_srcdir)\lib +includedir = $(top_srcdir)\include +slicedir = $(top_srcdir)\slice + +install_bindir = $(prefix)\bin + +OBJEXT = .obj + +SETARGV = setargv.obj + +!include $(top_srcdir)/config/Make.rules.msvc + + +libsubdir = lib + +!if "$(OPTIMIZE)" != "yes" +LIBSUFFIX = $(LIBSUFFIX)d +!endif + + +CPPFLAGS = $(CPPFLAGS) -I$(includedir) + + +LDFLAGS = $(LDFLAGS) $(LDPLATFORMFLAGS) $(CXXFLAGS) + +SLICEPARSERLIB = $(libdir)\slice$(LIBSUFFIX).lib + + +EVERYTHING = all clean install + +.SUFFIXES: +.SUFFIXES: .ice .cpp .c .obj + +.cpp.obj:: + $(CXX) /c $(CPPFLAGS) $(CXXFLAGS) $< + +.c.obj: + $(CC) /c $(CPPFLAGS) $(CFLAGS) $< + + +all:: $(SRCS) $(TARGETS) + +!if "$(TARGETS)" != "" + +clean:: + -del /q $(TARGETS) + +!endif + +clean:: + -del /q *.obj *.bak *.ilk *.exp *.pdb *.tds + +install:: diff --git a/cpp/demo/Freeze/library/Scanner.l b/cpp/demo/Freeze/library/Scanner.l index ec62ae3ea7b..9205dc90471 100644 --- a/cpp/demo/Freeze/library/Scanner.l +++ b/cpp/demo/Freeze/library/Scanner.l @@ -30,6 +30,7 @@ WS [ \t\v\f\r] NL [\n] %option noyywrap +%option always-interactive %% diff --git a/cpp/demo/Freeze/phonebook/Scanner.l b/cpp/demo/Freeze/phonebook/Scanner.l index 789b6a9f60b..006a823e9bf 100644 --- a/cpp/demo/Freeze/phonebook/Scanner.l +++ b/cpp/demo/Freeze/phonebook/Scanner.l @@ -30,6 +30,7 @@ WS [ \t\v\f\r] NL [\n] %option noyywrap +%option always-interactive %% diff --git a/cpp/demo/Freeze/transform/.gitignore b/cpp/demo/Freeze/transform/.gitignore new file mode 100644 index 00000000000..a60cb736a63 --- /dev/null +++ b/cpp/demo/Freeze/transform/.gitignore @@ -0,0 +1,17 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +create +read +readnew +recreate +ContactData.cpp +NewContactData.cpp +ContactData.h +NewContactData.h +db/* +dbnew/* +Contacts.h +Contacts.cpp +NewContacts.h +NewContacts.cpp diff --git a/cpp/demo/Freeze/transform/Makefile b/cpp/demo/Freeze/transform/Makefile index 8b3ce15ea4a..18e4fe89a47 100644 --- a/cpp/demo/Freeze/transform/Makefile +++ b/cpp/demo/Freeze/transform/Makefile @@ -62,7 +62,8 @@ NewContacts.h NewContacts.cpp: NewContactData.ice $(SLICE2FREEZE) cleandb:: -rm -f db/* dbnew/* -clean:: cleandb +clean:: + -rm -f db/* dbnew/* -rm -f Contacts.h Contacts.cpp NewContacts.h NewContacts.cpp include .depend diff --git a/cpp/demo/book/lifecycle/Scanner.l b/cpp/demo/book/lifecycle/Scanner.l index dd9ba8e499c..cfe00c3214a 100644 --- a/cpp/demo/book/lifecycle/Scanner.l +++ b/cpp/demo/book/lifecycle/Scanner.l @@ -30,6 +30,7 @@ WS [ \t\v\f\r] NL [\n] %option noyywrap +%option always-interactive %% diff --git a/cpp/iceslmakedist.py b/cpp/iceslmakedist.py new file mode 100755 index 00000000000..b04ba431ef5 --- /dev/null +++ b/cpp/iceslmakedist.py @@ -0,0 +1,447 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2007 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, shutil, fnmatch, re, glob + +# +# Program usage. +# +def usage(): + print "Usage: " + sys.argv[0] + " [options] [tag]" + print + print "Options:" + print "-h Show this message." + print "-v Be verbose." + print + print "If no tag is specified, HEAD is used." + +# +# Find files matching a pattern. +# +def find(path, patt): + result = [ ] + files = os.listdir(path) + for x in files: + fullpath = os.path.join(path, x); + if os.path.isdir(fullpath) and not os.path.islink(fullpath): + result.extend(find(fullpath, patt)) + elif fnmatch.fnmatch(x, patt): + result.append(fullpath) + return result + +# +# Comment out rules in a Makefile. +# +def fixMakefile(file, target): + origfile = file + ".orig" + os.rename(file, origfile) + oldMakefile = open(origfile, "r") + newMakefile = open(file, "w") + origLines = oldMakefile.readlines() + + doComment = 0 + doCheck = 0 + newLines = [] + for x in origLines: + # + # If the rule contains the target string, then + # comment out this rule. + # + if not x.startswith("\t") and x.find(target) != -1 and x.find(target + ".o") == -1: + doComment = 1 + # + # If the line starts with "clean::", then check + # the following lines and comment out any that + # contain the target string. + # + elif x.startswith("clean::"): + doCheck = 1 + # + # Stop when we encounter an empty line. + # + elif len(x.strip()) == 0: + doComment = 0 + doCheck = 0 + + if doComment or (doCheck and x.find(target) != -1): + x = "#" + x + newLines.append(x) + + newMakefile.writelines(newLines) + newMakefile.close() + oldMakefile.close() + os.remove(origfile) + +# +# Remove lines containing a keyword from a file. +# +def editFile(file, target): + origfile = file + ".orig" + os.rename(file, origfile) + oldFile = open(origfile, "r") + newFile = open(file, "w") + origLines = oldFile.readlines() + + newLines = [] + for x in origLines: + if x.find(target) == -1: + newLines.append(x) + + newFile.writelines(newLines) + newFile.close() + oldFile.close() + os.remove(origfile) + +# +# Comment out implicit parser/scanner rules in config/Make.rules. +# +def fixMakeRules(file): + origfile = file + ".orig" + os.rename(file, origfile) + oldFile = open(origfile, "r") + newFile = open(file, "w") + origLines = oldFile.readlines() + + doComment = 0 + newLines = [] + for x in origLines: + if x.find("%.y") != -1 or x.find("%.l") != -1: + doComment = 1 + # + # Stop when we encounter an empty line. + # + elif len(x.strip()) == 0: + doComment = 0 + + if doComment: + x = "#" + x + newLines.append(x) + + newFile.writelines(newLines) + newFile.close() + oldFile.close() + os.remove(origfile) + +# +# Fix version in README, INSTALL files +# +def fixVersion(files, version): + for file in files: + origfile = file + ".orig" + os.rename(file, origfile) + oldFile = open(origfile, "r") + newFile = open(file, "w") + newFile.write(re.sub("@ver@", version, oldFile.read())) + newFile.close() + oldFile.close() + os.remove(origfile) + +# +# Check arguments +# +tag = "HEAD" +verbose = 0 +for x in sys.argv[1:]: + if x == "-h": + usage() + sys.exit(0) + elif x == "-v": + verbose = 1 + elif x.startswith("-"): + print sys.argv[0] + ": unknown option `" + x + "'" + print + usage() + sys.exit(1) + else: + tag = "-r" + x + +# +# Remove any existing "dist" directory and create a new one. +# +distdir = "dist" +if os.path.exists(distdir): + shutil.rmtree(distdir) +os.mkdir(distdir) +os.mkdir(os.path.join(distdir, "icesl")) +tmpdir = "tmp" +os.mkdir(os.path.join(distdir, tmpdir)) + +# +# Export sources from git. +# +print "Checking out sources " + tag + "..." +if verbose: + quiet = "-v" +else: + quiet = "" +os.system("git archive " + quiet + " " + tag + " . | (cd dist/icesl && tar xf -)") + +os.chdir(os.path.join("..", "sl", "src")) +os.system("git archive " + quiet + " " + tag + " . | (cd ../../cpp/dist/tmp && tar xf -)") + +os.chdir(os.path.join("..", "..", "distribution", "src", "icesl")) +os.system("git archive " + quiet + " " + tag + " . | (cd ../../../cpp/dist/tmp && tar xf -)") + +os.chdir(os.path.join("..", "..", "..", "cpp", distdir)) + +# +# Copy IceSL specific install files. +# +print "Copying icesl install files..." +shutil.copyfile(os.path.join("tmp", "ICE_LICENSE"), os.path.join("icesl", "ICE_LICENSE")) +shutil.copyfile(os.path.join("tmp", "README"), os.path.join("icesl", "README")) +shutil.copyfile(os.path.join("tmp", "INSTALL"), os.path.join("icesl", "INSTALL")) + +# +# Move Make.rules.mak.icesl +# +shutil.move(os.path.join("icesl", "config", "Make.rules.mak.icesl"), os.path.join("icesl", "config", "Make.rules.mak")) + +# +# Generate bison files. +# +print "Generating bison files..." +cwd = os.getcwd() +grammars = find("icesl", "*.y") +for x in grammars: + # + # Change to the directory containing the file. + # + (dir,file) = os.path.split(x) + os.chdir(dir) + (base,ext) = os.path.splitext(file) + # + # Run gmake to create the output files. + # + if verbose: + quiet = "" + else: + quiet = "-s" + if file == "cexp.y": + os.system("gmake " + quiet + " cexp.c") + else: + os.system("gmake " + quiet + " " + base + ".cpp") + # + # Edit the Makefile to comment out the grammar rules. + # + fixMakefile("Makefile.mak", base) + + os.chdir(cwd) + +# +# Generate flex files. +# +print "Generating flex files..." +scanners = find("icesl", "*.l") +for x in scanners: + # + # Change to the directory containing the file. + # + (dir,file) = os.path.split(x) + os.chdir(dir) + (base,ext) = os.path.splitext(file) + # + # Run gmake to create the output files. + # + if verbose: + quiet = "" + else: + quiet = "-s" + os.system("gmake " + quiet + " " + base + ".cpp") + # + # Edit the Makefile to comment out the flex rules. + # + fixMakefile("Makefile.mak", base) + + os.chdir(cwd) + +# +# Remove files. +# +print "Removing unnecessary files..." +filesToRemove = [ \ + os.path.join("icesl", "CHANGES"), \ + os.path.join("icesl", "INSTALL.HP-UX"), \ + os.path.join("icesl", "INSTALL.MACOSX"), \ + os.path.join("icesl", "INSTALL.SOLARIS"), \ + os.path.join("icesl", "INSTALL.WINDOWS"), \ + os.path.join("icesl", "INSTALL.LINUX"), \ + os.path.join("icesl", "iceemakedist.py"), \ + os.path.join("icesl", "iceslmakedist.py"), \ + os.path.join("icesl", "WINDOWS_SERVICE.txt"), \ + os.path.join("icesl", "makedist.py"), \ + os.path.join("icesl", "fixCopyright.py"), \ + os.path.join("icesl", "fixVersion.py"), \ + os.path.join("icesl", "allTests.py"), \ + os.path.join("icesl", "allDemos.py"), \ + os.path.join("icesl", "config", "convertssl.py"), \ + os.path.join("icesl", "config", "findSliceFiles.py"), \ + os.path.join("icesl", "config", "glacier2router.cfg"), \ + os.path.join("icesl", "config", "ice_ca.cnf"), \ + os.path.join("icesl", "config", "icegridnode.cfg"), \ + os.path.join("icesl", "config", "icegridregistry.cfg"), \ + os.path.join("icesl", "config", "icegrid-slice.3.1.ice.gz"), \ + os.path.join("icesl", "config", "makedepend.py"), \ + os.path.join("icesl", "config", "makegitignore.py"), \ + os.path.join("icesl", "config", "makeprops.py"), \ + os.path.join("icesl", "config", "Make.rules"), \ + os.path.join("icesl", "config", "Make.rules.AIX"), \ + os.path.join("icesl", "config", "Make.rules.bcc"), \ + os.path.join("icesl", "config", "Make.rules.Darwin"), \ + os.path.join("icesl", "config", "Make.rules.FreeBSD"), \ + os.path.join("icesl", "config", "Make.rules.HP-UX"), \ + os.path.join("icesl", "config", "Make.rules.Linux"), \ + os.path.join("icesl", "config", "Make.rules.OSF1"), \ + os.path.join("icesl", "config", "Make.rules.SunOS"), \ + os.path.join("icesl", "config", "Make.rules.icee"), \ + os.path.join("icesl", "config", "Make.rules.mak.icee"), \ + os.path.join("icesl", "config", "PropertyNames.xml"), \ + os.path.join("icesl", "config", "templates.xml"), \ + os.path.join("icesl", "config", "upgradeicegrid.py"), \ + os.path.join("icesl", "config", "upgradeicestorm.py"), \ + ] +filesToRemove.extend(find("icesl", ".gitignore")) +filesToRemove.extend(find("icesl", "Makefile")) +for x in filesToRemove: + os.remove(x) +shutil.rmtree(os.path.join("icesl", "demo")) +shutil.rmtree(os.path.join("icesl", "doc")) +shutil.rmtree(os.path.join("icesl", "test")) +shutil.rmtree(os.path.join("icesl", "include", "Freeze")) +shutil.rmtree(os.path.join("icesl", "include", "Glacier2")) +shutil.rmtree(os.path.join("icesl", "include", "Ice")) +shutil.rmtree(os.path.join("icesl", "include", "IceBox")) +shutil.rmtree(os.path.join("icesl", "include", "IceGrid")) +shutil.rmtree(os.path.join("icesl", "include", "IcePatch2")) +shutil.rmtree(os.path.join("icesl", "include", "IceSSL")) +shutil.rmtree(os.path.join("icesl", "include", "IceStorm")) +shutil.rmtree(os.path.join("icesl", "include", "IceXML")) +shutil.rmtree(os.path.join("icesl", "src", "ca")) +shutil.rmtree(os.path.join("icesl", "src", "Freeze")) +shutil.rmtree(os.path.join("icesl", "src", "FreezeScript")) +shutil.rmtree(os.path.join("icesl", "src", "Glacier2")) +shutil.rmtree(os.path.join("icesl", "src", "Ice")) +shutil.rmtree(os.path.join("icesl", "src", "IceBox")) +shutil.rmtree(os.path.join("icesl", "src", "IceGrid")) +shutil.rmtree(os.path.join("icesl", "src", "IcePatch2")) +shutil.rmtree(os.path.join("icesl", "src", "iceserviceinstall")) +shutil.rmtree(os.path.join("icesl", "src", "IceSSL")) +shutil.rmtree(os.path.join("icesl", "src", "IceStorm")) +shutil.rmtree(os.path.join("icesl", "src", "IceXML")) +shutil.rmtree(os.path.join("icesl", "src", "slice2cpp")) +shutil.rmtree(os.path.join("icesl", "src", "slice2cppe")) +shutil.rmtree(os.path.join("icesl", "src", "slice2cs")) +shutil.rmtree(os.path.join("icesl", "src", "slice2docbook")) +shutil.rmtree(os.path.join("icesl", "src", "slice2freeze")) +shutil.rmtree(os.path.join("icesl", "src", "slice2freezej")) +shutil.rmtree(os.path.join("icesl", "src", "slice2html")) +shutil.rmtree(os.path.join("icesl", "src", "slice2java")) +shutil.rmtree(os.path.join("icesl", "src", "slice2javae")) +shutil.rmtree(os.path.join("icesl", "src", "slice2py")) +shutil.rmtree(os.path.join("icesl", "src", "slice2rb")) + +# +# Get IceSL version. +# +config = open(os.path.join("tmp", "Ice", "AssemblyInfo.cs"), "r") +version = re.search("AssemblyVersion.*\"([0-9\.]*)\".*", config.read()).group(1) + +print "Fixing makefiles..." + +for makeRulesName in [os.path.join("icesl", "config", "Make.rules.mak")]: + fixMakeRules(makeRulesName) + makeRules = open(makeRulesName, "r") + lines = makeRules.readlines() + makeRules.close() + for i in range(len(lines)): + if lines[i].find("prefix") == 0: + lines[i] = lines[i].replace("IceE-$(VERSION)", "IceE-" + version) + makeRules = open(makeRulesName, "w") + makeRules.writelines(lines) + makeRules.close() + + +# +# Change SUBDIRS and INSTALL_SUBDIRS in top-level Makefile. +# +for makeFileName in [os.path.join("icesl", "Makefile.mak")]: + makeFile = open(makeFileName, "r") + lines = makeFile.readlines() + makeFile.close() + for i in range(len(lines)): + if lines[i].find("SUBDIRS") == 0: + lines[i] = "SUBDIRS = src\n" + if lines[i].find("INSTALL_SUBDIRS") == 0: + lines[i] = "INSTALL_SUBDIRS = $(install_bindir) $(install_libdir)\n" + makeFile = open(makeFileName, "w") + makeFile.writelines(lines) + makeFile.close() + +# +# Disable install targets for libIceUtil, libSlice. +# +for makeFileName in [os.path.join("icesl", "src", "IceUtil", "Makefile.mak"), \ + os.path.join("icesl", "src", "Slice", "Makefile.mak")]: + makeFile = open(makeFileName, "r") + lines = makeFile.readlines() + makeFile.close() + + doComment = 0 + for i in range(len(lines)): + if lines[i].find("install::") == 0: + doComment = 1 + elif len(lines[i].strip()) == 0: + doComment = 0 + elif doComment: + lines[i] = "#" + lines[i] + + makeFile = open(makeFileName, "w") + makeFile.writelines(lines) + makeFile.close() + +# +# Fix versions in README and INSTALL files. +# +print "Fixing version in README and INSTALL files..." +fixVersion(find("icesl", "README*"), version) +fixVersion(find("icesl", "INSTALL*"), version) + +# +# Create archives. +# +print "Creating distribution..." +icever = "IceSL-trans-" + version +os.rename("icesl", icever) +if verbose: + quiet = "v" +else: + quiet = "" +os.system("chmod -R u+rw,go+r . " + icever) +os.system("find " + icever + " -type d -exec chmod a+x {} \\;") +os.system("tar c" + quiet + "f " + icever + ".tar " + icever) +os.system("gzip -9 " + icever + ".tar") +if verbose: + quiet = "" +else: + quiet = "q" +os.system("zip -9r" + quiet + " " + icever + ".zip " + icever) + +# +# Copy files (README, etc.). +# +#shutil.copyfile(os.path.join(icever, "CHANGES"), "Ice-" + version + "-CHANGES") + +# +# Done. +# +print "Cleaning up..." +shutil.rmtree(icever) +shutil.rmtree(tmpdir) +print "Done." diff --git a/cpp/include/Freeze/.gitignore b/cpp/include/Freeze/.gitignore index 9ad9aba73e2..501ab8b0aca 100644 --- a/cpp/include/Freeze/.gitignore +++ b/cpp/include/Freeze/.gitignore @@ -13,3 +13,4 @@ Evictor.h TransactionalEvictor.h Transaction.h Catalog.h +CatalogIndexList.h diff --git a/cpp/include/Freeze/Initialize.h b/cpp/include/Freeze/Initialize.h index 3675969e485..e71e051ab74 100644 --- a/cpp/include/Freeze/Initialize.h +++ b/cpp/include/Freeze/Initialize.h @@ -71,6 +71,26 @@ createTransactionalEvictor(const Ice::ObjectAdapterPtr& adapter, const std::vector<IndexPtr>& indices = std::vector<IndexPtr>(), bool createDb = true); +// +// TransactionalEvictorDeadlockException propagates through collocation-optimized calls +// The TransactionalEvictor catches and retries on this exception +// +class FREEZE_API TransactionalEvictorDeadlockException : public Ice::LocalException +{ +public: + + TransactionalEvictorDeadlockException(const char*, int, const TransactionPtr& = 0); + + virtual ~TransactionalEvictorDeadlockException() throw(); + + virtual std::string ice_name() const; + virtual void ice_print(std::ostream&) const; + virtual Ice::Exception* ice_clone() const; + virtual void ice_throw() const; + + TransactionPtr tx; +}; + FREEZE_API ConnectionPtr createConnection(const Ice::CommunicatorPtr& communicator, const std::string& envName); diff --git a/cpp/src/Freeze/.gitignore b/cpp/src/Freeze/.gitignore index 6010c0e2930..b09bdea2d1e 100644 --- a/cpp/src/Freeze/.gitignore +++ b/cpp/src/Freeze/.gitignore @@ -26,3 +26,4 @@ TransactionalEvictor.h Transaction.h PingObject.h Catalog.cpp +CatalogIndexList.cpp diff --git a/cpp/src/Freeze/ConnectionI.cpp b/cpp/src/Freeze/ConnectionI.cpp index 824fc167c9c..10af58cdbbe 100644 --- a/cpp/src/Freeze/ConnectionI.cpp +++ b/cpp/src/Freeze/ConnectionI.cpp @@ -56,7 +56,7 @@ Freeze::ConnectionI::removeMapIndex(const string& mapName, const string& indexNa } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), _transaction); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/EvictorIteratorI.cpp b/cpp/src/Freeze/EvictorIteratorI.cpp index 401b17750fd..0ff5f418569 100644 --- a/cpp/src/Freeze/EvictorIteratorI.cpp +++ b/cpp/src/Freeze/EvictorIteratorI.cpp @@ -23,7 +23,7 @@ Freeze::EvictorIteratorI::EvictorIteratorI(ObjectStoreBase* store, const Transac _key(1024), _more(store != 0), _initialized(false), - _tx(tx == 0 ? 0 : tx->dbTxn()) + _tx(tx) { _batchIterator = _batch.end(); } @@ -74,6 +74,8 @@ Freeze::EvictorIteratorI::nextBatch() CommunicatorPtr communicator = _store->communicator(); + DbTxn* txn = _tx == 0 ? 0: _tx->dbTxn(); + try { for(;;) @@ -108,7 +110,7 @@ Freeze::EvictorIteratorI::nextBatch() dbKey.set_size(static_cast<u_int32_t>(firstKey.size())); } - _store->db()->cursor(_tx, &dbc, 0); + _store->db()->cursor(txn, &dbc, 0); bool done = false; do @@ -217,7 +219,7 @@ Freeze::EvictorIteratorI::nextBatch() } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), _tx); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/EvictorIteratorI.h b/cpp/src/Freeze/EvictorIteratorI.h index 41fed5db623..4e3e540d49c 100644 --- a/cpp/src/Freeze/EvictorIteratorI.h +++ b/cpp/src/Freeze/EvictorIteratorI.h @@ -45,7 +45,7 @@ private: std::vector<Ice::Identity> _batch; bool _more; bool _initialized; - DbTxn* _tx; + TransactionIPtr _tx; }; } diff --git a/cpp/src/Freeze/IndexI.cpp b/cpp/src/Freeze/IndexI.cpp index 29b89cffcdb..f8ca1b32c7d 100644 --- a/cpp/src/Freeze/IndexI.cpp +++ b/cpp/src/Freeze/IndexI.cpp @@ -174,7 +174,7 @@ Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -294,7 +294,7 @@ Freeze::IndexI::untypedCount(const Key& bytes) const } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index 25b0e088c94..669db800600 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -260,7 +260,7 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -1476,7 +1476,7 @@ Freeze::MapHelperI::destroy() } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -1798,7 +1798,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) int result = 0; - DbTxn * txn = connection->dbTxn(); + DbTxn* txn = connection->dbTxn(); try { @@ -1892,7 +1892,7 @@ Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) } catch(const DbDeadlockException& dx) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction()); } catch(const DbException& dx) { diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 1d554c6bc2a..53f1c6140ac 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -255,7 +255,7 @@ Freeze::ObjectStoreBase::dbHasObject(const Identity& ident, const TransactionIPt if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // Else, try again } @@ -406,7 +406,7 @@ Freeze::ObjectStoreBase::load(const Identity& ident, const TransactionIPtr& tran out << "Deadlock in Freeze::ObjectStoreBase::load while searching \"" << _evictor->filename() + "/" + _dbName << "\""; } - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -458,7 +458,7 @@ Freeze::ObjectStoreBase::update(const Identity& ident, const ObjectRecord& rec, out << "Deadlock in Freeze::ObjectStoreBase::update while updating \"" << _evictor->filename() + "/" + _dbName << "\""; } - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { @@ -511,7 +511,7 @@ Freeze::ObjectStoreBase::insert(const Identity& ident, const ObjectRecord& rec, } if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // // Otherwise, try again @@ -559,7 +559,7 @@ Freeze::ObjectStoreBase::remove(const Identity& ident, const TransactionIPtr& tr } if(tx != 0) { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } // // Otherwise, try again diff --git a/cpp/src/Freeze/SharedDb.cpp b/cpp/src/Freeze/SharedDb.cpp index 57018ec6efc..ab651e267c2 100644 --- a/cpp/src/Freeze/SharedDb.cpp +++ b/cpp/src/Freeze/SharedDb.cpp @@ -198,6 +198,7 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD assert(0); throw DatabaseException(__FILE__, __LINE__, "Catalog already opened"); } + newCatalog->_inMap = true; mapKey.dbName = _catalogIndexListName; @@ -212,6 +213,8 @@ Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedD assert(0); throw DatabaseException(__FILE__, __LINE__, "CatalogIndexList already opened"); } + newCatalogIndexList->_inMap = true; + catalog = newCatalog.release(); catalogIndexList = newCatalogIndexList.release(); @@ -572,7 +575,7 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey, } else { - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) @@ -615,7 +618,8 @@ Freeze::SharedDb::SharedDb(const MapKey& mapKey, const string& keyTypeId, const _mapKey(mapKey), _key(keyTypeId), _value(valueTypeId), - _refCount(0) + _refCount(0), + _inMap(false) { _trace = _mapKey.communicator->getProperties()->getPropertyAsInt("Freeze.Trace.Map"); diff --git a/cpp/src/Freeze/TransactionI.cpp b/cpp/src/Freeze/TransactionI.cpp index 725953a4c6c..e8f1bdb2932 100644 --- a/cpp/src/Freeze/TransactionI.cpp +++ b/cpp/src/Freeze/TransactionI.cpp @@ -137,10 +137,12 @@ Freeze::TransactionI::rollbackInternal(bool warning) out << "failed to rollback transaction " << hex << txnId << dec << ": " << dx.what(); } + DeadlockException deadlockException(__FILE__, __LINE__, dx.what(), this); + postCompletion(false, true); // After postCompletion is called the transaction may be // dead. Beware! - throw DeadlockException(__FILE__, __LINE__, dx.what()); + throw deadlockException; } catch(const ::DbException& dx) { diff --git a/cpp/src/Freeze/TransactionalEvictorContext.cpp b/cpp/src/Freeze/TransactionalEvictorContext.cpp index 369c6fd1763..2c68a4eae2e 100644 --- a/cpp/src/Freeze/TransactionalEvictorContext.cpp +++ b/cpp/src/Freeze/TransactionalEvictorContext.cpp @@ -19,6 +19,49 @@ using namespace std; using namespace Freeze; using namespace Ice; +// +// TransactionalEvictorDeadlockException +// + +Freeze::TransactionalEvictorDeadlockException::TransactionalEvictorDeadlockException(const char* file, int line, const TransactionPtr& transaction) : + Ice::LocalException(file, line), + tx(transaction) +{ +} + +Freeze::TransactionalEvictorDeadlockException::~TransactionalEvictorDeadlockException() throw() +{ +} + +string +Freeze::TransactionalEvictorDeadlockException::ice_name() const +{ + return "Freeze::TransactionalEvictorDeadlockException"; +} + +Ice::Exception* +Freeze::TransactionalEvictorDeadlockException::ice_clone() const +{ + return new TransactionalEvictorDeadlockException(*this); +} + +void +Freeze::TransactionalEvictorDeadlockException::ice_throw() const +{ + throw *this; +} + +void +Freeze::TransactionalEvictorDeadlockException::ice_print(ostream& out) const +{ + Ice::Exception::ice_print(out); + out << ":\ntransactional evictor deadlock exception"; +} + + +// +// TransactionalEvictorContext +// Freeze::TransactionalEvictorContext::TransactionalEvictorContext(const SharedDbEnvPtr& dbEnv) : _tx((new ConnectionI(dbEnv))->beginTransactionI()), @@ -115,6 +158,11 @@ Freeze::TransactionalEvictorContext::checkDeadlockException() { _deadlockException->ice_throw(); } + + if(_nestedCallDeadlockException.get() != 0) + { + _nestedCallDeadlockException->ice_throw(); + } } bool @@ -157,6 +205,15 @@ Freeze::TransactionalEvictorContext::exception(const std::exception& ex) _deadlockException.reset(dynamic_cast<DeadlockException*>(dx->ice_clone())); return false; } + + const TransactionalEvictorDeadlockException* edx = + dynamic_cast<const TransactionalEvictorDeadlockException*>(&ex); + if(edx != 0 && _owner == IceUtil::ThreadControl()) + { + _nestedCallDeadlockException.reset(dynamic_cast<TransactionalEvictorDeadlockException*>(edx->ice_clone())); + return false; + } + return true; } diff --git a/cpp/src/Freeze/TransactionalEvictorContext.h b/cpp/src/Freeze/TransactionalEvictorContext.h index 12b2a2e8765..9c5e16a8348 100644 --- a/cpp/src/Freeze/TransactionalEvictorContext.h +++ b/cpp/src/Freeze/TransactionalEvictorContext.h @@ -14,6 +14,7 @@ #include <Freeze/TransactionalEvictor.h> #include <Freeze/EvictorStorage.h> #include <Freeze/EvictorI.h> +#include <Freeze/Initialize.h> #include <IceUtil/IceUtil.h> namespace Freeze @@ -147,6 +148,7 @@ private: bool _rollbackOnly; std::auto_ptr<DeadlockException> _deadlockException; + std::auto_ptr<TransactionalEvictorDeadlockException> _nestedCallDeadlockException; // // Protected by this diff --git a/cpp/src/Freeze/TransactionalEvictorI.cpp b/cpp/src/Freeze/TransactionalEvictorI.cpp index 5ce3ed9dab6..8951cde8e0f 100644 --- a/cpp/src/Freeze/TransactionalEvictorI.cpp +++ b/cpp/src/Freeze/TransactionalEvictorI.cpp @@ -394,10 +394,11 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) { servantHolder.init(ctx, current, store); } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { + assert(dx.tx == ctx->transaction()); ctx->deadlockException(); - throw; + throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx); } sample = servantHolder.servant(); } @@ -496,6 +497,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) do { + TransactionPtr tx; + try { if(ownCtx) @@ -504,7 +507,8 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) } CtxHolder ctxHolder(ownCtx, ctx, _dbEnv); - + tx = ctx->transaction(); + try { TransactionalEvictorContext::ServantHolder sh; @@ -540,7 +544,7 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) if(dispatchStatus == DispatchAsync) { // - // May throw DeadlockException + // May throw DeadlockException or TransactionalEvictorDeadlockException // ctx->checkDeadlockException(); @@ -565,9 +569,12 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) // servant holder destructor runs here and may throw (if !rolled back) // } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { - ctx->deadlockException(); + if(dx.tx == tx) + { + ctx->deadlockException(); + } throw; } catch(...) @@ -583,9 +590,20 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) // commit occurs here (when ownCtx) // } - catch(const DeadlockException&) + catch(const DeadlockException& dx) { - if(ownCtx) + if(ownCtx && dx.tx == tx) + { + tryAgain = true; + } + else + { + throw TransactionalEvictorDeadlockException(__FILE__, __LINE__, dx.tx); + } + } + catch(const TransactionalEvictorDeadlockException& dx) + { + if(ownCtx && dx.tx == tx) { tryAgain = true; } @@ -594,7 +612,6 @@ Freeze::TransactionalEvictorI::dispatch(Request& request) throw; } } - } while(tryAgain); } diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp index 9158def55ff..b7361dce4a1 100644 --- a/cpp/src/IceGrid/LocatorI.cpp +++ b/cpp/src/IceGrid/LocatorI.cpp @@ -26,53 +26,67 @@ class AMI_Adapter_getDirectProxyI : public AMI_Adapter_getDirectProxy { public: - AMI_Adapter_getDirectProxyI(const LocatorIPtr& locator, const string& id, const LocatorAdapterInfo& adapter) : - _locator(locator), _id(id), _adapter(adapter) + AMI_Adapter_getDirectProxyI(const LocatorI::RequestPtr& request, const string& id) : + _request(request), _id(id) { } virtual void ice_response(const ::Ice::ObjectPrx& obj) { assert(obj); - _locator->getDirectProxyCallback(_adapter.proxy->ice_getIdentity(), obj); + _request->response(_id, obj); } - virtual void ice_exception(const ::Ice::Exception& ex) - { - _locator->getDirectProxyException(_adapter, _id, ex); + virtual void ice_exception(const ::Ice::Exception& e) + { + try + { + e.ice_throw(); + } + catch(const AdapterNotActiveException& ex) + { + if(ex.activatable) + { + _request->activate(_id); + return; + } + } + catch(const Ice::Exception&) + { + } + + _request->exception(_id, e); } private: - const LocatorIPtr _locator; + const LocatorI::RequestPtr _request; const string _id; - const LocatorAdapterInfo _adapter; }; class AMI_Adapter_activateI : public AMI_Adapter_activate { public: - AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id, const LocatorAdapterInfo& adapter) : - _locator(locator), _id(id), _adapter(adapter) + AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id) : + _locator(locator), _id(id) { } virtual void ice_response(const ::Ice::ObjectPrx& obj) { - _locator->getDirectProxyCallback(_adapter.proxy->ice_getIdentity(), obj); + _locator->activateFinished(_id, obj); } virtual void ice_exception(const ::Ice::Exception& ex) { - _locator->getDirectProxyException(_adapter, _id, ex); + _locator->activateException(_id, ex); } private: const LocatorIPtr _locator; const string _id; - const LocatorAdapterInfo _adapter; }; // @@ -205,29 +219,70 @@ LocatorI::Request::execute() ++_lastAdapter; } } - assert(!adapters.empty()); + for(LocatorAdapterInfoSeq::const_iterator p = adapters.begin(); p != adapters.end(); ++p) { - requestAdapter(*p); + p->proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, p->id)); + } +} + +void +LocatorI::Request::activate(const string& id) +{ + // + // Activate the adapter + // + // NOTE: we use a timeout large enough to ensure that the activate() call won't + // timeout if the server hangs in deactivation and/or activation. + // + for(LocatorAdapterInfoSeq::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p) + { + if(p->id == id) + { + _locator->activate(*p, this); + _activating.insert(id); + } + } + + // + // If this is a request for a replica group, don't wait for the activation to + // complete. Instead, we query the next adapter which might be already active. + // + if(_replicaGroup) + { + LocatorAdapterInfo adapter; + { + Lock sync(*this); + if(_lastAdapter != _adapters.end()) + { + adapter = *_lastAdapter; + ++_lastAdapter; + } + } + if(adapter.proxy) + { + adapter.proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, adapter.id)); + } } } void -LocatorI::Request::exception(const Ice::Exception& ex) +LocatorI::Request::exception(const string& id, const Ice::Exception& ex) { LocatorAdapterInfo adapter; { Lock sync(*this); - if(!_exception.get()) { _exception.reset(ex.ice_clone()); } + + _activating.erase(id); if(_lastAdapter == _adapters.end()) { --_count; // Expect one less adapter proxy if there's no more adapters to query. - + // // If we received all the required proxies, it's time to send the // answer back to the client. @@ -236,7 +291,6 @@ LocatorI::Request::exception(const Ice::Exception& ex) { sendResponse(); } - return; } else { @@ -244,16 +298,28 @@ LocatorI::Request::exception(const Ice::Exception& ex) ++_lastAdapter; } } - requestAdapter(adapter); + + if(adapter.proxy) + { + adapter.proxy->getDirectProxy_async(new AMI_Adapter_getDirectProxyI(this, adapter.id)); + } } void -LocatorI::Request::response(const Ice::ObjectPrx& proxy) +LocatorI::Request::response(const string& id, const Ice::ObjectPrx& proxy) { + if(!proxy) + { + exception(id, AdapterNotActiveException()); + return; + } + Lock sync(*this); assert(proxy); - _proxies.push_back(proxy->ice_identity(_locator->getCommunicator()->stringToIdentity("dummy"))); + _activating.erase(id); + + _proxies[id] = proxy->ice_identity(_locator->getCommunicator()->stringToIdentity("dummy")); // // If we received all the required proxies, it's time to send the @@ -266,22 +332,11 @@ LocatorI::Request::response(const Ice::ObjectPrx& proxy) } void -LocatorI::Request::requestAdapter(const LocatorAdapterInfo& adapter) -{ - assert(adapter.proxy); - if(_locator->getDirectProxyRequest(this, adapter)) - { - AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(_locator, _id, adapter); - adapter.proxy->getDirectProxy_async(amiCB); - } -} - -void LocatorI::Request::sendResponse() { if(_proxies.size() == 1) { - _amdCB->ice_response(_proxies.back()); + _amdCB->ice_response(_proxies.begin()->second); } else if(_proxies.empty()) { @@ -304,10 +359,19 @@ LocatorI::Request::sendResponse() { Ice::EndpointSeq endpoints; endpoints.reserve(_proxies.size()); - for(vector<Ice::ObjectPrx>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + for(LocatorAdapterInfoSeq::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p) { - Ice::EndpointSeq edpts = (*p)->ice_getEndpoints(); - endpoints.insert(endpoints.end(), edpts.begin(), edpts.end()); + map<string, Ice::ObjectPrx>::const_iterator q = _proxies.find(p->id); + if(q != _proxies.end()) + { + Ice::EndpointSeq edpts = q->second->ice_getEndpoints(); + endpoints.insert(endpoints.end(), edpts.begin(), edpts.end()); + } + } + + for(set<string>::const_iterator q = _activating.begin(); q != _activating.end(); ++q) + { + _locator->cancelActivate(*q, this); } Ice::ObjectPrx proxy = _locator->getCommunicator()->stringToProxy("dummy:default"); @@ -442,54 +506,55 @@ LocatorI::getLocalQuery(const Ice::Current&) const return _localQuery; } -bool -LocatorI::getDirectProxyRequest(const RequestPtr& request, const LocatorAdapterInfo& adapter) +const Ice::CommunicatorPtr& +LocatorI::getCommunicator() const { - Lock sync(*this); - - // - // Check if there's already pending requests for this adapter. If that's the case, - // we just add this one to the queue. If not, we add it to the queue and initiate - // a call on the adapter to get its direct proxy. - // - PendingRequestsMap::iterator p; - p = _pendingRequests.insert(make_pair(adapter.proxy->ice_getIdentity(), PendingRequests())).first; - p->second.push_back(request); - return p->second.size() == 1; + return _communicator; } void -LocatorI::getDirectProxyException(const LocatorAdapterInfo& adpt, const string& id, const Ice::Exception& ex) +LocatorI::activate(const LocatorAdapterInfo& adapter, const RequestPtr& request) { - try - { - ex.ice_throw(); - } - catch(const AdapterNotActiveException& ex) { - if(ex.activatable) + Lock sync(*this); + + // + // Check if there's already pending requests for this adapter. If that's the case, + // we just add this one to the queue. If not, we add it to the queue and initiate + // a call on the adapter to get its direct proxy. + // + PendingRequestsMap::iterator p; + p = _pendingRequests.insert(make_pair(adapter.id, PendingRequests())).first; + p->second.insert(request); + if(p->second.size() != 1) { - // - // Activate the adapter if it can be activated on demand. - // - // NOTE: we use a timeout large enough to ensure that the - // activate() call won't timeout if the server hangs in - // deactivation and/or activation. - // - AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, id, adpt); - int timeout = adpt.activationTimeout + adpt.deactivationTimeout; - AdapterPrx::uncheckedCast(adpt.proxy->ice_timeout(timeout * 1000))->activate_async(amiCB); return; } } - catch(const Ice::Exception&) + + AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, adapter.id); + int timeout = adapter.activationTimeout + adapter.deactivationTimeout; + AdapterPrx::uncheckedCast(adapter.proxy->ice_timeout(timeout * 1000))->activate_async(amiCB); +} + +void +LocatorI::cancelActivate(const string& id, const RequestPtr& request) +{ + Lock sync(*this); + PendingRequestsMap::iterator p = _pendingRequests.find(id); + if(p != _pendingRequests.end()) { + p->second.erase(request); } +} +void +LocatorI::activateFinished(const string& id, const Ice::ObjectPrx& proxy) +{ PendingRequests requests; { Lock sync(*this); - PendingRequestsMap::iterator p = _pendingRequests.find(adpt.proxy->ice_getIdentity()); + PendingRequestsMap::iterator p = _pendingRequests.find(id); assert(p != _pendingRequests.end()); requests.swap(p->second); _pendingRequests.erase(p); @@ -497,40 +562,24 @@ LocatorI::getDirectProxyException(const LocatorAdapterInfo& adpt, const string& for(PendingRequests::iterator q = requests.begin(); q != requests.end(); ++q) { - (*q)->exception(ex); + (*q)->response(id, proxy); } } void -LocatorI::getDirectProxyCallback(const Ice::Identity& adapterId, const Ice::ObjectPrx& proxy) +LocatorI::activateException(const string& id, const Ice::Exception& ex) { PendingRequests requests; { Lock sync(*this); - PendingRequestsMap::iterator p = _pendingRequests.find(adapterId); + PendingRequestsMap::iterator p = _pendingRequests.find(id); assert(p != _pendingRequests.end()); requests.swap(p->second); _pendingRequests.erase(p); } - if(proxy) - { - for(PendingRequests::const_iterator q = requests.begin(); q != requests.end(); ++q) - { - (*q)->response(proxy); - } - } - else + for(PendingRequests::iterator q = requests.begin(); q != requests.end(); ++q) { - for(PendingRequests::const_iterator q = requests.begin(); q != requests.end(); ++q) - { - (*q)->exception(AdapterNotActiveException()); - } + (*q)->exception(id, ex); } } - -const Ice::CommunicatorPtr& -LocatorI::getCommunicator() const -{ - return _communicator; -} diff --git a/cpp/src/IceGrid/LocatorI.h b/cpp/src/IceGrid/LocatorI.h index e36741631f9..f0f97239c83 100644 --- a/cpp/src/IceGrid/LocatorI.h +++ b/cpp/src/IceGrid/LocatorI.h @@ -13,6 +13,8 @@ #include <IceGrid/Internal.h> #include <IceGrid/Locator.h> +#include <set> + namespace IceGrid { @@ -30,6 +32,8 @@ typedef std::vector<LocatorAdapterInfo> LocatorAdapterInfoSeq; class LocatorI : public Locator, public IceUtil::Mutex { +public: + class Request : public IceUtil::Mutex, public IceUtil::Shared { public: @@ -38,8 +42,15 @@ class LocatorI : public Locator, public IceUtil::Mutex const LocatorAdapterInfoSeq&, int, const TraceLevelsPtr&); void execute(); - void response(const Ice::ObjectPrx&); - void exception(const Ice::Exception&); + void response(const std::string&, const Ice::ObjectPrx&); + void activate(const std::string&); + void exception(const std::string&, const Ice::Exception&); + + virtual bool + operator<(const Request& r) const + { + return this < &r; + } private: @@ -54,13 +65,12 @@ class LocatorI : public Locator, public IceUtil::Mutex const TraceLevelsPtr _traceLevels; unsigned int _count; LocatorAdapterInfoSeq::const_iterator _lastAdapter; - std::vector<Ice::ObjectPrx> _proxies; + std::map<std::string, Ice::ObjectPrx> _proxies; std::auto_ptr<Ice::Exception> _exception; + std::set<std::string> _activating; }; typedef IceUtil::Handle<Request> RequestPtr; -public: - LocatorI(const Ice::CommunicatorPtr&, const DatabasePtr&, const Ice::LocatorRegistryPrx&, const RegistryPrx&, const QueryPrx&); @@ -73,13 +83,15 @@ public: virtual Ice::LocatorRegistryPrx getRegistry(const Ice::Current&) const; virtual RegistryPrx getLocalRegistry(const Ice::Current&) const; virtual QueryPrx getLocalQuery(const Ice::Current&) const; - - bool getDirectProxyRequest(const RequestPtr&, const LocatorAdapterInfo&); - void getDirectProxyException(const LocatorAdapterInfo&, const std::string&, const Ice::Exception&); - void getDirectProxyCallback(const Ice::Identity&, const Ice::ObjectPrx&); const Ice::CommunicatorPtr& getCommunicator() const; + void activate(const LocatorAdapterInfo&, const RequestPtr&); + void cancelActivate(const std::string&, const RequestPtr&); + + void activateFinished(const std::string&, const Ice::ObjectPrx&); + void activateException(const std::string&, const Ice::Exception&); + protected: const Ice::CommunicatorPtr _communicator; @@ -88,8 +100,8 @@ protected: const RegistryPrx _localRegistry; const QueryPrx _localQuery; - typedef std::vector<RequestPtr> PendingRequests; - typedef std::map<Ice::Identity, PendingRequests> PendingRequestsMap; + typedef std::set<RequestPtr> PendingRequests; + typedef std::map<std::string, PendingRequests> PendingRequestsMap; PendingRequestsMap _pendingRequests; }; diff --git a/cpp/src/IceGrid/Scanner.l b/cpp/src/IceGrid/Scanner.l index 8f78cea0757..2ebda3c291d 100644 --- a/cpp/src/IceGrid/Scanner.l +++ b/cpp/src/IceGrid/Scanner.l @@ -45,6 +45,7 @@ NL [\n] keyword [[:alpha:]]* %option noyywrap +%option always-interactive %% diff --git a/cpp/src/IceStorm/Scanner.l b/cpp/src/IceStorm/Scanner.l index 07fc177c19f..818f8f0b9b7 100644 --- a/cpp/src/IceStorm/Scanner.l +++ b/cpp/src/IceStorm/Scanner.l @@ -45,6 +45,7 @@ NL [\n] keyword [[:alpha:]]* %option noyywrap +%option always-interactive %% diff --git a/cpp/test/Freeze/evictor/Client.cpp b/cpp/test/Freeze/evictor/Client.cpp index a11d4cc23a3..517e02341dd 100644 --- a/cpp/test/Freeze/evictor/Client.cpp +++ b/cpp/test/Freeze/evictor/Client.cpp @@ -424,6 +424,11 @@ public: // Expected from time to time // } + catch(const Ice::Exception& e) + { + cerr << "Caught Ice::Exception: " << e << endl; + test(false); + } catch(...) { cerr << "caught some other exception" << endl; diff --git a/cpp/test/Freeze/evictor/TestI.cpp b/cpp/test/Freeze/evictor/TestI.cpp index df6c87176ac..b9d87ac0c89 100644 --- a/cpp/test/Freeze/evictor/TestI.cpp +++ b/cpp/test/Freeze/evictor/TestI.cpp @@ -406,7 +406,7 @@ Test::ServantI::getTotalBalance(const Current& current) te->setCurrentTransaction(0); return total; } - catch(const Freeze::DeadlockException&) + catch(const Freeze::TransactionalEvictorDeadlockException&) { te->getCurrentTransaction()->rollback(); te->setCurrentTransaction(0); diff --git a/cpp/test/IceGrid/deployer/Server.cpp b/cpp/test/IceGrid/deployer/Server.cpp index 977c9270c1b..9762e0143e2 100644 --- a/cpp/test/IceGrid/deployer/Server.cpp +++ b/cpp/test/IceGrid/deployer/Server.cpp @@ -32,7 +32,15 @@ Server::run(int argc, char* argv[]) string name = properties->getProperty("Ice.ProgramName"); - Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Server"); + Ice::ObjectAdapterPtr adapter; + + if(!properties->getProperty("ReplicatedAdapter").empty()) + { + adapter = communicator()->createObjectAdapter("ReplicatedAdapter"); + adapter->activate(); + } + + adapter = communicator()->createObjectAdapter("Server"); Ice::ObjectPtr object = new TestI(adapter, properties); adapter->add(object, communicator()->stringToIdentity(name)); diff --git a/cpp/test/IceGrid/replicaGroup/AllTests.cpp b/cpp/test/IceGrid/replicaGroup/AllTests.cpp index 1bef85f3b3d..866b5f23580 100644 --- a/cpp/test/IceGrid/replicaGroup/AllTests.cpp +++ b/cpp/test/IceGrid/replicaGroup/AllTests.cpp @@ -99,6 +99,19 @@ instantiateServer(const AdminPrx& admin, const string& templ, const string& node cerr << ex << endl; test(false); } + + assert(params.find("id") != params.end()); + try + { + admin->startServer(params.find("id")->second); + } + catch(const NodeUnreachableException&) + { + } + catch(const Ice::Exception&) + { + test(false); + } } void |