]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
First draft of wait mechanism.
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 15 Jul 2015 16:07:39 +0000 (18:07 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 15 Jul 2015 16:07:39 +0000 (18:07 +0200)
idl/SALOME_SDS.idl
src/SALOMESDS/CMakeLists.txt
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_KeyWaiter.cxx [new file with mode: 0644]
src/SALOMESDS/SALOMESDS_KeyWaiter.hxx [new file with mode: 0644]
src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx
src/SALOMESDS/SALOMESDS_Transaction.cxx
src/SALOMESDS/SALOMESDS_Transaction.hxx

index d5c5d4d15f904a86aa3a831bb7b3c89fe8cb7991..d26c2ad58819a83b8400fc06c19648454e89d9ec 100644 (file)
@@ -81,12 +81,18 @@ module SALOME
 
   typedef sequence<Transaction> ListOfTransaction;
 
+  interface KeyWaiter
+  {
+    ByteVec waitFor() raises (SALOME::SALOME_Exception);
+  };
+
   interface DataScopeServerTransaction : DataScopeServerBase
   {
     ByteVec fetchSerializedContent(in string varName) raises (SALOME::SALOME_Exception);
     Transaction createRdOnlyVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction createRdExtVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction createRdWrVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+    KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception);
     void atomicApply(in ListOfTransaction transactions) raises (SALOME::SALOME_Exception);
   };
 
index e76e4b664d1cdd37f5a229786aedabe30ce6e836..8a9a4c145d205020d520d565e439c249e35e50ab 100644 (file)
@@ -45,6 +45,7 @@ SET(SalomeSDS_SOURCES
   SALOMESDS_PickelizedPyObjRdExtServer.cxx
   SALOMESDS_PickelizedPyObjRdWrServer.cxx
   SALOMESDS_Transaction.cxx
+  SALOMESDS_KeyWaiter.cxx
   )
 
 ADD_LIBRARY(SalomeSDS ${SalomeSDS_SOURCES})
index 3e82e2f5bdec201da376b54ed26dcbc4df0d2019..38b92339326a4c5a7039c31e2096d14fdb61e3f9 100644 (file)
@@ -23,6 +23,7 @@
 #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
+#include "SALOMESDS_KeyWaiter.hxx"
 #include "SALOMESDS_Transaction.hxx"
 #include "SALOME_NamingService.hxx"
 #include "SALOMESDS_Exception.hxx"
@@ -102,13 +103,13 @@ CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
 
 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
 {
-  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(retrieveVarInternal3(varName));
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
   return SALOME::BasicDataServer::_duplicate((*it0).first);
 }
 
 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
 {
-  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(retrieveVarInternal3(varName));
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
   return (*it0).second;
 }
 
@@ -218,7 +219,7 @@ std::vector< std::string > DataScopeServerBase::getAllVarNames() const
   return ret;
 }
 
-void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName)
+void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
@@ -229,7 +230,7 @@ void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName)
     }
 }
 
-void DataScopeServerBase::checkExistingVar(const std::string& varName)
+void DataScopeServerBase::checkExistingVar(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
@@ -240,7 +241,25 @@ void DataScopeServerBase::checkExistingVar(const std::string& varName)
     }
 }
 
-std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName)
+PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
+{
+  checkExistingVar(varName);
+  BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
+  PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
+  if(!ret)
+    {
+      std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
+      throw Exception(oss.str());
+    }
+  if(!ret->isDict())
+    {
+      std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
+      throw Exception(oss.str());
+    }
+  return ret;
+}
+
+std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
@@ -251,7 +270,7 @@ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterat
       throw Exception(oss.str());
     }
   std::size_t pos(std::distance(allNames.begin(),it));
-  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
   for(std::size_t i=0;i<pos;i++,it0++);
   return it0;
 }
@@ -310,9 +329,12 @@ DataScopeServer::~DataScopeServer()
 
 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, const std::string& scopeName):DataScopeServerBase(orb,scopeName)
 {
+  CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
+  PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
+  _poa_for_key_waiter=poa;
 }
 
-DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):DataScopeServerBase(other)
+DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
 {
 }
 
