diff -Naur Ice-3.2.0.orig/include/Ice/IncomingAsync.h Ice-3.2.0/include/Ice/IncomingAsync.h --- Ice-3.2.0.orig/include/Ice/IncomingAsync.h 2007-02-01 10:40:28.000000000 -0600 +++ Ice-3.2.0/include/Ice/IncomingAsync.h 2007-03-19 09:58:48.000000000 -0500 @@ -12,6 +12,8 @@ #include #include +#include +#include namespace IceInternal { @@ -53,6 +55,28 @@ const Ice::ConnectionIPtr _connectionCopy; }; +class ICE_API IncomingAsyncD +{ +public: + + void ice_waitForResponse(); + +protected: + + IncomingAsyncD(); + + void __exception(const Ice::Exception&); + + void __response(); + +protected: + + bool _handled; + IceUtil::Mutex _mutex; + IceUtil::Cond _cond; + std::auto_ptr _ex; +}; + } namespace Ice diff -Naur Ice-3.2.0.orig/src/Ice/IncomingAsync.cpp Ice-3.2.0/src/Ice/IncomingAsync.cpp --- Ice-3.2.0.orig/src/Ice/IncomingAsync.cpp 2007-02-01 10:40:28.000000000 -0600 +++ Ice-3.2.0/src/Ice/IncomingAsync.cpp 2007-03-19 09:59:37.000000000 -0500 @@ -154,6 +154,40 @@ } } +IceInternal::IncomingAsyncD::IncomingAsyncD() : + _handled(false) +{ +} + +void IceInternal::IncomingAsyncD::__exception(const Ice::Exception& ex) +{ + _ex.reset(ex.ice_clone()); + __response(); +} + +void IceInternal::IncomingAsyncD::__response() +{ + { + IceUtil::Mutex::Lock lock(_mutex); + _handled = true; + } + _cond.broadcast(); +} + +void IceInternal::IncomingAsyncD::ice_waitForResponse() +{ + IceUtil::Mutex::Lock lock(_mutex); + while(!_handled) + { + _cond.wait(lock); + } + if(_ex.get()) + { + _ex->ice_throw(); + } +} + + IceAsync::Ice::AMD_Object_ice_invoke::AMD_Object_ice_invoke(Incoming& in) : IncomingAsync(in) { diff -Naur Ice-3.2.0.orig/src/Ice/ObjectAdapterI.cpp Ice-3.2.0/src/Ice/ObjectAdapterI.cpp --- Ice-3.2.0.orig/src/Ice/ObjectAdapterI.cpp 2007-02-14 13:20:45.000000000 -0600 +++ Ice-3.2.0/src/Ice/ObjectAdapterI.cpp 2007-03-18 16:39:19.000000000 -0500 @@ -603,6 +603,10 @@ else { endpoints = ref->getEndpoints(); + if(endpoints.empty() && _id.empty()) + { + return true; + } } IceUtil::Monitor::Lock sync(*this); diff -Naur Ice-3.2.0.orig/src/slice2cpp/Gen.cpp Ice-3.2.0/src/slice2cpp/Gen.cpp --- Ice-3.2.0.orig/src/slice2cpp/Gen.cpp 2007-02-01 10:40:28.000000000 -0600 +++ Ice-3.2.0/src/slice2cpp/Gen.cpp 2007-03-19 10:06:44.000000000 -0500 @@ -303,6 +303,9 @@ AsyncImplVisitor asyncImplVisitor(H, C, _dllExport); p->visit(&asyncImplVisitor, false); + AsyncDImplVisitor asyncDImplVisitor(H, C, _dllExport); + p->visit(&asyncDImplVisitor, false); + ProxyVisitor proxyVisitor(H, C, _dllExport); p->visit(&proxyVisitor, false); @@ -2526,6 +2529,21 @@ vector params; vector paramsDecl; vector args; + vector cbArgs; + + ContainerPtr container = p->container(); + ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + + bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd")); + + if(amd) + { + args.push_back("__cb"); + if(ret) + { + cbArgs.push_back("__ret"); + } + } ParamDeclList paramList = p->parameters(); for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) @@ -2553,88 +2571,100 @@ params.push_back(typeString); paramsDecl.push_back(typeString + ' ' + paramName); - args.push_back(paramName); + + if(amd && (*q)->isOutParam()) + { + cbArgs.push_back(paramName); + } + else + { + args.push_back(paramName); + } } params.push_back("const ::Ice::Context*"); paramsDecl.push_back("const ::Ice::Context* __context"); args.push_back("__current"); - ContainerPtr container = p->container(); - ClassDefPtr cl = ClassDefPtr::dynamicCast(container); string thisPointer = fixKwd(cl->scoped()) + "*"; + string classNameAMD = "AMD_" + cl->name(); + string classScope = fixKwd(cl->scope()); + string classScopedAMD = classScope + classNameAMD; + H << sp; H << nl << "virtual " << retS << ' ' << name << spar << params << epar << ';'; - bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd")); - if(amd) + + C << sp << nl << retS << nl << "IceDelegateD" << scoped << spar << paramsDecl << epar; + C << sb; + C << nl << "::Ice::Current __current;"; + C << nl << "__initCurrent(__current, " << p->flattenedScope() + p->name() + "_name, " + << operationModeToString(p->sendMode()) << ", __context);"; + C << nl << "while(true)"; + C << sb; + C << nl << "::IceInternal::Direct __direct(__current);"; + if(ret) { - C << sp << nl << retS << nl << "IceDelegateD" << scoped << spar << params << epar; - C << sb; - C << nl << "throw ::Ice::CollocationOptimizationException(__FILE__, __LINE__);"; - if(ret != 0) - { - C << nl << "return " << retS << "(); // to avoid a warning with some compilers;"; - } - C << eb; + C << nl << retS << " __ret;"; } - else + C << nl << "try"; + C << sb; + C << nl << thisPointer << " __servant = dynamic_cast< " << thisPointer << ">(__direct.servant().get());"; + C << nl << "if(!__servant)"; + C << sb; + C << nl << "::Ice::OperationNotExistException __opEx(__FILE__, __LINE__);"; + C << nl << "__opEx.id = __current.id;"; + C << nl << "__opEx.facet = __current.facet;"; + C << nl << "__opEx.operation = __current.operation;"; + C << nl << "throw __opEx;"; + C << eb; + if(!amd) { - C << sp << nl << retS << nl << "IceDelegateD" << scoped << spar << paramsDecl << epar; - C << sb; - C << nl << "::Ice::Current __current;"; - C << nl << "__initCurrent(__current, " << p->flattenedScope() + p->name() + "_name, " - << operationModeToString(p->sendMode()) << ", __context);"; - C << nl << "while(true)"; - C << sb; - C << nl << "::IceInternal::Direct __direct(__current);"; - if(ret) - { - C << nl << retS << " __ret;"; - } - C << nl << "try"; - C << sb; - C << nl << thisPointer << " __servant = dynamic_cast< " << thisPointer << ">(__direct.servant().get());"; - C << nl << "if(!__servant)"; - C << sb; - C << nl << "::Ice::OperationNotExistException __opEx(__FILE__, __LINE__);"; - C << nl << "__opEx.id = __current.id;"; - C << nl << "__opEx.facet = __current.facet;"; - C << nl << "__opEx.operation = __current.operation;"; - C << nl << "throw __opEx;"; - C << eb; C << nl << "try"; C << sb; - C << nl; + } + C << nl; + if(amd) + { + C << "IceUtil::Handle< IceAsyncD" << classScopedAMD << '_' << name << " > " + << "__cb = new IceAsyncD" << classScopedAMD << '_' << name << spar << cbArgs << epar << ';'; + C << nl << "__servant->" << name << "_async" << spar << args << epar << ';'; + C << nl << "__cb->ice_waitForResponse();"; + } + else + { if(ret) { C << "__ret = "; } C << "__servant->" << name << spar << args << epar << ';'; + } + if(!amd) + { C << eb; C << nl << "catch(const ::Ice::LocalException& __ex)"; C << sb; C << nl << "throw ::IceInternal::LocalExceptionWrapper(__ex, false);"; C << eb; - C << eb; - C << nl << "catch(...)"; - C << sb; - C << nl << "__direct.destroy();"; - C << nl << "throw;"; - C << eb; - C << nl << "__direct.destroy();"; - if(ret) - { - C << nl << "return __ret;"; - } - else - { - C << nl << "return;"; - } - C << eb; - C << eb; } + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "__direct.destroy();"; + C << nl << "throw;"; + C << eb; + C << nl << "__direct.destroy();"; + if(ret) + { + C << nl << "return __ret;"; + } + else + { + C << nl << "return;"; + } + C << eb; + C << eb; } Slice::Gen::ObjectDeclVisitor::ObjectDeclVisitor(Output& h, Output& c, const string& dllExport) : @@ -5159,6 +5189,212 @@ C << eb; } +Slice::Gen::AsyncDImplVisitor::AsyncDImplVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _useWstring(false) +{ +} + +bool +Slice::Gen::AsyncDImplVisitor::visitUnitStart(const UnitPtr& p) +{ + if(!p->hasNonLocalClassDecls() || !p->hasContentsWithMetaData("amd")) + { + return false; + } + + H << sp << nl << "namespace IceAsyncD" << nl << '{'; + + return true; +} + +void +Slice::Gen::AsyncDImplVisitor::visitUnitEnd(const UnitPtr& p) +{ + H << sp << nl << '}'; +} + +bool +Slice::Gen::AsyncDImplVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasNonLocalClassDecls() || !p->hasContentsWithMetaData("amd")) + { + return false; + } + + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + + string name = fixKwd(p->name()); + + H << sp << nl << "namespace " << name << nl << '{'; + + return true; +} + +void +Slice::Gen::AsyncDImplVisitor::visitModuleEnd(const ModulePtr& p) +{ + H << sp << nl << '}'; + + _useWstring = resetUseWstring(_useWstringHist); +} + +bool +Slice::Gen::AsyncDImplVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + return true; +} + +void +Slice::Gen::AsyncDImplVisitor::visitClassDefEnd(const ClassDefPtr&) +{ + _useWstring = resetUseWstring(_useWstringHist); +} + +namespace { + +struct MemberInfo +{ + MemberInfo(const string& name, const TypePtr& type, const StringList& metadata) : + name(name), type(type), metadata(metadata) + { } + + string name; + TypePtr type; + StringList metadata; +}; + +typedef vector MemberInfoList; + +} + +void +Slice::Gen::AsyncDImplVisitor::visitOperation(const OperationPtr& p) +{ + ContainerPtr container = p->container(); + ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + + if(cl->isLocal() || (!cl->hasMetaData("amd") && !p->hasMetaData("amd"))) + { + return; + } + + string name = p->name(); + + string classNameAMD = "AMD_" + cl->name(); + string classScope = fixKwd(cl->scope()); + string classScopedAMD = classScope + classNameAMD; + + vector params; + vector paramsDecl; + vector ctorParams; + vector ctorParamsDecl; + vector memberDecls; + MemberInfoList members; + + TypePtr ret = p->returnType(); + string retS = inputTypeToString(ret, _useWstring, p->getMetaData()); + string ctorRetS = outputTypeToString(ret, _useWstring, p->getMetaData()); + + if(ret) + { + params.push_back(retS); + ctorParams.push_back(ctorRetS); + paramsDecl.push_back(retS + " __ret"); + ctorParamsDecl.push_back(ctorRetS + "__ret"); + members.push_back(MemberInfo("__ret", ret, p->getMetaData())); + } + + ParamDeclList paramList = p->parameters(); + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + if((*q)->isOutParam()) + { + string paramName = fixKwd((*q)->name()); + TypePtr type = (*q)->type(); + string typeString = inputTypeToString(type, _useWstring, (*q)->getMetaData()); + string ctorTypeString = outputTypeToString(type, _useWstring, (*q)->getMetaData()); + + params.push_back(typeString); + ctorParams.push_back(ctorTypeString); + paramsDecl.push_back(typeString + ' ' + paramName); + ctorParamsDecl.push_back(ctorTypeString + ' ' + paramName); + members.push_back(MemberInfo(paramName, type, (*q)->getMetaData())); + } + } + + H << sp << nl << "class " << _dllExport << classNameAMD << '_' << name + << " : public " << classScopedAMD << '_' << name << ", public ::IceInternal::IncomingAsyncD"; + H << sb; + H.dec(); + H << nl << "public:"; + H.inc(); + + H << sp; + H << nl << classNameAMD << '_' << name << spar << ctorParams << epar << ';'; + + H << sp; + H << nl << "virtual void ice_response" << spar << params << epar << ';'; + H << nl << "virtual void ice_exception(const ::Ice::Exception&);"; + H << nl << "virtual void ice_exception(const ::std::exception&);"; + H << nl << "virtual void ice_exception();"; + H << nl; + for(MemberInfoList::const_iterator i = members.begin(), end = members.end() ; i != end ; ++i) + { + string paramName = fixKwd(i->name); + string typeString = outputTypeToString(i->type, _useWstring, i->metadata); + H << nl << typeString << ' ' << paramName << ';'; + } + H << eb << ';'; + + C << sp << nl << "IceAsyncD" << classScopedAMD << '_' << name << "::" << classNameAMD << '_' << name + << spar << ctorParamsDecl << epar; + for(MemberInfoList::const_iterator i = members.begin(), end = members.end() ; i != end ; ++i) + { + C << nl << " " << (i == members.begin() ? ':' : ',') << i->name << '(' << i->name << ')'; + } + C << sb; + C << eb; + + C << sp << nl << "void" << nl << "IceAsyncD" << classScopedAMD << '_' << name << "::ice_response" + << spar << paramsDecl << epar; + C << sb; + for(MemberInfoList::const_iterator i = members.begin(), end = members.end() ; i != end ; ++i) + { + string seqType = findMetaData(i->metadata, true); + if(seqType == "array" || seqType.find("range") == 0) + { + C << nl << "this->" << i->name << ".assign(" << i->name << ".first, " << i->name << ".second);"; + } + else + { + C << nl << "this->" << i->name << " = " << i->name << ';'; + } + } + C << nl << "__response();"; + C << eb; + + C << sp << nl << "void" << nl << "IceAsyncD" << classScopedAMD << '_' << name + << "::ice_exception(const ::Ice::Exception& ex)"; + C << sb; + C << nl << "__exception(ex);"; + C << eb; + + C << sp << nl << "void" << nl << "IceAsyncD" << classScopedAMD << '_' << name + << "::ice_exception(const ::std::exception& ex)"; + C << sb; + C << nl << "ice_exception(::Ice::UnknownLocalException(__FILE__, __LINE__, " + << "std::string(\"std::exception: \") + ex.what()));"; + C << eb; + + C << sp << nl << "void" << nl << "IceAsyncD" << classScopedAMD << '_' << name + << "::ice_exception()"; + C << sb; + C << nl << "ice_exception(::Ice::UnknownLocalException(__FILE__, __LINE__, " + << "\"unknown c++ exception\"));"; + C << eb; +} + void Slice::Gen::validateMetaData(const UnitPtr& u) { diff -Naur Ice-3.2.0.orig/src/slice2cpp/Gen.h Ice-3.2.0/src/slice2cpp/Gen.h --- Ice-3.2.0.orig/src/slice2cpp/Gen.h 2007-02-01 10:40:28.000000000 -0600 +++ Ice-3.2.0/src/slice2cpp/Gen.h 2007-03-18 08:24:28.000000000 -0500 @@ -397,6 +397,30 @@ std::list _useWstringHist; }; + class AsyncDImplVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + AsyncDImplVisitor(::IceUtil::Output&, ::IceUtil::Output&, const std::string&); + + virtual bool visitUnitStart(const UnitPtr&); + virtual void visitUnitEnd(const UnitPtr&); + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual void visitOperation(const OperationPtr&); + + private: + + ::IceUtil::Output& H; + ::IceUtil::Output& C; + + std::string _dllExport; + bool _useWstring; + std::list _useWstringHist; + }; + private: class MetaDataVisitor : public ParserVisitor diff -Naur Ice-3.2.0.orig/src/slice2cs/Gen.cpp Ice-3.2.0/src/slice2cs/Gen.cpp --- Ice-3.2.0.orig/src/slice2cs/Gen.cpp 2007-02-13 07:30:23.000000000 -0600 +++ Ice-3.2.0/src/slice2cs/Gen.cpp 2007-03-19 10:34:54.000000000 -0500 @@ -4300,59 +4300,84 @@ vector params = getParams(op); vector args = getArgs(op); + bool amd = containingClass->hasMetaData("amd") || op->hasMetaData("amd"); + _out << sp; _out << nl << "public " << retS << ' ' << opName << spar << params << "Ice.Context context__" << epar; _out << sb; - if(containingClass->hasMetaData("amd") || op->hasMetaData("amd")) + + _out << nl << "Ice.Current current__ = new Ice.Current();"; + _out << nl << "initCurrent__(ref current__, \"" << op->name() << "\", " + << sliceModeToIceMode(op->sendMode()) + << ", context__);"; + _out << nl << "while(true)"; + _out << sb; + _out << nl << "IceInternal.Direct direct__ = new IceInternal.Direct(current__);"; + _out << nl << "object servant__ = direct__.servant();"; + _out << nl << "if(servant__ is " << fixId(name) << ")"; + _out << sb; + _out << nl << "try"; + _out << sb; + _out << nl; + if(amd) { - _out << nl << "throw new Ice.CollocationOptimizationException();"; + string cbName = fixId(containingClass->scope()) + "AMD_" + containingClass->name() + '_' + op->name() + "_D"; + + vector outArgs = getArgsAsyncCB(op); + transform(outArgs.begin(), outArgs.end(), outArgs.begin(), + bind1st(plus(), "out ")); + + if(ret) + { + _out << nl << retS << " ret__;"; + } + + _out << nl << cbName << " cb__ = new " << cbName << "();"; + + _out << nl << "((" << fixId(containingClass->scoped()) << ")servant__)." + << opName << "_async" << spar << getArgsAsync(op) << "current__" << epar << ';'; + + _out << nl << "cb__.ice_waitForResponse" << spar << outArgs << epar << ';'; + + _out << nl << "return" << (ret ? " ret__" : "") << ';'; } else { - _out << nl << "Ice.Current current__ = new Ice.Current();"; - _out << nl << "initCurrent__(ref current__, \"" << op->name() << "\", " - << sliceModeToIceMode(op->sendMode()) - << ", context__);"; - _out << nl << "while(true)"; - _out << sb; - _out << nl << "IceInternal.Direct direct__ = new IceInternal.Direct(current__);"; - _out << nl << "object servant__ = direct__.servant();"; - _out << nl << "if(servant__ is " << fixId(name) << ")"; - _out << sb; - _out << nl << "try"; - _out << sb; - _out << nl; if(ret) { _out << "return "; } _out << "((" << fixId(containingClass->scoped()) << ")servant__)." - << opName << spar << args << "current__" << epar << ';'; + << opName << spar << args << "current__" << epar << ';'; if(!ret) { _out << nl << "return;"; } - _out << eb; + } + _out << eb; + if(!amd) + { _out << nl << "catch(Ice.LocalException ex__)"; _out << sb; _out << nl << "throw new IceInternal.LocalExceptionWrapper(ex__, false);"; _out << eb; - _out << nl << "finally"; - _out << sb; - _out << nl << "direct__.destroy();"; - _out << eb; - _out << eb; - _out << nl << "else"; - _out << sb; - _out << nl << "direct__.destroy();"; - _out << nl << "Ice.OperationNotExistException opEx__ = new Ice.OperationNotExistException();"; - _out << nl << "opEx__.id = current__.id;"; - _out << nl << "opEx__.facet = current__.facet;"; - _out << nl << "opEx__.operation = current__.operation;"; - _out << nl << "throw opEx__;"; - _out << eb; - _out << eb; } + _out << nl << "finally"; + _out << sb; + _out << nl << "direct__.destroy();"; + _out << eb; + _out << eb; + _out << nl << "else"; + _out << sb; + _out << nl << "direct__.destroy();"; + _out << nl << "Ice.OperationNotExistException opEx__ = new Ice.OperationNotExistException();"; + _out << nl << "opEx__.id = current__.id;"; + _out << nl << "opEx__.facet = current__.facet;"; + _out << nl << "opEx__.operation = current__.operation;"; + _out << nl << "throw opEx__;"; + _out << eb; + _out << eb; + _out << eb; } @@ -4672,6 +4697,12 @@ string classNameAMDI = "_AMD_" + cl->name(); vector paramsAMD = getParamsAsyncCB(p); + vector outParamsAMD; + + transform(paramsAMD.begin(), paramsAMD.end(), back_inserter(outParamsAMD), + bind1st(plus(), "out ")); + + vector paramsAMDNames; _out << sp << nl << "public interface " << classNameAMD << '_' << name; _out << sb; @@ -4680,6 +4711,11 @@ _out << eb; TypePtr ret = p->returnType(); + + if(ret) + { + paramsAMDNames.push_back("ret__"); + } TypeStringList outParams; ParamDeclList paramList = p->parameters(); @@ -4688,6 +4724,7 @@ if((*pli)->isOutParam()) { outParams.push_back(make_pair((*pli)->type(), (*pli)->name())); + paramsAMDNames.push_back((*pli)->name()); } } @@ -4774,6 +4811,44 @@ _out << eb; } _out << eb; + _out << eb; + + _out << sp << nl << "public class " << classNameAMD << '_' << name << "_D" + << " : IceInternal.IncomingAsyncD, " << classNameAMD << '_' << name; + _out << sb; + + _out << sp << nl << "public " << classNameAMD << '_' << name << "_D" << "()"; + _out << sb; + _out << eb; + + _out << sp << nl << "public void ice_response" << spar << paramsAMD << epar; + _out << sb; + for(vector::const_iterator i = paramsAMDNames.begin(), end = paramsAMDNames.end() ; i != end ; ++i) + { + _out << nl << "this." << *i << " = " << *i << ';'; + _out << nl << "response__();"; + } + _out << eb; + + _out << sp << nl << "public void ice_waitForResponse" << spar << outParamsAMD << epar; + _out << sb; + _out << nl << "waitForResponse__();"; + for(vector::const_iterator i = paramsAMDNames.begin(), end = paramsAMDNames.end() ; i != end ; ++i) + { + _out << nl << *i << " = " << "this." << *i << ';'; + } + _out << eb; + + _out << sp << nl << "public void ice_exception(_System.Exception ex)"; + _out << sb; + _out << nl << "exception__(ex);"; + _out << eb; + _out << nl; + + for(vector::const_iterator i = paramsAMD.begin(), end = paramsAMD.end() ; i != end ; ++i) + { + _out << nl << "private " << *i << ';'; + } _out << eb; }