@@ -357,36 +379,44 @@ SALOME::ByteVec *DataScopeServerTransaction::fetchSerializedContent(const char *
 
 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
 {
+  checkNotAlreadyExistingVar(varName);
   TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
-  ret->checkNotAlreadyExisting();
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
 }
 
 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
 {
+  checkNotAlreadyExistingVar(varName);
   TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
-  ret->checkNotAlreadyExisting();
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
 }
 
 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
 {
+  checkNotAlreadyExistingVar(varName);
   TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
-  ret->checkNotAlreadyExisting();
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
 }
 
 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
 {
+  checkNotAlreadyExistingVar(varName);
   TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
-  ret->checkNotAlreadyExisting();
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
 }
 
+SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
+{
+  checkVarExistingAndDict(varName);
+  KeyWaiter *ret(new KeyWaiter(this,keyVal));
+  CORBA::Object_var obj(ret->activate());
+  return SALOME::KeyWaiter::_narrow(obj);
+}
+
 class TrustTransaction
 {
 public:
index 63af1c33338419cc34954dbaf085b7413c67a4e8..749fcae9fe387f05efe5d5fefcd743e7f6bdf439 100644 (file)
@@ -37,6 +37,8 @@
 
 namespace SALOMESDS
 {
+  class PickelizedPyObjServer;
+
   class SALOMESDS_EXPORT DataScopeServerBase : public virtual POA_SALOME::DataScopeServerBase, public POAHolder
   {
   public:
@@ -64,10 +66,11 @@ namespace SALOMESDS
     static std::string BuildTmpVarNameFrom(const std::string& varName);
   public:
     std::vector< std::string> getAllVarNames() const;
-    void checkNotAlreadyExistingVar(const std::string& varName);
-    void checkExistingVar(const std::string& varName);
+    void checkNotAlreadyExistingVar(const std::string& varName) const;
+    void checkExistingVar(const std::string& varName) const;
+    PickelizedPyObjServer *checkVarExistingAndDict(const std::string& varName);
   protected:
-    std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator retrieveVarInternal3(const std::string& varName);
+    std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
   protected:
     PyObject *_globals;
     PyObject *_locals;
@@ -100,13 +103,17 @@ namespace SALOMESDS
     void createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
     void createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
     void createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
+    PortableServer::POA_var getPOA4KeyWaiter() const { return _poa_for_key_waiter; }
   public://remotely callable
     SALOME::ByteVec *fetchSerializedContent(const char *varName);
     SALOME::Transaction_ptr createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+    SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal);
     void atomicApply(const SALOME::ListOfTransaction& transactions);
+  private:
+    PortableServer::POA_var _poa_for_key_waiter;
   };
   
   /*
diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx
new file mode 100644 (file)
index 0000000..aead153
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOMESDS_KeyWaiter.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
+#include "SALOMESDS_PickelizedPyObjServer.hxx"
+
+using namespace SALOMESDS;
+
+KeyWaiter::KeyWaiter(DataScopeServerTransaction *dst, const SALOME::ByteVec& keyVal):_dst(dst),_ze_key(0),_ze_value(0)
+{
+  std::string st;
+  PickelizedPyObjServer::FromByteSeqToCpp(keyVal,st);
+  _ze_key=PickelizedPyObjServer::GetPyObjFromPickled(st,_dst);
+  PyObject *selfMeth(PyObject_GetAttrString(_dst->getPickler(),"__contains__"));
+  PyObject *args(PyTuple_New(1));
+  PyTuple_SetItem(args,0,_ze_key); Py_XINCREF(_ze_key); // _ze_key is stolen by PyTuple_SetItem
+  PyObject *retPy(PyObject_CallObject(selfMeth,args));
+  Py_XDECREF(args);
+  Py_XDECREF(selfMeth);
+  //
+  if(retPy!=Py_False && retPy!=Py_True)
+    throw Exception("KeyWaiter constructor : unexpected return of dict.__contains__ !");
+  
+  Py_XDECREF(retPy);
+}
+
+KeyWaiter::~KeyWaiter()
+{
+  Py_XDECREF(_ze_key);
+  if(_ze_value)
+    Py_XDECREF(_ze_value);
+}
+
+PortableServer::POA_var KeyWaiter::getPOA() const
+{
+  return _dst->getPOA4KeyWaiter();
+}
+
+SALOME::ByteVec *KeyWaiter::waitFor()
+{
+  return 0;
+}
diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx
new file mode 100644 (file)
index 0000000..f1a6f46
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOMESDS_KEYWAITER_HXX__
+#define __SALOMESDS_KEYWAITER_HXX__
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOME_SDS)
+
+#include "SALOMESDS_Defines.hxx"
+#include "SALOMESDS_AutoRefCountPtr.hxx"
+
+#include <Python.h>
+
+namespace SALOMESDS
+{
+  class DataScopeServerTransaction;
+
+  class SALOMESDS_EXPORT KeyWaiter : public virtual POA_SALOME::KeyWaiter, public POAHolder
+  {
+  public:
+    KeyWaiter(DataScopeServerTransaction *dst, const SALOME::ByteVec& keyVal);
+    virtual ~KeyWaiter();
+    PortableServer::POA_var getPOA() const;
+    SALOME::ByteVec *waitFor();
+  private:
+    DataScopeServerTransaction *_dst;
+    PyObject *_ze_key;
+    PyObject *_ze_value;
+  };
+}
+
+#endif
index 0dd9701e3f3327ca7e286118584b69beacba2377..d0ef1e96fbab5d692b033068d68aea7b37af0fee 100644 (file)
@@ -94,14 +94,14 @@ SALOME::ByteVec *PickelizedPyObjServer::FromCppToByteSeq(const std::string& strT
 }
 
 //! New reference returned
-PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::string& pickledData)
+PyObject *PickelizedPyObjServer::GetPyObjFromPickled(const std::string& pickledData, DataScopeServerBase *dsb)
 {
   std::size_t sz(pickledData.size());
   PyObject *pickledDataPy(PyString_FromStringAndSize(NULL,sz));// agy : do not use PyString_FromString because std::string hides a vector of byte.
   char *buf(PyString_AsString(pickledDataPy));// this buf can be used thanks to python documentation.
   const char *inBuf(pickledData.c_str());
   std::copy(inBuf,inBuf+sz,buf);
-  PyObject *selfMeth(PyObject_GetAttrString(_father->getPickler(),"loads"));
+  PyObject *selfMeth(PyObject_GetAttrString(dsb->getPickler(),"loads"));
   PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,pickledDataPy);
   PyObject *ret(PyObject_CallObject(selfMeth,args));
   Py_XDECREF(args);
@@ -110,14 +110,20 @@ PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::string& pickledD
 }
 
 //! New reference returned
-PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::vector<unsigned char>& pickledData)
+PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::string& pickledData)
+{
+  return GetPyObjFromPickled(pickledData,_father);
+}
+
+//! New reference returned
+PyObject *PickelizedPyObjServer::GetPyObjFromPickled(const std::vector<unsigned char>& pickledData, DataScopeServerBase *dsb)
 {
   std::size_t sz(pickledData.size());
   PyObject *pickledDataPy(PyString_FromStringAndSize(NULL,sz));// agy : do not use PyString_FromString because std::string hides a vector of byte.
   char *buf(PyString_AsString(pickledDataPy));// this buf can be used thanks to python documentation.
   const unsigned char *inBuf(&pickledData[0]);
   std::copy(inBuf,inBuf+sz,buf);
-  PyObject *selfMeth(PyObject_GetAttrString(_father->getPickler(),"loads"));
+  PyObject *selfMeth(PyObject_GetAttrString(dsb->getPickler(),"loads"));
   PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,pickledDataPy);
   PyObject *ret(PyObject_CallObject(selfMeth,args));
   Py_XDECREF(args);
@@ -125,6 +131,12 @@ PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::vector<unsigned
   return ret;
 }
 
+//! New reference returned
+PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::vector<unsigned char>& pickledData)
+{
+  return GetPyObjFromPickled(pickledData,_father);
+}
+
 //! obj is consumed by this method.
 std::string PickelizedPyObjServer::pickelize(PyObject *obj)
 {
index e8f3edb5f14974859ae54b1e2374dc31a618e57f..968339b8c0542038efd2077eeec1d7f4b415a065 100644 (file)
@@ -46,6 +46,8 @@ namespace SALOMESDS
   public:
     static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret);
     static SALOME::ByteVec *FromCppToByteSeq(const std::string& strToBeConv);
+    static PyObject *GetPyObjFromPickled(const std::string& pickledData, DataScopeServerBase *dsb);
+    static PyObject *GetPyObjFromPickled(const std::vector<unsigned char>& pickledData, DataScopeServerBase *dsb);
     PyObject *getPyObjFromPickled(const std::string& pickledData);
     PyObject *getPyObjFromPickled(const std::vector<unsigned char>& pickledData);
     std::string pickelize(PyObject *obj);
index e46a6dafb8e9b99004fa0e9c9686329bdc0af3e7..7809157b00acc32a66ddcba499722b37a0fe3506 100644 (file)
@@ -99,20 +99,7 @@ TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransactio
 
 void TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure()
 {
-  checkNotAlreadyExisting();
-  //
-  BasicDataServer *var(_dsct->retrieveVarInternal2(_var_name.c_str()));
-  _varc=dynamic_cast<PickelizedPyObjServer *>(var);
-  if(!_varc)
-    {
-      std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << _var_name << "\"exists but it is not serialized !";
-      throw Exception(oss.str());
-    }
-  if(!_varc->isDict())
-    {
-      std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << _var_name << "\"exists but it is not a Dict !";
-      throw Exception(oss.str());
-    }
+  _varc=checkVarExistingAndDict();
   //
   _zeDataBefore.clear();
   SALOME::ByteVec *zeDataBefore(_varc->fetchSerializedContent());
index 55531c22466affc6f6f6f6eba08974744cfb6cd0..37e37f2bcaceb2c7eed3a39a656c8b2284e28a89 100644 (file)
@@ -33,6 +33,8 @@
 
 namespace SALOMESDS
 {
+  class PickelizedPyObjServer;
+
   class SALOMESDS_EXPORT Transaction : public virtual POA_SALOME::Transaction, public POAHolder
   {
   public:
@@ -40,6 +42,7 @@ namespace SALOMESDS
     std::string getVarName() const { return _var_name; }
     void checkNotAlreadyExisting() { _dsct->checkNotAlreadyExistingVar(_var_name); }
     void checkVarExisting() { _dsct->checkExistingVar(_var_name); }
+    PickelizedPyObjServer *checkVarExistingAndDict() { return _dsct->checkVarExistingAndDict(_var_name); }
     PortableServer::POA_var getPOA() const { return _dsct->getPOA(); }
     virtual void prepareRollBackInCaseOfFailure() = 0;
     virtual void perform() = 0;