Salome HOME
diff_KERNEL_SRC_BR_Dev_For_4_0__BR_For40_DSC.tgz. For a correct use of YACS in a...
authorjfa <jfa@opencascade.com>
Thu, 21 Feb 2008 13:16:03 +0000 (13:16 +0000)
committerjfa <jfa@opencascade.com>
Thu, 21 Feb 2008 13:16:03 +0000 (13:16 +0000)
58 files changed:
bin/appliskel/runRemote.sh
bin/launchConfigureParser.py
bin/runSalome.py
idl/SALOME_Component.idl
idl/SALOME_ContainerManager.idl
salome_adm/unix/SALOMEconfig.ref.in
src/Container/Component_i.cxx
src/Container/Container_i.cxx
src/Container/SALOME_Component_i.hxx
src/Container/SALOME_ContainerManager.cxx
src/Container/SALOME_Container_i.hxx
src/DSC/DSC_Basic/DSC_i.cxx
src/DSC/DSC_Basic/DSC_interface.cxx
src/DSC/DSC_Basic/DSC_interface.hxx
src/DSC/DSC_Python/calcium.i
src/DSC/DSC_Python/dsccalcium.py
src/DSC/DSC_User/Basic/data_short_port_provides.hxx
src/DSC/DSC_User/Datastream/Calcium/Calcium.c
src/DSC/DSC_User/Datastream/Calcium/Calcium.cxx
src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumProvidesPort.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumTypes2CorbaTypes.cxx
src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx
src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx
src/DSC/DSC_User/Datastream/Calcium/CorbaTypes2CalciumTypes.cxx
src/DSC/DSC_User/Datastream/Calcium/Makefile.am
src/DSC/DSC_User/Datastream/Calcium/calcium_integer_port_uses.hxx
src/DSC/DSC_User/Datastream/Calcium/calciumf.c
src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx
src/DSC/DSC_User/Datastream/CouplingPolicy.hxx
src/DSC/DSC_User/Datastream/GenericPort.hxx
src/DSC/DSC_User/Datastream/GenericUsesPort.hxx
src/DSC/DSC_User/Datastream/Palm/PalmCouplingPolicy.hxx
src/DSC/DSC_User/Superv_Component_i.cxx
src/DSC/DSC_User/Superv_Component_i.hxx
src/Launcher/BatchLight_BatchManager.cxx
src/Launcher/BatchLight_BatchManager.hxx
src/Launcher/BatchLight_BatchManager_PBS.cxx
src/Launcher/BatchLight_BatchManager_PBS.hxx
src/Launcher/BatchLight_BatchManager_SLURM.cxx
src/Launcher/BatchLight_BatchManager_SLURM.hxx
src/Launcher/BatchLight_Job.cxx
src/Launcher/BatchLight_Job.hxx
src/Launcher/SALOME_Launcher.cxx
src/Launcher/SALOME_Launcher.hxx
src/Logger/SALOME_Logger_Server.hxx
src/NOTIFICATION_SWIG/Makefile.am
src/NamingService/NamingService_WaitForServerReadiness.cxx
src/NamingService/Test/NamingServiceTest.cxx
src/Notification/CosNotifyShorthands.h
src/Notification/Makefile.am
src/ResourcesManager/SALOME_ResourcesManager.cxx
src/SALOMEDS/SALOMEDS_Driver_i.hxx
src/SALOMETraceCollector/SALOMETraceCollector.cxx
src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx
src/Utils/Utils_ORB_INIT.hxx

index 6cd76ef4695adb645142191348d2e74275202d55..522b6ddd75e9f5888d078fa83175f49dc93589d5 100755 (executable)
@@ -37,7 +37,8 @@
 #     $0 : ${APPLI}/runRemote.sh: from arg name, rebuild and export $APPLI variable
 #     $1 : computer name for CORBA name service (where SALOME was launched)
 #     $2 : port for CORBA name service
-#     $3 and following : local command to execute, with args
+#     $3 : working directory
+#     $4 and following : local command to execute, with args
 #
 
 # --- retrieve APPLI path, relative to $HOME, set ${APPLI}
@@ -60,9 +61,34 @@ export NSPORT
 initref="NameService=corbaname::"$1":$2"
 echo "ORBInitRef $initref" > $OMNIORB_CONFIG
 
+#go to the requested working directory if any
+if test "x$3" != x; then
+  if test "x$3" = "x\$TEMPDIR"; then
+    #create a temp working dir and change to it
+    WDIR=`mktemp -d` && {
+      cd $WDIR
+    }
+  else
+    if test -d $3; then
+      #the dir exists, go to it
+      cd $3
+    else
+      if test -a $3; then
+        # It's a file do nothing
+        echo $3 "is an existing file. Can't use it as a working directory"
+      else
+        #It does not exists, create it
+        mkdir -p $3 && {
+          cd $3
+        }
+      fi
+    fi
+  fi
+fi
+
 # --- execute the command in the SALOME environment
 
-shift 2
+shift 3
 
 # suppress --rcfile option because of problem on Mandriva2006 - B Secher mai 2007
 #${KERNEL_ROOT_DIR}/bin/salome/envSalome.py /bin/sh --rcfile $HOME/$APPLI/.bashrc -c "$*"
index 150f155983e401a4c92f199e12509827fb800cd7..399c40ef73a7bcd0595db57cfb4012a0fbdb9f25 100755 (executable)
@@ -586,6 +586,15 @@ def CreateOptionParser (theAdditionalOptions=[]):
                           dest="pinter",
                           help=help_str)
 
+    # Print Naming service port into a user file. Default: False.
+    help_str = "Print Naming Service Port into a user file."
+    o_nspl = optparse.Option("--ns-port-log",
+                             metavar="<ns_port_log_file>",
+                             type="string",
+                             action="store",
+                             dest="ns_port_log_file",
+                             help=help_str)
+
     # All options
     opt_list = [o_t,o_g, # GUI/Terminal
                 o_d,o_o, # Desktop
@@ -604,13 +613,14 @@ def CreateOptionParser (theAdditionalOptions=[]):
                 o_c,     # Catch exceptions
                 o_a,     # Print free port and exit
                 o_n,     # --nosave-config
-                o_pi]     # Interactive python console
+                o_pi,    # Interactive python console
+                o_nspl]
                 
 
     #std_options = ["gui", "desktop", "log_file", "py_scripts", "resources",
     #               "xterm", "modules", "embedded", "standalone",
     #               "portkill", "killall", "interp", "splash",
-    #               "catch_exceptions", "print_port", "save_config"]
+    #               "catch_exceptions", "print_port", "save_config", "ns_port_log_file"]
 
     opt_list += theAdditionalOptions
 
@@ -811,6 +821,10 @@ def get_env(theAdditionalOptions=[], appname="SalomeApp"):
         else:
             args[file_nam] = [cmd_opts.log_file]
 
+    # Naming Service port log file
+    if cmd_opts.ns_port_log_file is not None:
+      args["ns_port_log_file"] = cmd_opts.ns_port_log_file
+
     # Python scripts
     args[script_nam] = []
     if cmd_opts.py_scripts is not None:
index 6c01d90e4f263db0231308b93142a7d94ce879c1..f20b507944fefc072e52db5d699c029baa45c428 100755 (executable)
@@ -393,6 +393,18 @@ def startSalome(args, modules_list, modules_root_dir):
     #
    
     clt=orbmodule.client(args)
+    # Save Naming service port name into
+    # the file args["ns_port_log_file"]
+    if args.has_key('ns_port_log_file'):
+      home = os.environ['HOME']
+      appli= os.environ.get("APPLI")
+      if appli is not None:
+        home='%s/%s'%(home,appli)
+        pass
+      file_name= '%s/%s'%(home, args["ns_port_log_file"])
+      f = open(file_name, "w")
+      f.write(os.environ['NSPORT'])
+      f.close()
 
     # (non obligatoire) Lancement Logger Server
     # et attente de sa disponibilite dans le naming service
@@ -784,7 +796,6 @@ def searchFreePort(args, save_config=1):
                 else:            
                     system('ln -s -f %s %s/.omniORB_last.cfg'%(os.environ['OMNIORB_CONFIG'], home))     
                 pass
-            #
             break
         print "%s"%(NSPORT),
         if NSPORT == limit:
index f3139b6ecf37474a7587a437e721d3e6e25f91c4..0619ebfa0c6a4efb8b103b439b008553e37ce921 100644 (file)
@@ -132,6 +132,16 @@ module Engines
     */
     readonly attribute string name ;
 
+    /*!
+      working directory of the %container
+    */
+    readonly attribute string workingdir ;
+
+    /*!
+      name of the %container log file (this has been set by the launcher)
+    */
+    attribute string logfilename ;
+
     /*!
       Shutdown the Container process.
     */
index c53d27a9c7bc658cebf00b4a231d11e6efe42462..8d2258cf571a1da8a0c7ab0e158d9aaaf0a40bc9 100644 (file)
@@ -54,6 +54,7 @@ struct MachineParameters
   boolean isMPI;
   string mpiImpl;
   string batch;
+  string workingdir;
 
   // PaCO specific informations
   string parallelLib;
@@ -68,6 +69,21 @@ struct MachineParameters
   enum policy {P_FIRST,P_CYCL,P_BEST};
   typedef policy ResPolicy;
 
+/*!
+  Structure used for Salome Batch Job parameters
+*/
+struct BatchParameters
+{
+  string batch_directory; // Where batch command will be launched
+                         // and log files will be created
+  string expected_during_time; // Time for the batch
+                              // has to be like this : hh:mm
+  string mem; // Minimum of memory needed
+             // has to be like : 32gb or 512mb
+
+  long nb_proc; // Number of processors requested
+};
+
 /*! \brief Interface of the %salomelauncher
     This interface is used for interaction with the unique instance
     of SalomeLauncher
@@ -77,7 +93,7 @@ struct MachineParameters
     long submitSalomeJob( in string fileToExecute,
                          in FilesList filesToExport,
                          in FilesList filesToImport,
-                         in long NumberOfProcessors,
+                         in BatchParameters batch_params,
                          in MachineParameters params ) raises (SALOME::SALOME_Exception);
     string querySalomeJob( in long jobId, in MachineParameters params ) raises (SALOME::SALOME_Exception);
     void deleteSalomeJob( in long jobId, in MachineParameters params ) raises (SALOME::SALOME_Exception);
index 22372e97abaf1f33eb35859ee923df44cc58bbf2..78688bd880cdd3e9e5375612d6a99a28ace3f936 100644 (file)
 /* A path to a ssh-like command */
 #define SSH "@SSH@"
 
+// This is only to suppress warning messages with defines redefined (cause of omniORB that exports these names)
+#ifdef PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#endif
+#ifdef PACKAGE_NAME
+#undef PACKAGE_NAME
+#endif
+#ifdef PACKAGE_STRING
+#undef PACKAGE_STRING
+#endif
+#ifdef PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#endif
+#ifdef PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#endif
+
 #endif
index cdbef093f044b1f50fde72b2ff7e8e2131047e6c..5b7efac97b8a6fef73547d3c4eb9a02d6c5c17f9 100644 (file)
@@ -164,6 +164,8 @@ Engines_Component_i::~Engines_Component_i()
 {
   MESSAGE("Component destructor");
   Engines_Container_i::decInstanceCnt(_interfaceName);
+  if(_myConnexionToRegistry)delete _myConnexionToRegistry;
+  if(_notifSupplier)delete _notifSupplier;
 }
 
 //=============================================================================
index ea1c23c116885daa9e07fcc12c127767a9016386..41e2b5b61ab952a652a7f01ce896b388e41a39b7 100644 (file)
@@ -241,6 +241,35 @@ char* Engines_Container_i::name()
    return CORBA::string_dup(_containerName.c_str()) ;
 }
 
+//=============================================================================
+/*! 
+ *  CORBA attribute: Container working directory 
+ */
+//=============================================================================
+
+char* Engines_Container_i::workingdir()
+{
+  char wd[256];
+  getcwd (wd,256);
+  return CORBA::string_dup(wd) ;
+}
+
+//=============================================================================
+/*! 
+ *  CORBA attribute: Container log file name
+ */
+//=============================================================================
+
+char* Engines_Container_i::logfilename()
+{
+  return CORBA::string_dup(_logfilename.c_str()) ;
+}
+
+void Engines_Container_i::logfilename(const char* name)
+{
+  _logfilename=name;
+}
+
 //=============================================================================
 /*! 
  *  CORBA method: Get the hostName of the Container (without domain extensions)
index 9e3ee13839e0124fec946027ae525481b03056f2..03234c307d2a2a16d397b3d552b86f24a11b5f1d 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef _SALOME_COMPONENT_I_HXX_
 #define _SALOME_COMPONENT_I_HXX_
 
+#include <SALOMEconfig.h>
+
 #include <SALOME_Container.hxx>
 
 #include <iostream>
@@ -40,7 +42,6 @@
 #include <sys/types.h>
 #include <string>
 #include <map>
-#include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SALOME_Component)
 #include "NOTIFICATION.hxx"
 #include "Salome_file_i.hxx"
index b74dda3756bd2ab00479f0e0f0fd7caf81d4acb0..dd6ee5a308a3239049dc91473db4ca45d0ff7aa4 100644 (file)
@@ -278,6 +278,10 @@ StartContainer(const Engines::MachineParameters& params,
       //Engines::Container_var cont=Engines::Container::_narrow(obj);
     }
 
+  //redirect stdout and stderr in a file
+  string logFilename="/tmp/"+_NS->ContainerName(params)+"_"+GetHostname()+"_"+getenv( "USER" )+".log" ;
+  command += " > " + logFilename + " 2>&1 &";
+
   // launch container with a system call
   int status=system(command.c_str());
   if (status == -1){
@@ -308,7 +312,16 @@ StartContainer(const Engines::MachineParameters& params,
     }
     
     if ( CORBA::is_nil(ret) )
-      MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed");
+      {
+        MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed");
+      }
+    else
+      {
+        logFilename=":"+logFilename;
+        logFilename="@"+GetHostname()+logFilename;
+        logFilename=getenv( "USER" )+logFilename;
+        ret->logfilename(logFilename.c_str());
+      }
 
     return ret;
   }
index f39a54c4b4608fb08f767b626efe7c5c93c77619..153b381f84d8820656b3f04d66559535e8a1d98d 100644 (file)
@@ -83,6 +83,10 @@ public:
 
   virtual void ping();
   char* name();
+  char* workingdir();
+  char* logfilename();
+  void logfilename(const char* name);
+
   virtual void Shutdown();
   char* getHostName();
   CORBA::Long getPID();
@@ -125,6 +129,7 @@ protected:
   SALOME_NamingService *_NS ;
   std::string _library_path;
   std::string _containerName;
+  std::string _logfilename;
   CORBA::ORB_var _orb;
   PortableServer::POA_var _poa;
   PortableServer::ObjectId * _id ;
index 41b5adcea99d584163de9052b21f18b798bcba49..bf67a554cbd382c6e93e4cb6bc57cae2c5999619 100644 (file)
@@ -37,7 +37,9 @@ Engines_DSC_i(CORBA::ORB_ptr orb,
                                                          instanceName, 
                                                          interfaceName) 
 {
-  std::cout << "--Engines_DSC_i: MARK 1 --" << instanceName << "----" << std::endl;
+#ifdef _DEBUG_
+  std::cerr << "--Engines_DSC_i: MARK 1 --" << instanceName << "----" << std::endl;
+#endif
 }
 
 Engines_DSC_i::~Engines_DSC_i() {}
index b32d69bfdce21414664a93ca5a112b6ca02af2e8..399a62c229b08d1e5e17ebb5fe680a9ea3e7c462 100644 (file)
 
 Engines_DSC_interface::Engines_DSC_interface() {}
 
-Engines_DSC_interface::~Engines_DSC_interface() {}
+Engines_DSC_interface::~Engines_DSC_interface() 
+{
+  my_ports_it = my_ports.begin();
+  for(;my_ports_it != my_ports.end();my_ports_it++)
+    delete my_ports_it->second;
+
+}
 
 void
 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref, 
index 525843110c2414ea83bfa7349875ebd749de66c0..5bf5712d201c7b0e4037bd148e0557af21798f8d 100644 (file)
@@ -164,9 +164,9 @@ protected:
     std::string repository_id;
 
     // Specifique aux provides port;
-    Ports::Port_ptr provides_port_ref;
+    Ports::Port_var provides_port_ref;
 
-    Ports::PortProperties_ptr port_prop;
+    Ports::PortProperties_var port_prop;
   };
 
   typedef std::map<std::string, port_t *> ports;
index 0deafca8021e2b101f4148b6ebf4c4db48a5a9f4..dddf3aa063f20c47c9af8dfa00d8c709573e1a5e 100644 (file)
@@ -13,6 +13,7 @@
 #include <Calcium.hxx>
 #include <calcium.h>
 #include <Superv_Component_i.hxx>
+#include <Salome_file_i.hxx>
 #include <omniORB4/CORBA.h>
 
 //--- from omniORBpy.h (not present on Debian Sarge packages)
@@ -38,10 +39,6 @@ struct omniORBpyAPI {
 
   omniORBpyAPI* api;
 
-#define OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS \
-catch (const CORBA::SystemException& ex) { \
-  return api->handleCxxSystemException(ex); \
-}
 
 %}
 
@@ -66,11 +63,8 @@ catch (const CORBA::SystemException& ex) { \
 %}
 
 %include <exception.i>
-%include "carrays.i" 
 
-%array_class(int, intArray);
-%array_class(float, floatArray);
-%array_class(double, doubleArray);
+
 
 /*
  * Most of this code is borrowed from numpy distribution
@@ -114,13 +108,52 @@ char* pytype_string(PyObject* py_obj) {
   return "unkown type";
 }
 
+/*
+For documentation only : numpy typecodes
+
+enum NPY_TYPECHAR { NPY_BOOLLTR = '?',
+                        NPY_BYTELTR = 'b',
+                        NPY_UBYTELTR = 'B',
+                        NPY_SHORTLTR = 'h',
+                        NPY_USHORTLTR = 'H',
+                        NPY_INTLTR = 'i',
+                        NPY_UINTLTR = 'I',
+                        NPY_LONGLTR = 'l',
+                        NPY_ULONGLTR = 'L',
+                        NPY_LONGLONGLTR = 'q',
+                        NPY_ULONGLONGLTR = 'Q',
+                        NPY_FLOATLTR = 'f',
+                        NPY_DOUBLELTR = 'd',
+                        NPY_LONGDOUBLELTR = 'g',
+                        NPY_CFLOATLTR = 'F',
+                        NPY_CDOUBLELTR = 'D',
+                        NPY_CLONGDOUBLELTR = 'G',
+                        NPY_OBJECTLTR = 'O',
+                        NPY_STRINGLTR = 'S',
+                        NPY_STRINGLTR2 = 'a',
+                        NPY_UNICODELTR = 'U',
+                        NPY_VOIDLTR = 'V',
+                        NPY_CHARLTR = 'c',
+
+                        NPY_INTPLTR = 'p',
+                        NPY_UINTPLTR = 'P',
+
+                        NPY_GENBOOLLTR ='b',
+                        NPY_SIGNEDLTR = 'i',
+                        NPY_UNSIGNEDLTR = 'u',
+                        NPY_FLOATINGLTR = 'f',
+                        NPY_COMPLEXLTR = 'c'
+};
+*/
+
 /* Given a Numeric typecode, return a string describing the type.
  */
 char* typecode_string(int typecode) {
-  char* type_names[20] = {"char","unsigned byte","byte","short",
-        "unsigned short","int","unsigned int","long",
-        "float","double","complex float","complex double",
-        "object","ntype","unkown"};
+  char* type_names[] = {"bool","byte","unsigned byte","short",
+        "unsigned short","int","unsigned int","long","unsigned long",
+        "longlong","unsigned longlong",
+        "float","double","long double","complex float","complex double","complex long double",
+        "object","string","unicode","void","ntypes","notype","char","unkown"};
   return type_names[typecode];
 }
 
@@ -337,6 +370,45 @@ typedef PyObject ArrayObject;
 #endif
 %}
 
+%include "carrays.i" 
+
+%array_class(int, intArray);
+%array_class(float, floatArray);
+%array_class(double, doubleArray);
+
+/* special struct to handle string arrays */
+%inline %{
+struct stringArray
+{
+  stringArray(int nelements,int size=0) {
+    nelem=nelements;
+    data= new char*[nelements];
+    for(int i=0;i<nelements;i++)
+    {
+      data[i]=(char *)malloc((size+1)*sizeof(char));
+      data[i][size+1]='\0';
+    }
+  }
+  ~stringArray() 
+  {
+    std::cerr << "~stringArray() " << nelem << std::endl;
+    for(int i=0;i<nelem;i++)
+      free(data[i]);
+    delete [] data;
+  }
+  char* __getitem__(int index) {
+    return data[index];
+  }
+  void __setitem__(int index, char* value) {
+    free(data[index]);
+    data[index] = strdup(value);
+  }
+  char** data;
+  int nelem;
+};
+%}
+/* End of special struct to handle string arrays */
+
 /* input typemap 
    This typemap can be used for input array objects only.
    It accepts swig carray objects or numpy contiguous or non contiguous objects.
@@ -373,6 +445,55 @@ TYPEMAP_IN3(double,  PyArray_DOUBLE)
 %apply float*  IN_ARRAY3 {float  *eval};
 %apply double* IN_ARRAY3 {double *eval};
 
+/*  Specific typemap for complex */
+%typemap(in) float*  ecpval
+             (ArrayObject* array=NULL, int is_new_object) {
+  int size[1] = {-1};
+  if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
+  {
+%#ifdef WITH_NUMPY
+    array = obj_to_array_contiguous_allow_conversion($input, PyArray_CFLOAT, &is_new_object);
+    if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
+    $1 = (float*) array->data;
+%#else
+    SWIG_exception(SWIG_TypeError, "complex array expected");
+%#endif
+  }
+}
+%typemap(freearg) float* ecpval {
+  if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
+}
+/* End of  Specific typemap for complex */
+
+/* array of strings on input */
+%typemap(in) char** eval
+         (ArrayObject* array=NULL, int is_new_object) {
+  int size[1] = {-1};
+  stringArray* sarray;
+  if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *),0)) == -1)
+  {
+%#ifdef WITH_NUMPY
+    array = obj_to_array_contiguous_allow_conversion($input, PyArray_STRING, &is_new_object);
+    if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
+    $1 = (char**) malloc(array_size(array,0)*sizeof(char*));
+    for(int i=0;i<array_size(array,0);i++)
+      $1[i]=(char*) array->data + i* array->strides[0];
+%#else
+    SWIG_exception(SWIG_TypeError, "string array expected");
+%#endif
+  }
+  else
+  {
+    $1=sarray->data;
+  }
+}
+
+%typemap(freearg) char** eval {
+  if (array$argnum) free($1);
+  if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
+}
+/* End of array of strings on input */
+
 /* inplace typemaps 
    This typemap can be used for input/output array objects.
    It accepts swig carray objects or numpy contiguous objects.
@@ -403,94 +524,145 @@ TYPEMAP_INPLACE3(double,  PyArray_DOUBLE)
 %apply float*  INPLACE_ARRAY3 {float  *lval};
 %apply double* INPLACE_ARRAY3 {double *lval};
 
-
-%typemap(in) CORBA::Boolean
-{
-  $1=(CORBA::Boolean)PyInt_AsLong($input);
+/*  typemap for complex inout */
+%typemap(in) float* lcpval
+             (ArrayObject* temp=NULL) {
+  if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0)) == -1)
+  {
+%#ifdef WITH_NUMPY
+    temp = obj_to_array_no_conversion($input,PyArray_CFLOAT);
+    if (!temp  || !require_contiguous(temp)) SWIG_fail;
+    $1 = (float*) temp->data;
+%#else
+    SWIG_exception(SWIG_TypeError, "complex array expected");
+%#endif
+  }
 }
+/*  End of typemap for complex inout */
 
-%typemap(in) CORBA::ORB_ptr 
-{
-  try {
-     CORBA::Object_ptr obj = api->pyObjRefToCxxObjRef($input,1);
-     $1 = CORBA::ORB::_narrow(obj);
+/* typemap for array of strings on input/output */
+%typemap(in) char** lval
+            (ArrayObject* temp=NULL) {
+  stringArray* sarray;
+  if ((SWIG_ConvertPtr($input, (void **) &sarray, $descriptor(stringArray *) ,0)) == -1)
+  {
+%#ifdef WITH_NUMPY
+    temp = obj_to_array_no_conversion($input,PyArray_STRING);
+    if (!temp  || !require_contiguous(temp)) SWIG_fail;
+    $1 = (char**) malloc(array_size(temp,0)*sizeof(char*));
+    for(int i=0;i<array_size(temp,0);i++)
+      $1[i]=(char*) temp->data+i*temp->strides[0];
+%#else
+    SWIG_exception(SWIG_TypeError, "string array expected");
+%#endif
   }
-  catch (...) {
-     PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
+  else
+  {
+    $1=sarray->data;
   }
 }
+%typemap(freearg) char** lval {
+  if (temp$argnum) free($1);
+}
+/* End of typemap for array of strings on input/output */
 
-%typemap(in) PortableServer::POA_ptr
+%typemap(in) CORBA::Boolean
 {
-  try {
-     CORBA::Object_ptr obj = api->pyObjRefToCxxObjRef($input,1);
-     $1 = PortableServer::POA::_narrow(obj);
-  }
-  catch (...) {
-     PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
-  }
+  $1=(CORBA::Boolean)PyInt_AsLong($input);
 }
 
-%typemap(in) Engines::Container_ptr
+%define CORBAPTR(type)
+%typemap(in) type##_ptr
 {
-  try {
-     CORBA::Object_ptr obj = api->pyObjRefToCxxObjRef($input,1);
-     $1 = Engines::Container::_narrow(obj);
+  Py_BEGIN_ALLOW_THREADS
+  try
+  {
+     CORBA::Object_var obj = api->pyObjRefToCxxObjRef($input,0);
+     $1 = type##::_narrow(obj);
   }
-  catch (...) {
+  catch(...)
+  {
+     Py_BLOCK_THREADS
      PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
   }
+  Py_END_ALLOW_THREADS
+}
+%typemap(freearg) type##_ptr {
+  CORBA::release($1);
 }
+%enddef
+
+CORBAPTR(CORBA::ORB)
+CORBAPTR(Ports::PortProperties)
+CORBAPTR(Ports::Port)
+CORBAPTR(Engines::Container)
+CORBAPTR(PortableServer::POA)
 
-%typemap(in) Ports::Port_ptr
+%typemap(out) Ports::Port_ptr 
 {
-  try {
-     CORBA::Object_ptr obj = api->pyObjRefToCxxObjRef($input,1);
-     $1 = Ports::Port::_narrow(obj);
-  }
-  catch (...) {
-     PyErr_SetString(PyExc_RuntimeError, "not a valid CORBA object ptr");
-  }
+  $result = api->cxxObjRefToPyObjRef($1, 1);
+  //All output Ports::Port_ptr variables are duplicated by security. Need to release them for python . Explanation ??
+  CORBA::release($1);
 }
 
-%typemap(out) Ports::Port_ptr , Ports::PortProperties_ptr
+%typemap(out) Ports::PortProperties_ptr, Engines::Salome_file_ptr
 {
   $result = api->cxxObjRefToPyObjRef($1, 1);
 }
 
+%typemap(out) Engines::DSC::uses_port *
+{
+   $result = PyList_New($1->length());
+   for (CORBA::ULong i=0; i < $1->length() ; i++)
+     PyList_SetItem($result,i,api->cxxObjRefToPyObjRef((*$1)[i], 1));
+   //delete the copy (created by new) of uses port sequence
+   delete $1;
+}
+
 /*
  * Exception section
  */
 // a general exception handler
 %exception {
+   Py_BEGIN_ALLOW_THREADS
    try {
       $action
    }
    catch(Engines::DSC::PortNotDefined& _e) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_ValueError,"Port not defined");
       return NULL;
    }
    catch(Engines::DSC::PortNotConnected& _e) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_ValueError,"Port not connected");
       return NULL;
    }
    catch(Engines::DSC::BadPortType& _e) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_ValueError,"Bad port type");
       return NULL;
    }
    catch (SALOME_Exception &e) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_RuntimeError,e.what());
       return NULL;
    }
    catch (SALOME::SALOME_Exception &e) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_RuntimeError,e.details.text);
       return NULL;
    }
-   OMNIPY_CATCH_AND_HANDLE_SYSTEM_EXCEPTIONS
+   catch (const CORBA::SystemException& e) {
+      Py_BLOCK_THREADS 
+      return api->handleCxxSystemException(e);
+   }
    catch(...) {
+      Py_BLOCK_THREADS
       PyErr_SetString(PyExc_ValueError,"Unknown exception");
       return NULL;
    }
+   Py_END_ALLOW_THREADS
 }
 
 /*
@@ -565,6 +737,23 @@ class PySupervCompo:public Superv_Component_i
 
     virtual Ports::PortProperties_ptr get_port_properties(const char* port_name);
 
+// Interface for Salome_file
+    Engines::Salome_file_ptr getInputFileToService(const char* service_name, const char* Salome_file_name);
+    void checkInputFilesToService(const char* service_name);
+    Engines::Salome_file_ptr setInputFileToService(const char* service_name, const char* Salome_file_name);
+    Engines::Salome_file_ptr getOutputFileToService(const char* service_name, const char* Salome_file_name);
+    void checkOutputFilesToService(const char* service_name);
+    Engines::Salome_file_ptr setOutputFileToService(const char* service_name, const char* Salome_file_name);
+// End of Interface for Salome_file
+
+// DSC interface for python components
+  virtual void add_provides_port(Ports::Port_ptr ref, const char* provides_port_name, Ports::PortProperties_ptr port_prop);
+  virtual void add_uses_port(const char* repository_id, const char* uses_port_name, Ports::PortProperties_ptr port_prop);
+  virtual Engines::DSC::uses_port * get_uses_port(const char* uses_port_name);
+// End of DSC interface for python components
+
+
+
     %extend
       {
        //To get the address of the component
@@ -592,14 +781,17 @@ int  cp_cd(Superv_Component_i *component,char *name);
 int cp_een(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
 int cp_edb(Superv_Component_i *component,int dep,double t,int n,char *nom,int nval,double *eval);
 int cp_ere(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
-int cp_ecp(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *eval);
+int cp_ecp(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,float  *ecpval);
 int cp_elo(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,int    *eval);
+int cp_ech(Superv_Component_i *component,int dep,float  t,int n,char *nom,int nval,char** eval,int strSize);
+
 
 int cp_len(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
 int cp_ldb(Superv_Component_i *component,int dep,double *ti,double *tf,int *niter,char *nom,int nmax,int *nval,double *lval);
 int cp_lre(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
-int cp_lcp(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lval);
+int cp_lcp(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,float  *lcpval);
 int cp_llo(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,int    *lval);
+int cp_lch(Superv_Component_i *component,int dep,float  *ti,float  *tf,int *niter,char *nom,int nmax,int *nval,char** lval,int strSize);
 
 int cp_fin(Superv_Component_i *component,int cp_end);
 
index c96fdc16c72cfc031a3e2f1655e5dbe2501ba327..48836d661f3bd1c2b6d868d2c7afafaf31d8f3df 100644 (file)
@@ -51,3 +51,21 @@ class PyDSCComponent(SALOME_ComponentPy.SALOME_ComponentPy_i,
   def get_port_properties(self,name):
     return self.proxy.get_port_properties(name)
 
+  def setInputFileToService(self,service_name,Salome_file_name):
+    return self.proxy.setInputFileToService(service_name,Salome_file_name)
+
+  def checkInputFilesToService(self,service_name):
+    return self.proxy.checkInputFilesToService(service_name)
+
+  def getInputFileToService(self,service_name,Salome_file_name):
+    return self.proxy.getInputFileToService(service_name,Salome_file_name)
+
+  def setOutputFileToService(self,service_name,Salome_file_name):
+    return self.proxy.setOutputFileToService(service_name,Salome_file_name)
+
+  def getOutputFileToService(self,service_name,Salome_file_name):
+    return self.proxy.getOutputFileToService(service_name,Salome_file_name)
+
+  def checkOutputFilesToService(self,service_name):
+    return self.proxy.checkOutputFilesToService(service_name)
+
index df33f65510784f58195a7bc96e56e825dacf9812..51ae3afd92d2f5eb3f576a11b7068cce94548d84 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef _DATA_SHORT_PORT_PROVIDES_HXX_
 #define _DATA_SHORT_PORT_PROVIDES_HXX_
 
+#include <SALOMEconfig.h>
+
 #include <iostream>
 #include "SALOME_Ports.hh"
 #include "provides_port.hxx"
index de497f752af6381047af73857084ba4a057fc16e..cba14ca11ede2f90fbb3bf8e59534040a3119d69 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  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. 
-// 
-//  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
-//
-//
-//
-//  File   : Calcium.c
-//  Author : Eric Fayolle (EDF)
-//  Module : KERNEL
-// Id          : $Id$
+/*  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, */
+/*  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS  */
+
+/*  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.  */
+
+/*  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 */
+
+
+
+/*  File   : Calcium.c */
+/*  Author : Eric Fayolle (EDF) */
+/*  Module : KERNEL */
+/* Id          : $Id$ */
 
 #include "calcium.h"
 #include <stdlib.h>
 // Interface C de SalomeCalcium 
 
 typedef int InfoType;
-typedef int bool;
+typedef char bool;
 
-// INTERFACES DE LECTURE
+/* INTERFACES DE LECTURE en 0 copie */
 
+/* Definition des méthodes calcium Ã©tendues en 0 copie */
+/* Le buffer est alloué par le port pas par l'utilisateur */
+/* Remarquer le type ** de data */
+/* L'utilisateur devra appeler ecp_..._free pour désallouer le buffer interne */
+/* Attention en cas de lectures multiples : le buffer retourné est le même */
+/* Attention si les niveaux sont actifs le buffer peut Ãªtre supprimé automatiquement par calcium. */
 
-// Definition des méthodes calcium Ã©tendues 
-// permettant le 0 copy.
-//const char * nomvar
 #define CALCIUM_EXT_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
   InfoType ecp_##_name (void * component, int mode,                    \
                        _timeType * ti, _timeType * tf, int * i,        \
@@ -70,60 +73,116 @@ typedef int bool;
     ecp_lecture_##_typeName##_free(data);                                      \
   };
 
+#define STAR *
 CALCIUM_EXT_LECT_INTERFACE_C_(len,float,int,int,);
 CALCIUM_EXT_LECT_INTERFACE_C_(lre,float,float,float,);
 CALCIUM_EXT_LECT_INTERFACE_C_(ldb,double,double,double,);
-CALCIUM_EXT_LECT_INTERFACE_C_(llo,float,bool,bool,);
+/* CALCIUM_EXT_LECT_INTERFACE_C_(llo,float,bool,bool,); */
 CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,);
-#define STAR *
-//  CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]); 
-// La signature n'est pas la même pour les chaines de caractères il y a aussi 
-// la taille des chaines
+/* CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]);  */
 
-//const char * nomvar
 
-#define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual)               \
+
+/* INTERFACES DE LECTURE avec recopie */
+
+#define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
   InfoType cp_##_name (void * component, int mode,                     \
                       _timeType * ti, _timeType * tf, int * i,         \
                       char * nomvar, int bufferLength,                 \
                       int * nRead, _type _qual * data ) {              \
     size_t _nRead;                                                     \
     long   _i=*i;                                                      \
-    fflush(stdout);           \
-    fflush(stderr);           \
-    fprintf(stderr,"Beginning of CPLxx: %s %d %f\n",nomvar,*i,*ti); \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
+    fprintf(stderr,"Beginning of cp_" #_name " : %s %d %f\n",nomvar,*i,*ti); \
                                                                        \
     if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL;       \
                                                                        \
-    InfoType info =  ecp_lecture_##_typeName (component, mode, ti, tf, &_i,    \
+    InfoType info =  ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \
                                         nomvar, bufferLength, &_nRead, \
-                                        &data );                       \
-    if(mode == CP_SEQUENTIEL)   \
-      *i = _i;                                                 \
+                                             &data );                  \
+    if(mode == CP_SEQUENTIEL)                                          \
+      *i = _i;                                                         \
     *nRead=_nRead;                                                     \
-    fprintf(stderr,"End of CPLxx: %s %d \n",nomvar,*i); \
-    fflush(stdout);           \
-    fflush(stderr);           \
+    fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,*i);               \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
                                                                        \
     return info;                                                       \
   };                                                                   \
   void cp_##_name##_free ( _type _qual * data) {                       \
-    ecp_lecture_##_typeName##_free(data);                                      \
+    ecp_lecture_##_typeName##_free(data);                              \
   };
 
 
-// Definition des méthodes calcium standard 
+
+InfoType cp_lch(void * component, int mode, float * ti,        float * tf, int * i,
+               char  * nomvar, int bufferLength, int * nRead,
+               char ** data, int strSize) {
+
+  size_t _nRead;                                                       
+  long   _i=*i;                                                        
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cp_lch: %s %d %f\n",nomvar,*i,*ti);     
+                                                                       
+  if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; 
+  
+  InfoType info =  ecp_lecture_str (component, mode, ti, tf, &_i, 
+                                   nomvar, bufferLength, &_nRead, 
+                                   &data);/*, strSize );*/
+  if(mode == CP_SEQUENTIEL)                                            
+    *i = _i;                                                           
+  *nRead=_nRead;                                                       
+  fprintf(stderr,"End of cp_lch: %s %d \n",nomvar,*i);                 
+  fflush(stdout);fflush(stderr);                                                       
+                                                                       
+  return info;                                                 
+};                                                                     
+
+InfoType cp_llo(void * component, int mode, float * ti,        float * tf, int * i,
+               char  * nomvar, int bufferLength, int * nRead,
+               int * data ) {
+
+  bool    *dLogique=NULL;
+  size_t _nRead;                                                       
+  long   _i=*i;
+  int j;
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cpllo: %s %d %f\n",nomvar,*i,*ti);      
+                                                                       
+  if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; 
+
+  dLogique = (bool *) malloc(bufferLength * sizeof(int));
+
+  InfoType info =  ecp_lecture_bool (component, mode, ti, tf, &_i, 
+                                    nomvar, bufferLength, &_nRead, 
+                                    &dLogique);
+  if(mode == CP_SEQUENTIEL)                                            
+    *i = _i;                                                           
+  *nRead=_nRead;
+
+  for ( j=0; j<_nRead; ++j) data[j] = dLogique[j];
+  free(dLogique);
+  
+  fprintf(stderr,"End of cpllo: %s %d \n",nomvar,*i);                  
+  fflush(stdout);fflush(stderr);                                                       
+                                                                       
+  return info;                                                 
+};                                                                     
+
+
+/* Definition des méthodes calcium standard  */
 
 CALCIUM_LECT_INTERFACE_C_(len,float,int,int,);
 CALCIUM_LECT_INTERFACE_C_(lre,float,float,float,);
 CALCIUM_LECT_INTERFACE_C_(ldb,double,double,double,);
-CALCIUM_LECT_INTERFACE_C_(llo,float,bool,bool,);
+/* CALCIUM_LECT_INTERFACE_C_(llo,float,bool,bool,); */
 CALCIUM_LECT_INTERFACE_C_(lcp,float,float,cplx,);
 #define STAR *
-//  CALCIUM_LECT_INTERFACE_C_(lch,float,char,STAR);
+/*   CALCIUM_LECT_INTERFACE_C_(lch,float,char,STAR); */
 
 
-// INTERFACES DE DÉBUT ET DE FIN DE COUPLAGE
+/*  INTERFACES DE DÉBUT ET DE FIN DE COUPLAGE */
 
 InfoType cp_cd (void * component, char * instanceName) {
   /* TODO : Trouver le nom de l'instance SALOME*/
@@ -139,6 +198,7 @@ InfoType cp_fin (void * component, int code) {
 }
 
 
+/*  INTERFACES D'ECRITURE  */
 
 #define CALCIUM_ECR_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual)        \
   InfoType cp_##_name (void * component, int mode,                     \
@@ -147,27 +207,74 @@ InfoType cp_fin (void * component, int code) {
                       _type _qual * data ) {                           \
                                                                        \
     /*long   _i=i;*/                                                   \
-    fflush(stdout);           \
-    fflush(stderr);           \
-    fprintf(stderr,"Beginning of CPExx: %s %d %f\n",nomvar,i,t); \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
+    fprintf(stderr,"Beginning of cp_" #_name " : %s %d %f\n",nomvar,i,t);      \
     if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL;             \
                                                                        \
     InfoType info =  ecp_ecriture_##_typeName (component, mode, &t, i, \
                                               nomvar, nbelem,          \
                                               data );                  \
-    fprintf(stderr,"End of CPExx: %s %d \n",nomvar,i); \
-    fflush(stdout);           \
-    fflush(stderr);           \
+    fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,i);                \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
                                                                        \
     return info;                                                       \
   };                                                                   \
 
 
-// Definition des méthodes calcium standard 
+
+InfoType cp_ech(void * component, int mode, float t, int i,
+               char  * nomvar,  int nbelem,
+               char ** data, int strSize) {
+                                                                       
+  /*long   _i=i;*/                                                     
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cp_ech: %s %d %f\n",nomvar,i,t);        
+  if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL;               
+    
+  InfoType info =  ecp_ecriture_str (component, mode, &t, i,   
+                                    nomvar, nbelem,            
+                                    data);/*, strSize );*/
+  fprintf(stderr,"End of cp_ech: %s %d \n",nomvar,i);                  
+  fflush(stdout);                                                      
+  fflush(stderr);                                                      
+                                                                       
+  return info;                                                 
+};                                                                     
+
+InfoType cp_elo(void * component, int mode, float t, int i,
+               char  * nomvar,  int nbelem,
+               int * data ) {
+                                                                       
+  /*long   _i=i;*/                                                     
+  bool * dLogique = NULL;
+  int j=0;
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cpelo: %s %d %f\n",nomvar,i,t); 
+  if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL;               
+
+  dLogique = (bool *) malloc(nbelem * sizeof(int));
+  for (j=0; j<nbelem; ++j) dLogique[j]=data[j];
+
+  InfoType info =  ecp_ecriture_bool (component, mode, &t, i,  
+                                    nomvar, nbelem,            
+                                    dLogique);
+
+  free(dLogique);
+
+  fprintf(stderr,"End of cpelo: %s %d \n",nomvar,i);                   
+  fflush(stdout);                                                      
+  fflush(stderr);                                                      
+                                                                       
+  return info;                                                 
+};                                                                     
+
+/*  Definition des méthodes calcium standard  */
 
 CALCIUM_ECR_INTERFACE_C_(een,float,int,int,);
 CALCIUM_ECR_INTERFACE_C_(ere,float,float,float,);
 CALCIUM_ECR_INTERFACE_C_(edb,double,double,double,);
-CALCIUM_ECR_INTERFACE_C_(elo,float,bool,bool,);
+/*CALCIUM_ECR_INTERFACE_C_(elo,float,bool,bool,);*/
 CALCIUM_ECR_INTERFACE_C_(ecp,float,float,cplx,);
 
index c17ddb80a321f590114eb6925658bbc0579755ed..39a8cac490f3ac57edf3170a4747b52891de6379 100644 (file)
@@ -43,6 +43,18 @@ extern "C"
       {
         dynamic_cast<calcium_integer_port_provides *>(port)->setDependencyType(depend);
       }
+    else if(std::string(type)=="CALCIUM_string")
+      {
+        dynamic_cast<calcium_string_port_provides *>(port)->setDependencyType(depend);
+      }
+    else if(std::string(type)=="CALCIUM_logical")
+      {
+        dynamic_cast<calcium_logical_port_provides *>(port)->setDependencyType(depend);
+      }
+    else if(std::string(type)=="CALCIUM_complex")
+      {
+        dynamic_cast<calcium_complex_port_provides *>(port)->setDependencyType(depend);
+      }
     else
       {
         std::cerr << "unknown type:" << std::endl;
index a6c301ee67596f2e9b385f8f0de1f6df44163ee3..1fe1c0e5b04ee4876376b18c51fa66463cfcc48f 100644 (file)
@@ -34,6 +34,8 @@
 #include "CouplingPolicy.hxx"
 #include "AdjacentFunctor.hxx"
 #include <boost/lambda/lambda.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
 #include "CalciumTypes.hxx"
 #include "CalciumException.hxx"
 
@@ -44,7 +46,8 @@ public:
 
   template <typename T_TIME, typename T_TAG >        class InternalDataIdContainer;
   template <typename T_TIME, typename T_TAG > friend class InternalDataIdContainer;
-  template <typename DataManipulator >        friend class BoundedDataIdProcessor;
+  template <typename DataManipulator, 
+    class EnableIf >                  friend class BoundedDataIdProcessor;
   template <typename DataManipulator >        friend class EraseDataIdProcessor;
   template <typename DataManipulator >        friend class DisconnectProcessor;
 
@@ -103,8 +106,9 @@ public:
   inline TimeType getTime(const DataId &dataId) const { return dataId.first;}
   inline TagType  getTag (const DataId &dataId) const { return dataId.second;}
 
-  // TODO : Vérifier l'application pour tous les types de données
-  template <typename DataManipulator>  struct BoundedDataIdProcessor;
+  template <typename DataManipulator, 
+           class EnableIf = void >    struct BoundedDataIdProcessor;
+  //template <typename DataManipulator>  struct BoundedDataIdProcessor;
   template <typename DataManipulator>  struct EraseDataIdProcessor;
   template <typename DataManipulator>  struct DisconnectProcessor;
 
@@ -157,10 +161,24 @@ struct CalciumCouplingPolicy::InternalDataIdContainer : public std::vector< std:
 };
 
 
-// TODO : Vérifier l'application pour tous les types de données
-// DESACTIVER POUR ?BOOL? et CHAR *
-template <typename DataManipulator>
+template <typename DataManipulator, class EnableIf >
 struct CalciumCouplingPolicy::BoundedDataIdProcessor{
+  BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
+  template < typename Iterator, typename DataId > 
+  void inline apply(typename iterator_t<Iterator>::value_type & data,
+                   const DataId & dataId,
+                   const Iterator  & it1) const {
+    typedef typename iterator_t<Iterator>::value_type value_type;
+    std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl;
+
+  }
+};
+
+
+template <typename DataManipulator >
+struct CalciumCouplingPolicy::BoundedDataIdProcessor<
+  DataManipulator, 
+  typename boost::enable_if< boost::is_float< typename DataManipulator::InnerType> >::type > {
     
   const CalciumCouplingPolicy & _couplingPolicy;
     
@@ -232,8 +250,8 @@ struct CalciumCouplingPolicy::BoundedDataIdProcessor{
 
       boost::lambda::placeholder1_type _1;
       boost::lambda::placeholder2_type _2;
-      // REM : Pour des buffers de type int
-      // le compilo indiquera warning: converting to `long int' from `Double'
+      // OLD: REM : Pour des buffers de type int
+      // OLD: le compilo indiquera warning: converting to `long int' from `Double'
       std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
                             ( _1 - _2 ) * coeff + _2 );
 //       for(size_t i =0;  i < dataSize3; ++i) {
index 8e8453c953e101e95a4160ef47678698b97b00f4..504d3b2562d182318e0071fd9bb0af797c796610 100644 (file)
 #ifndef _CALCIUM_INTERFACE_HXX_
 #define _CALCIUM_INTERFACE_HXX_
 
-#include <string>
-#include <vector>
-#include <iostream>
-#include "Superv_Component_i.hxx"
+//Interface C++
+#include "CalciumCxxInterface.hxx"
+
 #include "CalciumException.hxx"
 #include "CalciumTypes.hxx"
-#include "CalciumGenericUsesPort.hxx"
-#include "Copy2UserSpace.hxx"
-#include "Copy2CorbaSpace.hxx"
-#include "CalciumPortTraits.hxx"
 
 #include <stdio.h>
 
 //#define _DEBUG_
 
-// Déplacer cette information dans CorbaTypeManipulator
-// Gérer en même temps la recopie profonde.
-
-template <typename T1, typename T2>
-struct IsSameType {
-  static const bool value = false;
-};
-template <typename T1>
-struct IsSameType<T1,T1> {
-  static const bool value = true;
-};
-
-
-
-
-//class CalciumInterface {
-namespace CalciumInterface {
-//public :
-
-
-  static void
-  ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
-  { 
-    std::vector<std::string> usesPortNames;
-    std::vector<std::string>::const_iterator it;
-    component.get_uses_port_names(usesPortNames);    
-    
-    //récupérer le type de réel du port est un peu difficile
-    //car l'interface nous donne aucune indication
-
-    //     uses_port *myUsesPort;
-    calcium_uses_port* myCalciumUsesPort;
-      
-    for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) {
-      try {
-
-       myCalciumUsesPort= 
-         component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
-
-//     component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
-//     calcium_uses_port* myCalciumUsesPort=
-//       dynamic_cast<calcium_uses_port*>(myUsesPort);
-
-#ifdef _DEBUG_
-       std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<< 
-         //      typeid(myUsesPort).name() <<"-------------" <<
-         typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
-#endif
-       
-//     if ( !myCalciumUsesPort )
-//       throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
-//                                             << *it << " en port de type calcium_uses_port." ));
-
-       myCalciumUsesPort->disconnect(provideLastGivenValue);
-
-      } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-       std::cerr << ex.what() << std::endl;
-#endif
-       throw (CalciumException(CalciumTypes::CPTPVR,ex));
-      } catch ( const DSC_Exception & ex) {
-#ifdef _DEBUG_
-       std::cerr << ex.what() << std::endl;
-#endif
-       // Exception venant de SupervComponent :
-       //   PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)  
-       // ou du port uses : Dsc_Exception
-       // On continue Ã  traiter la deconnexion des autres ports uses
-      } catch (...) {
-       throw (CalciumException(CalciumTypes::CPATAL,"Exception innatendue"));
-       // En fonction du mode de gestion des erreurs throw;
-      }
-    }
-  }
-
-
-  // Uniquement appelé par l'utilisateur s'il a passé un pointeur de données NULL
-  // Ã  l'appel de ecp_lecture (demande de 0 copie)
-  template <typename T1, typename T2> static void
-  ecp_free ( T1 * dataPtr )
-  {
-    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
-    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                DataType; // Attention != T
-    typedef typename DataManipulator::InnerType           InnerType;
-
-    DeleteTraits<IsSameType<T1,InnerType>::value >::apply(dataPtr);
-  }
-
-  template <typename T1> static void
-  ecp_free ( T1 * dataPtr )
-  {
-    ecp_free<T1,T1> ( dataPtr );
-  }
-
-  template <typename T1 > static void
-  ecp_lecture ( Superv_Component_i & component,
-              CalciumTypes::DependencyType dependencyType,
-              double        & ti,
-              double const  & tf,
-              long          & i,
-              const string  & nomVar, 
-              size_t bufferLength,
-              size_t & nRead, 
-              T1 * &data )
-  {
-    ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
-                       i,nomVar,bufferLength,nRead,data);
-  
-  }
-
-  template <typename T1, typename T2 > static void
-  ecp_lecture ( Superv_Component_i & component,
-              CalciumTypes::DependencyType dependencyType,
-              double        & ti,
-              double const  & tf,
-              long          & i,
-              const string  & nomVar, 
-              size_t bufferLength,
-              size_t & nRead, 
-              T1 * &data )
-  {
-
-    assert(&component);
-
-    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
-    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T
-    typedef typename DataManipulator::InnerType           InnerType;
-
-    CorbaDataType     corbaData;
-    long         ilong;
-
 #ifdef _DEBUG_
-    std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
-#endif
-
-    if (nomVar.empty())
-      throw CalciumException(CalciumTypes::CPNMVR,
-                               LOC("Le nom de la variable est <nul>"));
-    PortType * port;
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 2 ------------------" << std::endl;
-#endif
-
-    try {
-      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
-#endif
-    } catch ( const Superv_Component_i::PortNotDefined & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPNMVR,ex));
-    } catch ( const Superv_Component_i::PortNotConnected & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;;
-#endif
-      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
-      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
-    } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPTPVR,ex));
-    }
-  
-    // mode == mode du port 
-    CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
-
-    if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                            LOC(OSS()<<"Le mode de dépendance de la variable " 
-                                << nomVar << " est indéfini."));
-
-    if ( ( portDependencyType != dependencyType ) && 
-        ( dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) 
-      throw CalciumException(CalciumTypes::CPITVR,
-                            LOC(OSS()<<"Le mode de dépendance de la variable " 
-                                << nomVar << ": " << portDependencyType << " ne correspond pas au mode demandé: " << dependencyType));
-
-  
-    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
-      corbaData = port->get(ti,tf, 0);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
-#endif
-    } 
-    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
-      corbaData = port->get(0, i);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
-#endif
-    } else {
-      // Lecture en séquence
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
-#endif
-      corbaData = port->next(ti,i);
-    }
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
-#endif
-    size_t corbaDataSize = DataManipulator::size(corbaData);
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
-#endif
-   
-    // Vérifie si l'utilisateur demande du 0 copie
-    if ( data == NULL ) {
-      if ( bufferLength != 0 ) {
-       MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
-      }
-      nRead = corbaDataSize;
-      // Si les types T et InnerType sont différents, il faudra effectuer tout de même une recopie
-      if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
-#endif
-      // On essaye de faire du 0 copy si les types T et InnerType sont les mêmes
-      Copy2UserSpace< IsSameType<T1,InnerType>::value >::apply(data,corbaData,nRead);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
-#endif
-      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-      // la donnée corba associée Ã  un DataId ! Ne pas effectuer la desallocation suivante :
-      //  old : Dans les deux cas la structure CORBA n'est plus utile 
-      //  old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
-      //  old : Dans l'autre cas seul la coquille CORBA est détruite 
-      //  tjrs correct : Dans les deux cas l'utilisateur devra appeler ecp_free (version modifiée)
-      // DataManipulator::delete_data(corbaData);
-   } else {
-      nRead = std::min < size_t > (corbaDataSize,bufferLength);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
-#endif
-      Copy2UserSpace<false>::apply(data,corbaData,nRead);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
-#endif
-      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-      // la donnée corba associée Ã  un DataId ! Ne pas effectuer la desallocation suivante :
-      //      DataManipulator::delete_data(corbaData);
-   }
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
-    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
-    std::cout << "Ptr :" << data << std::endl;
-
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
-#endif
-  
-    return;
-  }
-
-
-  template <typename T1> static void
-  ecp_ecriture ( Superv_Component_i & component,
-                CalciumTypes::DependencyType dependencyType,
-                double const  & t,
-                long   const  & i,
-                const string  & nomVar, 
-                size_t bufferLength,
-                T1  & data ) {
-    ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data); 
-  }
-
-  template <typename T1, typename T2> static void
-  ecp_ecriture ( Superv_Component_i & component,
-                CalciumTypes::DependencyType dependencyType,
-                double const  & t,
-                long   const  & i,
-                const string  & nomVar, 
-                size_t bufferLength,
-                T1  & data ) 
-  {
-    
-    assert(&component);
-
-    //typedef typename StarTrait<TT>::NonStarType           T;
-    typedef typename UsesPortTraits<T2>::PortType          PortType;
-    typedef typename ProvidesPortTraits<T2>::PortType      ProvidesPortType;
-    typedef typename ProvidesPortType::DataManipulator     DataManipulator;
-    // Verifier que l'on peut définir UsesPortType::DataManipulator
-    //    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
-    typedef typename DataManipulator::InnerType           InnerType;
-
-#ifdef _DEBUG_
-    std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
-#endif
-    if ( nomVar.empty() ) throw CalciumException(CalciumTypes::CPNMVR,
-                                                   LOC("Le nom de la variable est <nul>"));
-    PortType * port;
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl;
-#endif
-
-    try {
-      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
-#endif
-    } catch ( const Superv_Component_i::PortNotDefined & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPNMVR,ex));
-    } catch ( const Superv_Component_i::PortNotConnected & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;;
-#endif
-      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
-      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
-    } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPTPVR,ex));
-    }
-    // mode == mode du port 
-    // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
-    // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
-
-//     CalciumTypes::DependencyType portDependencyType;
-//     try {
-//       portDependencyType = port->getDependencyType();
-//       std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
-//     } catch ( const DSC_Exception & ex ) {
-//       std::cerr << ex.what() << std::endl;;
-//       throw (CalciumException(CalciumTypes::CPIT,ex));
-//     }
-
-    if ( dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                               LOC(OSS()<<"Le mode de dépendance demandé pour la variable " 
-                                   << nomVar << " est indéfini."));
-
-    if ( dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                               LOC(OSS()<<"Le mode de dépendance SEQUENCE_DEPENDENCY pour la variable " 
-                                   << nomVar << " est impossible en Ã©criture."));
-
-    // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
-    // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
-    // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
-    // modifier l'interface IDL pour y ajouter un mode de dépendance !
-    // ---->
-//     if ( portDependencyType != dependencyType ) 
-//       throw CalciumException(CalciumTypes::CPITVR,
-//                             LOC(OSS()<<"Le mode de dépendance de la variable " 
-//                                 << nomVar << " ne correspond pas au mode demandé."));
-
-  
-    if ( bufferLength < 1 )
-      throw CalciumException(CalciumTypes::CPNTNULL,
-                               LOC(OSS()<<"Le buffer a envoyer est de taille nulle "));
-
-
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
-#endif
-    CorbaDataType corbaData;
-
-    
-    // Si les types Utilisateurs et CORBA sont différents
-    // il faut effectuer une recopie sinon on utilise directement le
-    // buffer data pour constituer la séquence
-    // TODO : 
-    // - Attention en mode asynchrone il faudra eventuellement
-    //   faire une copie des données même si elles sont de même type.
-    // - En cas de collocalisation (du port provide et du port uses)
-    //   il est necessaire d'effectuer une recopie du buffer car la
-    //   séquence est envoyée au port provide par une référence sur 
-    //   la séquence locale. Or la méthode put récupère le buffer directement
-    //   qui est alors le buffer utilisateur. Il pourrait alors arrivé que :
-    //     * Le recepteur efface le buffer emetteur
-    //     * Le port lui-même efface le buffer de l'ulisateur !
-    //   Cette copie est effectuée dans GenericPortUses::put 
-    //   en fonction de la collocalisation ou non.
-    // - En cas de connection multiples d'un port uses distant vers plusieurs port provides
-    //   collocalisés les ports provides partagent la même copie de la donnée ! 
-    //   Il faut effectuer une copie dans le port provides.
-    //   Cette copie est effectuée dans GenericPortUses::put 
-    //   en fonction de la collocalisation ou non.
-    Copy2CorbaSpace<IsSameType<T1,InnerType>::value >::apply(corbaData,data,bufferLength);
-    //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
-    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
-      try
-      {
-        port->put(*corbaData,t, -1); 
-      }
-      catch ( const DSC_Exception & ex) 
-      {
-        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
-      }
-      //Le -1 peut Ãªtre traité par le cst DataIdContainer et transformé en 0 
-      //Etre obligé de mettre une Ã©toile ds (*corbadata) va poser des pb pour les types <> seq
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
-#endif
-    } 
-    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
-      try
-      {
-        port->put(*corbaData,-1, i);
-      }
-      catch ( const DSC_Exception & ex) 
-      {
-        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
-      }
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
-#endif
-    } 
-
-    
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
-    for (int i = 0; i < corbaData->length(); ++i)
-      cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << endl;
+#define DEBTRACE(msg) {std::cerr<<std::flush<<__FILE__<<" ["<<__LINE__<<"] : "<<msg<<std::endl<<std::flush;}
+#else
+#define DEBTRACE(msg)
 #endif
-    
-    //    if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
-    // Supprime l'objet CORBA avec eventuellement les données qu'il contient (case de la recopie)
-    delete corbaData;
 
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
-#endif
-   
-    return;
-  }
-
-};
 
 // Interface C/C++
 
@@ -498,6 +59,7 @@ template <> struct CalTimeType<double> {
   typedef double TimeType;
 };
 
+// Définition de ecp_fin
 extern "C"  CalciumTypes::InfoType 
 ecp_fin_ (void * component, int code) {
 
@@ -510,21 +72,14 @@ ecp_fin_ (void * component, int code) {
     CalciumInterface::ecp_fin( *_component,                            
                               provideLastGivenValue); 
   } catch ( const CalciumException & ex) { //tester l'arrêt par exception
-#ifdef _DEBUG_
-    std::cerr << ex.what() << std::endl;                               
-#endif
+    DEBTRACE( ex.what() );
     return ex.getInfo();                                               
   }                                                                    
   return CalciumTypes::CPOK;
 };
 
-#ifdef _DEBUG_
-#define DEBTRACE(msg) {std::cerr<<std::flush<<__FILE__<<" ["<<__LINE__<<"] : "<<msg<<std::endl<<std::flush;}
-#else
-#define DEBTRACE(msg)
-#endif
-
 
+// Définition de ecp_lecture_... , ecp_ecriture_..., ecp_free_...
 #define CALCIUM_C2CPP_INTERFACE_(_name,_type,_qual)                    \
   extern "C" CalciumTypes::InfoType ecp_lecture_##_name (void * component, int dependencyType, \
                                                         CalTimeType< _type _qual >::TimeType * ti, \
@@ -548,9 +103,7 @@ ecp_fin_ (void * component, int code) {
                                                     nomvar,            \
                                                     _bufferLength, _nRead, *data); \
     } catch ( const CalciumException & ex) {                           \
-      DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1b ------------------" ) \
-      DEBTRACE( ex.what() )                            \
-      DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1ter ------------------" ) \
+      DEBTRACE( ex.what() );                                           \
       return ex.getInfo();                                             \
     }                                                                  \
     if ( IsSameType< _name , cplx >::value ) { *nRead=_nRead/2;                \
@@ -561,16 +114,15 @@ ecp_fin_ (void * component, int code) {
     if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) \
         *ti=(CalTimeType< _type _qual >::TimeType)(_ti);                       \
     DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) \
-    /* \
-    for (int i=0; i<_nRead;++i)                                                \
-      printf("-------- CalciumInterface(lecture Inter Part), Valeur de data (typage entier) data[%d] : %d \n",i,(*data)[i]); \
-      */ \
-    DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) \
     return CalciumTypes::CPOK;                                         \
   };                                                                   \
+                                                                       \
+                                                                       \
   extern "C" void ecp_lecture_##_name##_free ( _type _qual * data) {   \
     CalciumInterface::ecp_free< _type, _name >(data);                  \
   };                                                                   \
+                                                                       \
+                                                                       \
   extern "C" CalciumTypes::InfoType ecp_ecriture_##_name (void * component, int dependencyType, \
                                                          CalTimeType< _type _qual >::TimeType *t, \
                                                          long  i,      \
@@ -593,23 +145,102 @@ ecp_fin_ (void * component, int code) {
       std::cerr << ex.what() << std::endl;                             \
       return ex.getInfo();                                             \
     }                                                                  \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data : " ) \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Ptr(1) :" << data ) \
-    /* \
-    for (int i=0; i<_bufferLength;++i)                                 \
-      printf("-------- CalciumInterface(ecriture Inter Part), Valeur de data (typage entier) data[%d] : %d \n",i,data[i]); \
-      */ \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Ptr(2) :" << data ) \
-    return CalciumTypes::CPOK;                                         \
+    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data :" << data ) \
+      return CalciumTypes::CPOK;                                       \
   };                                                                   \
 
 
 
 #define STAR *
+// Le premier argument est utilisée :
+//  - comme suffixe dans la définition des noms ecp_lecture_ ecp_ecriture_ ecp_free_
+//  - comme second argument template Ã  l'appel de la méthode C++ correspondante
+//      ( le port correspondant est alors obtenu par un trait)
+// Le second argument est utilisée :
+// - pour typer le paramètre data de la procédure générée 
+// - pour déduire le type des paramètres t, ti tf via un trait
+// - comme premier paramètre template Ã  l'appel de la méthode C++ correspondante
 CALCIUM_C2CPP_INTERFACE_(int,int,);
 CALCIUM_C2CPP_INTERFACE_(float,float, );
 CALCIUM_C2CPP_INTERFACE_(double,double,);
 CALCIUM_C2CPP_INTERFACE_(bool,bool,);
 CALCIUM_C2CPP_INTERFACE_(cplx,float,);
+CALCIUM_C2CPP_INTERFACE_(str,char*,);
+
+// INTERFACE C/CPP pour les chaines de caractères
+// Le paramètre supplémentaire strsize n'étant pas utilisé
+// j'utilise la génération par la macro CALCIUM_C2CPP_INTERFACE_(str,char*,);
+// TODO : vérifier ecp_free pour ce type particulier
+// extern "C" CalciumTypes::InfoType ecp_lecture_str (void * component, int dependencyType, 
+//                                                float * ti, float * tf, long * i, 
+//                                                const char * const nomvar, size_t bufferLength, 
+//                                                size_t * nRead, char ** *data, size_t strsize ) { 
+
+//   Superv_Component_i * _component = static_cast<Superv_Component_i *>(component); 
+//   double         _ti=*ti;                                           
+//   double         _tf=*tf;                                           
+//   size_t         _nRead=0;                                          
+//   size_t         _bufferLength=bufferLength;                                
+//   CalciumTypes::DependencyType _dependencyType=                     
+//     static_cast<CalciumTypes::DependencyType>(dependencyType);      
+  
+//   // - GERER POINTEUR NULL : NOTHING TODO 
+//   // - VERIFIER LA TAILLE DES CHAINES RETOURNEES (ELLES DEVRAIENT ETRES CORRECTES SI L'ECRITURE EST BIEN CODEE.)
+
+//   DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1 ------------------" ) 
+//     try {                                                           
+//       CalciumInterface::ecp_lecture< char*, char* >( *_component,   
+//                                                  _dependencyType, 
+//                                                  _ti, _tf, *i,      
+//                                                  nomvar,            
+//                                                  _bufferLength, _nRead, *data); 
+//     } catch ( const CalciumException & ex) {                                
+//       DEBTRACE( ex.what() );
+//       return ex.getInfo();                                          
+//     }                                                                       
+    
+//     *nRead = _nRead;                                                
+    
+//     if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) 
+//       *ti=(float)(_ti);                     
+    
+//     DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) ;
+
+//     return CalciumTypes::CPOK;
+//   };                                                                        
+                                                                       
+
+// extern "C" void ecp_lecture_str_free (char** data) {        
+//   CalciumInterface::ecp_free< char*, char* >(data);                 
+// };                                                                  
+                                                                       
+                                                                       
+// extern "C" CalciumTypes::InfoType ecp_ecriture_str (void * component, int dependencyType, 
+//                                                 float *t, long  i,  
+//                                                 const char * const nomvar, size_t bufferLength, 
+//                                                 char ** data, int strsize ) { 
+
+//     Superv_Component_i * _component = static_cast<Superv_Component_i *>(component); 
+//     /* Je ne sais pas pourquoi, je n'arrive pas Ã  passer t par valeur : corruption de la pile*/ 
+//     double         _t=*t;                                           
+//     size_t         _bufferLength=bufferLength;                              
+
+//     // - VERIFIER LA TAILLE DES CHAINES RETOURNEES (ELLES DEVRAIENT ETRES CORRECTES SI L'ECRITURE EST BIEN CODEE.)
+
+//     DEBTRACE( "-------- CalciumInterface(ecriture Inter Part) MARK 1 ------------------" ) 
+//     try {                                                           
+//       std::string essai(nomvar);                                    
+//       DEBTRACE( "----------->-" << nomvar )         
+//     CalciumInterface::ecp_ecriture< char*, char* >( *_component,    
+//                                                     static_cast<CalciumTypes::DependencyType>(dependencyType), 
+//                                                     _t,i,nomvar,_bufferLength,*data); 
+//     } catch ( const CalciumException & ex) {                                
+//       std::cerr << ex.what() << std::endl;                          
+//       return ex.getInfo();                                          
+//     }                                                                       
+//     DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data :" << data ) 
+//     return CalciumTypes::CPOK;                                              
+//   };                                                                        
+
 
 #endif
index baacd9c77098b333d2c8ab1dfbb27663ac18d2a6..d05cc440df6e41e9689187b95eb0007b5f35a03d 100644 (file)
 
 #include "Superv_Component_i.hxx"
 
-
-struct UnknownPortType {};
+// PROVIDES PORT TRAITS
+struct UnknownProvidesPortType {};
 template <class T> struct ProvidesPortTraits {
-  typedef  UnknownPortType PortType;
+  typedef  UnknownProvidesPortType PortType;
 };
 template <> struct ProvidesPortTraits<int> {
   typedef  calcium_integer_port_provides PortType;
@@ -48,25 +48,33 @@ template <> struct ProvidesPortTraits<float> {
 template <> struct ProvidesPortTraits<double> {
   typedef  calcium_double_port_provides PortType;
 };
-template <> struct ProvidesPortTraits<char *> {
-  typedef  calcium_string_port_provides PortType;
-};
 template <> struct ProvidesPortTraits<bool> {
   typedef  calcium_logical_port_provides PortType;
 };
-
 // Définition du type cplx pour disciminer ce type de port
 // de celui du float 
 struct cplx {};
 template <> struct ProvidesPortTraits<cplx> {
    typedef calcium_complex_port_provides PortType;
 };
+// Défénition du type str pour obtenir le type de port
+// correspondant
+struct str {};
+template <> struct ProvidesPortTraits<str> {
+   typedef calcium_string_port_provides PortType;
+};
+ template <> struct ProvidesPortTraits<char *> {
+   typedef  calcium_string_port_provides PortType;
+ };
 
 template < typename T > struct StarTrait        { typedef  T NonStarType; };
 template < typename T > struct StarTrait< T * > { typedef  T NonStarType; };
 
+
+// USES PORT TRAITS
+struct UnknownUsesPortType {};
 template <class T> struct UsesPortTraits {
-  typedef  UnknownPortType PortType;
+  typedef  UnknownUsesPortType PortType;
 };
 template <> struct UsesPortTraits<int> {
   typedef  calcium_integer_port_uses PortType;
@@ -80,7 +88,7 @@ template <> struct UsesPortTraits<float> {
 template <> struct UsesPortTraits<double> {
   typedef  calcium_double_port_uses PortType;
 };
-template <> struct UsesPortTraits<char *> {
+template <> struct UsesPortTraits<str> {
   typedef  calcium_string_port_uses PortType;
 };
 template <> struct UsesPortTraits<bool> {
index 075132663b67ec791642ffef4032afd3865191f1..e22288f6a55548c14fdd5f09068ef22f31d68ce2 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef _CALCIUM_PORT_PROVIDES_HXX_
 #define _CALCIUM_PORT_PROVIDES_HXX_
 
+#include <SALOMEconfig.h>
+
 #include "Calcium_Ports.hh"
 #include "CalciumGenericProvidesPort.hxx"
 #include "CalciumCouplingPolicy.hxx"
index 5cf6d10c5433c09bdee97e244fdf507d1370c0dc..5f7dcc18b7e132415669614298dac6ef80c410c3 100644 (file)
@@ -49,11 +49,11 @@ table[CalciumTypes::UNDEFINED_DEPENDENCY ] = Ports::Calcium_Ports::UNDEFINED_DEP
 
 
 #ifdef _DEBUG_
-std::cout << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::TIME_DEPENDENCY<<"] : "<< 
+std::cerr << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::TIME_DEPENDENCY<<"] : "<< 
   table[CalciumTypes::TIME_DEPENDENCY] << std::endl;
-std::cout << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::ITERATION_DEPENDENCY<<"] : "<< 
+std::cerr << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::ITERATION_DEPENDENCY<<"] : "<< 
   table[CalciumTypes::ITERATION_DEPENDENCY] << std::endl;
-std::cout << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::UNDEFINED_DEPENDENCY<<"] : "<< 
+std::cerr << "CORBA_DEPENDENCY_TYPE() : table["<<CalciumTypes::UNDEFINED_DEPENDENCY<<"] : "<< 
   table[CalciumTypes::UNDEFINED_DEPENDENCY] << std::endl;
 #endif
 }
@@ -67,7 +67,7 @@ Ports::Calcium_Ports::DependencyType CORBA_DEPENDENCY_TYPE::operator[]( const Ca
             Ports::Calcium_Ports::DependencyType >& ) *this ;
 
 #ifdef _DEBUG_
-std::cout << "CORBA_DEPENDENCY_TYPE() : ::operator["<<c<<"]: " << table[c] << std::endl;
+std::cerr << "CORBA_DEPENDENCY_TYPE() : ::operator["<<c<<"]: " << table[c] << std::endl;
 #endif
 
   assert( table.find( (CalciumTypes::DependencyType)c ) != table.end() ) ;
index f4ea3d681f23319fc17d0bb630df525f60a68860..21f3384976bfee34204ae89de510ba312653140a 100644 (file)
@@ -76,7 +76,7 @@ Copy2CorbaSpace<false>  {
     std::cerr << "-------- Copy2CorbaSpace<false> MARK 1 --(dataPtr : " <<
       dataPtr<<")----------------" << std::endl;
 #endif
-    
+    // Attention : Pour les chaines ou tout autre object complexe il faut utiliser une recopie profonde !   
     std::copy(&data,&data+nRead,dataPtr);
  
 #ifdef _DEBUG_
index 36d18e37dd569606f69dbc81871a3210fe9d0617..be959838e898d39ea415b2388215d55704b2576d 100644 (file)
 #include <iostream>
 #include "CalciumPortTraits.hxx"
 
+#include <cstdio>
+
+//Les demandes de copies vers l'espace utilisateur
+//proviennent d'une procédure de lecture  
+
 //Cas du zero copie
 template <bool zerocopy >
 struct Copy2UserSpace{
@@ -40,66 +45,108 @@ struct Copy2UserSpace{
   template <class T1, class T2>
   static void apply( T1 * & data, T2 & corbaData, size_t nRead ){
 
+    // La ligne suivante appelle Ã  un commentaire
+    // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
     typedef typename ProvidesPortTraits<T1>::PortType PortType;
     typedef typename PortType::DataManipulator        DataManipulator;
     typedef typename DataManipulator::InnerType       InnerType;
 
     // Devient propriétaire des données contenues dans la structure CORBA
     // (allouées par allocbuff() pour une séquence)
+    // Le client est propriétaire des données.
+    // Il doit cependant Ãªtre attentif au fait que s'il les modifie,
+    // une nouvelle demande de lecture lui fournira les données modifiées.
+    // TODO : ? Si plusieurs lecteurs demandent la même donnée ? 
+    //        ? qui devient le propriétaire? --> normalement le premier car
+    //        ensuite la séquence n'est plus propriétaire.
+    //      NO: Le port devrait resté propriétaire du contenu de la séquence
+    //      NO: L'utilisateur doit de toute les façons utiliser les données reçues en
+    //      NO: lecture seulement car si une nouvelle demande de lecture est formulée
+    //      NO: pour ces données, les eventuelles modifications seraient visibles !
+    // YES : La solution de donner la propriété Ã  l'utilisateur est convenable car si
+    // le port déréférence ces données (garbage collecteur, niveau) le buffer
+    // reste disponible Ã  l'ulisateur en lecture et Ã©criture
+    // Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK)
+    // du coup quid d'une nouvelle demande de lecture : A TESTER 
     InnerType * dataPtr  = DataManipulator::getPointer(corbaData,true);
 
     // Cette ligne poserait uun problème dans la méthode appelante, si elle
     // ne testait pas que les types utilisateurs et CORBA sont identiques :
     // ex :  InnerType == Corba::Long et d'un T == int
+    // C'est l'objet de la procédure suivante
     data = dataPtr; 
 
-    // L'utilisateur a la charge de la desallocation
-    // il devra appeler la méthode ecp_free pour désallouer le contenu de la séquence CORBA
-    // La structure CORBA sera désallouer le cas Ã©chéant dans la méthode appelante
+    // En zero copie l'utilisateur doit appeler ecp_free ( cas ou un buffer intermédiaire
+    // a Ã©té alloué pour cause de typage différent xor necessité de désalouer le buffer alloué par CORBA)
+    // L'utilisateur doit cependant Ãªtre attentif au fait qu'après désallocation, si la donnée
+    // est toujours estampillée dans le port une nouvelle lecture pour cette estampille
+    // rendrait un buffer vide.
   }
 };
 
 // Cas où il faut effectuer une recopie
 template <>
-struct Copy2UserSpace<false>{
+struct Copy2UserSpace<false> {
 
-  //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur
-  //nRead
+  //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead
   template <class T1, class T2>
   static void apply( T1 * &data, T2 & corbaData, size_t nRead){
 
+    // La ligne suivante appelle Ã  un commentaire
+    // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
     typedef typename ProvidesPortTraits<T1>::PortType  PortType;
     typedef typename PortType::DataManipulator         DataManipulator;
     typedef typename DataManipulator::InnerType        InnerType;
-
-    size_t corbaDataSize = DataManipulator::size      (corbaData);
-    // Récupère un pointeur sur les données contenues dans la structure CORBA sans en devenir propriétaire
-    InnerType * dataPtr  = DataManipulator::getPointer(corbaData,false);
-
-    // Attention : Pour les chaines ou tout autre object complexe il faut utiliser une recopie profonde !
-    // Recopie des données dans le buffer allouée par l'utilisateur 
-    // OU 
-    // Recopie des données dans le buffer allouée la méthode appelante
-    // dans le cas d'une demande utilisateur 0 copie mais sur 
-    // des types utilisateurs et CORBA incompatibles.
+    
+  
 #ifdef _DEBUG_
-    std::cerr << "-------- Copy2UserSpace<false> MARK 1 --(dataPtr : " <<dataPtr<<")----------------" << std::endl;
+    InnerType * dataPtr = NULL;
+      // Affiche la valeur du pointeur de la structure corba
+      //  et les pointeurs contenus le cas Ã©chéant
+      dataPtr  = DataManipulator::getPointer(corbaData,false);
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]);
+      std::cerr << std::endl;
+
+      T1 * tmpData = data;
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1b --data("<<tmpData<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
+      std::cerr << std::endl;
 #endif
+
+      // Pour les types pointeurs et ref il faut effectuer une recopie profonde.
+      // On la délègue au manipulateur de données. 
+      
+      // Recopie des données dans le buffer allouée par l'utilisateur 
+      // OU 
+      // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture)
+      // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles.
     
-    std::copy(dataPtr,dataPtr+nRead,data);
+      //std::copy(dataPtr,dataPtr+nRead,data);
+      DataManipulator::copy(corbaData,data,nRead);
+      
 #ifdef _DEBUG_
-    std::cerr << "-------- Copy2UserSpace<false> MARK 2 --(nRead: "<<nRead<<")-------------" << std::endl;
-    std::cerr << "-------- Copy2UserSpace<false> MARK 3  --(data : " <<data<<") :";
-    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
-    std::cout << std::endl;
+      tmpData = data;
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1c --data("<<tmpData<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
+      std::cerr << std::endl;
 #endif
-
- }
+    
+  }
+  
 };
 
 
+// Désallocation des buffers si necessaire
 template <bool rel>
 struct DeleteTraits {
   template <typename T> 
@@ -110,18 +157,25 @@ struct DeleteTraits {
     //typedef typename DataManipulator::Type         DataType; // Attention != T
     
     // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-    // la donnée corba associée Ã  un DataId ! Ne pas effectuer la desallocation suivante :
+    // la donnée corba associée Ã  un DataId ! 
+    // Ne pas effectuer la desallocation suivante :
     // DataManipulator::relPointer(dataPtr);
+    // TODO : Il convient cependant de rendre la propriété du buffer Ã  la séquence CORBA
+    // TODO : PB   : On n'a plus de référence sur la séquence. 
+    // TODO : Modifier l'API ecp_free pour indiquer le dataId associé ?
+    // TODO : ??VERIF accès concurrent Ã  la séquence stockée ?? suppression simultanée ?
+
   }
 };
 
-// Cas où une recopie avait Ã©té effectuée
+// Désalocation du buffer intermédiaire 
+// dans le cas de types utilisateur/CORBA différents 
 template <>
 struct DeleteTraits<false>{
+
   template <typename T> 
-  static void apply(T * dataPtr) {
-    delete[] dataPtr;
-  }
+  static void apply(T * dataPtr) { delete[] dataPtr; }
+
 };
 
 #endif
index 7c827dbb5ff0160b235887d28957149c2e942100..8ae28c91c73dff23e582f981d394a4e2a07ed86c 100644 (file)
@@ -49,11 +49,11 @@ table[Ports::Calcium_Ports::UNDEFINED_DEPENDENCY ] = CalciumTypes::UNDEFINED_DEP
 
 
 #ifdef _DEBUG_
-std::cout << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::TIME_DEPENDENCY<<"] : "<< 
+std::cerr << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::TIME_DEPENDENCY<<"] : "<< 
   table[Ports::Calcium_Ports::TIME_DEPENDENCY] << std::endl;
-std::cout << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::ITERATION_DEPENDENCY<<"] : "<< 
+std::cerr << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::ITERATION_DEPENDENCY<<"] : "<< 
   table[Ports::Calcium_Ports::ITERATION_DEPENDENCY] << std::endl;
-std::cout << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::UNDEFINED_DEPENDENCY<<"] : "<< 
+std::cerr << "DEPENDENCY_TYPE() : table["<<Ports::Calcium_Ports::UNDEFINED_DEPENDENCY<<"] : "<< 
   table[Ports::Calcium_Ports::UNDEFINED_DEPENDENCY] << std::endl;
 #endif
 }
@@ -66,7 +66,7 @@ CalciumTypes::DependencyType DEPENDENCY_TYPE::operator[]( const Ports::Calcium_P
                                            CalciumTypes::DependencyType>&)*this ;
 
 #ifdef _DEBUG_
-std::cout << "DEPENDENCY_TYPE() : ::operator["<<c<<"]: " << table[c] << std::endl;
+std::cerr << "DEPENDENCY_TYPE() : ::operator["<<c<<"]: " << table[c] << std::endl;
 #endif
 
   assert( table.find( (Ports::Calcium_Ports::DependencyType)c ) != table.end() ) ;
index f3d3fffb436727a6a855d461ead1ac78d4776c0c..3bdabe92a62603dd47fcd6234bc5e4ba7cdfe2c7 100644 (file)
@@ -49,6 +49,7 @@ salomeinclude_HEADERS = calcium_port_factory.hxx \
                        CalciumCouplingPolicy.hxx \
                        CalciumException.hxx \
                        CalciumTypes.hxx \
+                       CalciumCxxInterface.hxx \
                        CalciumInterface.hxx \
                        Copy2UserSpace.hxx \
                        Copy2CorbaSpace.hxx \
index 6733cdbdfa625e32ca951b725abbc552b9d135da..3216a20f402317ddf46ecc94104275d863a33554 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef _CALCIUM_INTEGER_PORT_USES_HXX_
 #define _CALCIUM_INTEGER_PORT_USES_HXX_
 
+#include <SALOMEconfig.h>
+
 #include "Calcium_Ports.hh"
 #include "CalciumGenericUsesPort.hxx"
 
index a31eda3c2840f9666f1df010952adad0a0219208..557e1ed1a7ab08c136144b2b81532d7a85ac6004 100644 (file)
@@ -61,6 +61,16 @@ void F_FUNC(cplen,CPLEN)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_
   free_str1(cnom);
 }
 
+void F_FUNC(cpllo,CPLLO)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_PSTR(nom),
+            int *max,int *n, int *tab,int *err STR_PLEN(nom))
+{
+  char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPLLO: %s %f %f\n",cnom,*ti,*tf);
+  *err=cp_llo((void *)*compo,*dep,ti,tf,iter,cnom,*max,n,tab);
+  fprintf(stderr,"End of CPLLO: %s \n",cnom);
+  free_str1(cnom);
+}
+
 void F_FUNC(cpldb,CPLDB)(long *compo,int *dep,double *ti,double *tf,int *iter,STR_PSTR(nom),
             int *max,int *n, double *tab,int *err STR_PLEN(nom))
 {
@@ -81,6 +91,75 @@ void F_FUNC(cplre,CPLRE)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_
   free_str1(cnom);
 }
 
+void F_FUNC(cplcp,CPLCP)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_PSTR(nom),
+            int *max,int *n, float *tab,int *err STR_PLEN(nom))
+{
+  char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPLCP: %s %f %f \n",cnom, *ti,*tf);
+  *err=cp_lcp((void *)*compo,*dep,ti,tf,iter,cnom,*max,n,tab);
+  fprintf(stderr,"End of CPLCP: %s %f %f \n",cnom,*ti,*tf);
+  free_str1(cnom);
+}
+
+void F_FUNC(cplch,CPLCH)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_PSTR(nom),
+            int *max,int *n, char *tab,int *err STR_PLEN(nom) STR_PLEN(tab) )
+{
+  char **tabChaine=NULL;
+  int    index=0;
+  char*  cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPLCH: %s %f %f \n",cnom, *ti,*tf);
+
+  tabChaine = (char **) malloc(sizeof(char *) * (*max));
+  for (index = 0; index < *max; index++)
+    tabChaine[index] = (char *) malloc(sizeof(char) * (STR_LEN(tab)+1));
+
+  *err=cp_lch((void *)*compo,*dep,ti,tf,iter,cnom,*max,n,tabChaine,STR_LEN(tab));
+
+  for (index = 0; index < *n; index++)
+    strcpy(&tab[index * STR_LEN(tab)], tabChaine[index]);
+
+  fprintf(stderr,"End of CPLCH: %s %f %f \n",cnom,*ti,*tf);
+  if (tabChaine != (char **) NULL)  {
+    for (index = 0; index < *n; index++)
+      free(tabChaine[index]);
+    free(tabChaine);
+  }
+  free_str1(cnom);
+}
+
+void F_FUNC(cpech,CPECH)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),int *n, char *tab,int *err 
+                        STR_PLEN(nom) STR_PLEN(tab))
+{
+  char ** tabChaine=NULL;
+  int     index=0,index2=0;
+  char*   cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPECH: %s %f \n",cnom, *ti);
+
+  tabChaine = (char **) malloc(sizeof(char *) * *n);
+  for (index = 0; index < *n; index++) {
+    
+    tabChaine[index] = (char *) malloc(sizeof(char) * (STR_LEN(tab) + 1));
+    strncpy(tabChaine[index],&tab[STR_LEN(tab) * index],STR_LEN(tab));
+    tabChaine[index][STR_LEN(tab)]='\0';
+    for (index2 = STR_LEN(tab) - 1; index2 >= 0; index2--) {
+      if ( tabChaine[index][index2] == ' '  ||
+          tabChaine[index][index2] == '\0'   )
+       tabChaine[index][index2]='\0';
+    }
+  }
+
+  *err=cp_ech((void *)*compo,*dep,*ti,*iter,cnom,*n,tabChaine,STR_LEN(tab) );
+
+  fprintf(stderr,"End of CPECH: %s %f \n",cnom, *ti);
+  if (tabChaine != (char **) NULL) {
+    for (index = 0; index < *n; index++)
+      free(tabChaine[index]);
+
+    free(tabChaine);
+  }
+  free_str1(cnom);
+}
+
 void F_FUNC(cpedb,CPEDB)(long *compo,int *dep,double *ti,int *iter,STR_PSTR(nom),int *n, double *tab,int *err STR_PLEN(nom))
 {
   char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
@@ -99,6 +178,15 @@ void F_FUNC(cpere,CPERE)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),
   free_str1(cnom);
 }
 
+void F_FUNC(cpecp,CPECP)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),int *n, float *tab,int *err STR_PLEN(nom))
+{
+  char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPECP: %s %f \n",cnom, *ti);
+  *err=cp_ecp((void *)*compo,*dep,*ti,*iter,cnom,*n,tab);
+  fprintf(stderr,"End of CPECP: %s %f \n",cnom, *ti);
+  free_str1(cnom);
+}
+
 void F_FUNC(cpeen,CPEEN)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),int *n, int *tab,int *err STR_PLEN(nom))
 {
   char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
@@ -108,6 +196,15 @@ void F_FUNC(cpeen,CPEEN)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),
   free_str1(cnom);
 }
 
+void F_FUNC(cpelo,CPELO)(long *compo,int *dep,float *ti,int *iter,STR_PSTR(nom),int *n, int *tab,int *err STR_PLEN(nom))
+{
+  char* cnom=fstr1(STR_PTR(nom),STR_LEN(nom));
+  fprintf(stderr,"CPELO: %s %f %d\n",cnom, *ti,*iter);
+  *err=cp_elo((void *)*compo,*dep,*ti,*iter,cnom,*n,tab);
+  fprintf(stderr,"End of CPELO: %s %f \n",cnom,*ti);
+  free_str1(cnom);
+}
+
 void F_FUNC(cpfin,CPFIN)(long *compo,int *dep,int *err)
 {
   fprintf(stderr,"CPFIN: \n");
index a60cf98b3203133dd99a00a3ab0d896da689b44a..c0adc185397e39b60d25301b15c74ebb2c1e4ec6 100644 (file)
 // Date        : $LastChangedDate: 2007-02-07 18:26:44 +0100 (mer, 07 fév 2007) $
 // Id          : $Id$
 
-#ifndef _TYPE_MANIPULATION_HXX_
-#define _TYPE_MANIPULATION_HXX_
+#ifndef _CORBA_TYPE_MANIPULATION_HXX_
+#define _CORBA_TYPE_MANIPULATION_HXX_
 
 #include <iostream>
+#include <cstring>
 #include <CORBA.h>
 
-using namespace std;
 
 // Classes manipulation
 // -------------------
@@ -48,10 +48,10 @@ using namespace std;
 // - delete_data
 // - dump
 // et
-// deux type :
-// - Type   : Le type CORBA de la donnée manipulée
-// - InType : Le mapping CORBA pour un paramètre IN du type manipulé
+// trois types :
+// - Type      : Le type CORBA de la donnée manipulée
+// - InType    : Le mapping CORBA pour un paramètre IN du type manipulé
+// - InnerType : Type interne des valeurs d'un type contenant 
 
 // Cette classe permet de manipuler des types CORBA 
 // any, struct, union et sequence (utiliser plutôt les seq_manipulator)
@@ -185,7 +185,7 @@ public:
 
   // Dump de l'objet pour deboguage : Affiche la donnee
   static void inline dump (CorbaInType data) {
-    cerr << "[atom_manipulation] Data : " << data << endl;
+    std::cerr << "[atom_manipulation] Data : " << data << std::endl;
   }
 };
 
@@ -196,11 +196,10 @@ template <typename seq_T,typename elem_T>
 class seq_u_manipulation {
   
 public:
-  typedef seq_T * Type;
-  // correspond au mapping corba de la séquence en paramètre IN
-  typedef const seq_T & CorbaInType; 
-  typedef elem_T  InnerType;
-
+  typedef seq_T *       Type;        // Type de donnée abstrait manipulé par GenericPort::Put,Get,..
+  typedef const seq_T & CorbaInType; // Mapping corba de la séquence en paramètre IN
+  typedef elem_T        InnerType;   // Il n'existe pas dans CORBA de seq_T::elem_T
+                                     // C'est la raison d'être du second paramètre template de seq_u_mani
  
   // Operation de recuperation des donnees venant de l'ORB
   // Remarque : On a un paramètre d'entrée de type const seq_T &
@@ -209,23 +208,40 @@ public:
     CORBA::Long len = data.length();
     CORBA::Long max = data.maximum();
     // Récupère et devient propriétaire des données reçues dans la séquence. 
-    // La séquence sera désalloué (mais pas le buffer) au retour 
-    // de la méthode put (car mapping de type IN : const seq & )
-    // ATTENTION TESTER p184 si le pointeur est null
-    // ATTENTION TESTER Si le flag release si la sequence contient des chaines
-    // ou des object refs
+    // La séquence (mais pas le buffer) sera désallouée au retour 
+    // de la méthode GenericPort::put (car le mapping CORBA de ce type IN est : const seq & )
+
+    // OLD : On ne teste pas si le flag release de la séquence est Ã  true ou false 
+    // OLD : ( pour des séquences de chaines ou d'objrefs )
+    // OLD :   -> Si on est collocalisé le port uses doit créer une copie pour Ã©viter la modification
+    // OLD : du contenu de la séquence lorsque l'utilisateur modifie ses données dans son programme (0 copie)
+
+    // Le flag release() de la séquence est Ã  false si elle n'est pas propriétaire du buffer
+    // En  collocalité c'est le cas (on Ã©vite ici la copie réalisée auparavant dans le port uses).
+
+    // ATTENTION TESTER p194 si le pointeur est null (release flag==false)
+    //    -> La séquence n'était pas propriétaire des données !
 #ifdef _DEBUG_
     std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl;
 #endif
-    InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true); 
+    if ( data.release() ) {
+      InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+
+    // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
+    // Les données de la séquence seront automatiquement désallouées par appel Ã  la méthode freebuf
+    // dans le destructeur de la séquence (cf  delete_data).
 #ifdef _DEBUG_
-    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 2 ------"<<  p_data <<"------------" << std::endl;
+      std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(0 copy) bis ------"<<  p_data <<"------------" << std::endl;
 #endif
+    
+      return  new seq_T (max, len, p_data, true);
+    }
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(recopie) bis ------"<<  &data <<"------------" << std::endl;
+#endif
+    // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)    
+    return new seq_T(data);
 
-    // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
-    // Les données seront automatiquement désallouées par appel interne Ã  la méthode freebuf
-    // lors de la destruction de l'objet par appel Ã  delete_data.
-    return  new seq_T (max, len, p_data, true);
   }
 
   static inline size_t size(Type data) { 
@@ -234,6 +250,9 @@ public:
 
   // Operation de destruction d'une donnee
   static inline void delete_data(Type data) {
+    //La séquence est détruite par appel Ã  son destructeur
+    //Ce destructeur prend en compte la nécessité de détruire ou non
+    //les données contenues en fonction de son flag interne release()
     delete data;
   }
 
@@ -246,9 +265,9 @@ public:
     return new seq_T (data);
   }
 
-  // Permet de désallouer le buffer dont on détient le pointeur par appel
-  // Ã  la méthode getPointer avec ownerShip=True si la séquence contenante
-  // Ã  Ã©té détruite.
+  // Permet d'obtenir un pointeur sur le buffer de la séquence
+  // si ownerShip=True, la séquence n'est plus propriétaire du buffer et est
+  // détruite (mais pas le buffer !)
   static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
     InnerType * p_data;
     if (ownerShip) {
@@ -266,12 +285,12 @@ public:
     seq_T::freebuf(dataPtr);
   }
 
-  // Permet d'allouer un buffer pour la séquence
+  // Permet d'allouer un buffer compatible avec le type séquence
   static inline InnerType *  allocPointer(size_t size ) {
     return seq_T::allocbuf(size);
   }
 
-  // Operation de création du type corba soit
+  // Operation de création de la séquence corba soit
   // - Vide et de taille size
   // - Utilisant les données du pointeur *data de taille size 
   // (généralement pas de recopie qlq soit l'ownership )
@@ -287,17 +306,54 @@ public:
     }
     return tmp;
   } 
+
+  // Copie le contenu de la séquence dans le buffer idata de taille isize
+  // pour les types non pointeur
+  template <typename T >
+  static inline void copy( Type data, T * const idata, size_t isize ) { 
+    
+    InnerType *dataPtr  = getPointer(data,false);
+
+    for (int i = 0; i< isize; ++i) 
+      idata[i]=dataPtr[i];
+
+    // Ce mode de recopie ne permet pas  la conversion de type (ex int -> CORBA::Long
+    //OLD:     Type tmp = new seq_T(isize,isize,idata,false); 
+    //OLD:     // giveOwnerShip == false -> seul le contenu du buffer data est détruit et remplacé
+    //OLD:     // par celui de data dans l'affectation suivante :
+    //OLD:     //       ---> ATTENTION SI LA TAILLE DU BUFFER EST TROP PETITE, QUE FAIT CORBA !
+    //OLD:     //              corruption mémoire
+    //OLD:     // Cependant ce cas devrait pas arrivé (on s'assure dans les couches supérieures
+    //OLD:     //  de la taille correcte du buffer de recopie)
+    //OLD:     // Si giveOwnerShip Ã©tait == true -> le buffer et son contenu serait détruit puis une 
+    //OLD:     // allocation de la taille du buffer de data serait effectué avant la copie des données  
+    //OLD:     // tmp = data;
+  } 
+
+  // Copie le contenu de la séquence de char* dans le buffer idata de taille isize
+  static inline void copy( Type data, char* * const idata, size_t isize ) { 
+
+    char* *dataPtr  = getPointer(data,false);
+
+    // Si idata[i] n'a pas Ã©té alloué suffisament grand,
+    // il y a corruption de la mémoire
+    for (int i = 0; i< isize; ++i) 
+      strcpy(idata[i],dataPtr[i]);
+  }
   
   // Dump de l'objet pour deboguage
   static void inline dump (CorbaInType data) {
     // Affiche la longueur des donnees
-    cerr << "[seq_u_manipulation] Data length: " << data.length() << endl;
+    std::cerr << "[seq_u_manipulation] Data length: " << data.length() << std::endl;
     // Affiche la longueur des donnees
-    cerr << "[seq_u_manipulation] Data max: " << data.maximum() << endl;
+    std::cerr << "[seq_u_manipulation] Data max: " << data.maximum() << std::endl;
   }
 };
 
 
+// TODO : Vérifier la conformité de l'implémentation par rapport
+//        au type unbounded
+
 // Gére un type sequence de taille limitée (bounded)
 // Ces types sont manipulés par pointeur
 // Cette classe diffère de la seq_u_manipulation
@@ -322,11 +378,23 @@ public:
     // Récupère et devient propriétaire des données reçues dans la séquence 
     // la séquence sera désalloué (mais pas le buffer)
     // au retour de la méthode put (car mapping de type IN : const seq & )
-    InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+     if ( data.release() ) {
+       InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+
     // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie)
     // Les données seront automatiquement désallouées par appel interne Ã  la méthode freebuf
     // lors de la destruction de l'objet par appel Ã  delete_data.
-    return new seq_T (len, p_data, true);
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Pas de Duplication  -----------" << std::endl;
+#endif
+       return new seq_T (len, p_data, true);
+     }
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Duplication pour en devenir propriétaire -----------" << std::endl;
+#endif
+    // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)    
+    return new seq_T(data);
+
   }
 
   static inline size_t size(Type data) { 
@@ -393,7 +461,7 @@ public:
   // Dump de l'objet pour deboguage
   static inline void dump (CorbaInType data) {
     // Affiche la longueur des donnees
-    cerr << "[seq_b_manipulation] Data length: " << data.length() << endl;
+    std::cerr << "[seq_b_manipulation] Data length: " << data.length() << std::endl;
   }
 };
 
index 0ef2b6c10734e4d2e66f8afebfc8184cf4e60317..2ed03762cb5a493d0b831366b43dc7a89ffc57a6 100644 (file)
@@ -93,7 +93,7 @@ public:
   // Elle profite Ã  tous les modes de couplages n'implémentant pas
   // de comportement particulier dans la méthode get pour 
   // le cas d'une demande de dataId inexistant mais encadré par deux autres
-  template <typename DataManipulator>
+  template <typename DataManipulator, class EnableIf = void >
   struct BoundedDataIdProcessor{
     BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
     template < typename Iterator, typename DataId > 
index 6148b8f8f60d75b6794a07035516b9dc11779be4..dd6005780010e26042d65d9b89b018d79d6c1e67 100644 (file)
@@ -103,10 +103,12 @@ GenericPort<DataManipulator, COUPLING_POLICY >::GenericPort() :
 template < typename DataManipulator, typename COUPLING_POLICY>
 GenericPort<DataManipulator, COUPLING_POLICY>::~GenericPort() {
   typename DataTable::iterator it;
-  //   for (it=storedDatas.begin(); it!=storedDatas.end(); ++it) {
-  //     std::cout << "~GenericPort() : destruction de la donnnée associée au DataId :"<<  (*it).first << std::endl;
-  //     DataManipulator::delete_data( (*it).second );
-  //   }
+  for (it=storedDatas.begin(); it!=storedDatas.end(); ++it) {
+#ifdef _DEBUG_
+    std::cerr << "~GenericPort() : destruction de la donnnée associée au DataId :"<<  (*it).first << std::endl;
+#endif
+    DataManipulator::delete_data( (*it).second );
+  }
 }
 
 template < typename DataManipulator, typename COUPLING_POLICY> void 
@@ -150,7 +152,7 @@ void GenericPort<DataManipulator, COUPLING_POLICY>::put(CorbaInDataType dataPara
   try {
 #ifdef _DEBUG_
     // Affichage des donnees pour DEBUGging
-    cerr << "parametres emis: " << time << ", " << tag << endl;
+    std::cerr << "parametres emis: " << time << ", " << tag << std::endl;
     DataManipulator::dump(dataParam);
 #endif
   
@@ -428,21 +430,22 @@ GenericPort<DataManipulator, COUPLING_POLICY>::get(TimeType time,
        // Cependant  comme les données sont censées Ãªtre produites
        // par ordre croissant de DataId, de nouvelles données ne devrait pas améliorer
        // l'interpolation.
-       // Les données calciulées sont donc  stockées dans storedDatas. 
-       // La propriété des données N'EST PAS transférée Ã  l'utilisateur en mode CALCIUM.
 #ifdef _DEBUG_
        std::cout << "-------- Get : MARK 8 ------------------" << std::endl;
 #endif
 
-       typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
+       typedef typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> BDI;
+       BDI processBoundedDataId(*this);
+       //      typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
        //si static BDIP::apply(dataToTransmit,expectedDataId,wDataIt1);
        //ancienne version template processBoundedDataId<DataManipulator>(dataToTransmit,expectedDataId,wDataIt1);
        //BDIP processBoundedDataId;
        processBoundedDataId.apply(dataToTransmit,expectedDataId,wDataIt1);
   
        // Il ne peut pas y avoir déjà une clé expectedDataId dans storedDatas (utilisation de la notation [] )
+       // La nouvelle donnée produite est stockée, ce n'était pas le cas dans CALCIUM
        // Cette opération n'a peut Ãªtre pas un caractère générique.
-       // A déplacer en paramètre de la méthode précédente ?
+       // A déplacer en paramètre de la méthode précédente ? ou déléguer ce choix au mode de couplage ?
        storedDatas[expectedDataId]=dataToTransmit;
 
 #ifdef _DEBUG_
index f6f0ce9128cf8bc981aa7d87c4e2cc638c72fbb2..effed2b0725255ec4de0eb3be6be6fd7986bdaf3 100644 (file)
@@ -72,7 +72,10 @@ GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::Gen
 }
 
 template <typename DataManipulator,typename CorbaPortType, char * repositoryName, typename UsesPort > 
-GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::~GenericUsesPort() {}
+GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::~GenericUsesPort() 
+{
+  delete _my_ports;
+}
 
 template <typename DataManipulator,typename CorbaPortType, char * repositoryName, typename UsesPort > 
 const char *
@@ -85,37 +88,34 @@ template <typename DataManipulator,typename CorbaPortType, char * repositoryName
 template <typename TimeType,typename TagType>
 void
 GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::put( CorbaInDataType data, 
-                                                                      TimeType time, 
-                                                                      TagType tag) {
-  typedef typename CorbaPortType::_ptr_type CorbaPortTypePtr;
+                                                                                 TimeType time, 
+                                                                                 TagType tag) {
+  typedef typename CorbaPortType::_var_type CorbaPortTypeVar;
   if (!_my_ports)
     throw DSC_Exception(LOC("There is no connected provides port to communicate with."));
 
-  // PB1 : Cf remarque dans CalciumInterface, si on n'effectue pas de copie
-  //       du buffer ! 
-  // PB2 : Si les ports provides auquels on envoie data sont collocalisés
-  // ils vont partagés le même buffer (à cause de notre optim ds get_data)
-  // il faut alors effectuer une copie ici.
-  // Pour l'instant on résoud PB2 en créant une copie de la donnée en cas
-  // de connexions multiples. Il faudra tester la collocalisation.
-  DataType copyOfData; // = data; PB1
+  // OLD : PB1 : Cf remarque dans CalciumInterface, si on n'effectue pas de copie
+  // OLD :       du buffer ! 
+  // OLD : PB2 : Si les ports provides auquels on envoie data sont collocalisés
+  // OLD : ils vont partagés le même buffer (à cause de notre optim ds get_data)
+  // OLD : il faut alors effectuer une copie ici.
+  // OLD : Pour l'instant on résoud PB2 en créant une copie de la donnée en cas
+  // OLD : de connexions multiples. Il faudra tester la collocalisation.
+  // OLD :  DataType copyOfData; // = data; PB1
   for(int i = 0; i < _my_ports->length(); i++) {
 
-    CorbaPortTypePtr port = CorbaPortType::_narrow((*_my_ports)[i]);
+    CorbaPortTypeVar port = CorbaPortType::_narrow((*_my_ports)[i]);
     //if (i) { PB1
-    copyOfData = DataManipulator::clone(data);
+    //OLD :   copyOfData = DataManipulator::clone(data);
 #ifdef _DEBUG_
-    std::cout << "-------- GenericUsesPort::put : Copie de data("
-      //<< DataManipulator::getPointer(data)
-             <<") vers copyOfData ("
-             <<DataManipulator::getPointer(copyOfData)
-             <<")------------------" << std::endl;
+    std::cout << "-------- GenericUsesPort::put -------- " << std::endl;
 #endif
     //} PB1
     try {
-      port->put(*copyOfData,time,tag); // catcher les exceptions
-    }   catch(const CORBA::SystemException& ex){
-      DataManipulator::delete_data(copyOfData);
+      port->put(data,time,tag);
+      // OLD : port->put(*copyOfData,time,tag);
+    } catch(const CORBA::SystemException& ex) {
+      //OLD : DataManipulator::delete_data(copyOfData);
       throw DSC_Exception(LOC(OSS() << "Impossible d'invoquer la méthode put sur le port n°"
                              << i << "( i>=  0)"));
 
@@ -124,8 +124,8 @@ GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::put
     // La séquence est détruite avec le buffer si on n'est pas collocalisé
     // La séquence est détruite sans son buffer sinon (cf comportement de get_data
     // appelée dans put (port provides)
-    DataManipulator::delete_data(copyOfData);
-    }
+    //OLD : DataManipulator::delete_data(copyOfData);
+  }
 }
 
 
@@ -138,9 +138,9 @@ GenericUsesPort< DataManipulator, CorbaPortType, repositoryName, UsesPort
   if (_my_ports) delete _my_ports;
 
 #ifdef _DEBUG_
-  std::cerr << "GenericUsesPort::uses_port_changed" << endl;
+  std::cerr << "GenericUsesPort::uses_port_changed" << std::endl;
 #endif
-  _my_ports = new Engines::DSC::uses_port(*new_uses_port);
+  _my_ports = new_uses_port;
 }
 
 #endif
index 30cdf27d73f6bb6fa174fcb570890e995673b17b..c5f57fff49ed5275ac27837bb08b92e90f174a94 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef _PALM_COUPLING_POLICIES_HXX_
 #define _PALM_COUPLING_POLICIES_HXX_
 
+#include <SALOMEconfig.h>
+
 #include <CORBA.h>
 #include <vector>
 #include "DataIdFilter.hxx"
index e94cad7c828c3cb29208b263b498fe8d4a4d6c57..3f2a3e972a17535254fcd1348a66cdc537269938 100644 (file)
@@ -44,7 +44,7 @@ Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb,
   Engines_DSC_i(orb, poa, contId, instanceName, interfaceName) 
 {
 #ifdef _DEBUG_
-  std::cout << "--Superv_Component_i : MARK 1 ----  " << instanceName << "----" << std::endl;
+  std::cerr << "--Superv_Component_i : MARK 1 ----  " << instanceName << "----" << std::endl;
 #endif
   register_factory("BASIC", new basic_port_factory());
   register_factory("PALM", new palm_port_factory());
@@ -60,6 +60,11 @@ Superv_Component_i::~Superv_Component_i()
   {
     delete begin->second;
   }
+
+  my_superv_ports_it = my_superv_ports.begin();
+  for(;my_superv_ports_it != my_superv_ports.end();my_superv_ports_it++) 
+    delete my_superv_ports_it->second;
+
 }
 
 void 
@@ -155,11 +160,11 @@ Superv_Component_i::add_port(const char * port_fab_type,
   }
   else if (s_port_type == "uses") {
 #ifdef _DEBUG_
-    std::cout << "---- Superv_Component_i::add_port : MARK 1 ---- "  << std::endl;
+    std::cerr << "---- Superv_Component_i::add_port : MARK 1 ---- "  << std::endl;
 #endif
     uses_port * port = create_uses_data_port(port_fab_type);
 #ifdef _DEBUG_
-    std::cout << "---- Superv_Component_i::add_port : MARK 2 ---- "  << std::endl;
+    std::cerr << "---- Superv_Component_i::add_port : MARK 2 ---- "  << std::endl;
 #endif
     add_port(port, port_name);
   }
@@ -179,9 +184,11 @@ Superv_Component_i::add_port(provides_port * port,
 
   try {
 
-    Engines_DSC_interface::add_provides_port(port->get_port_ref(), 
+    Ports::PortProperties_var portproperties=port->get_port_properties();
+    Ports::Port_var portref=port->get_port_ref();
+    Engines_DSC_interface::add_provides_port(portref, 
                                             provides_port_name,
-                                            port->get_port_properties());
+                                            portproperties);
 
     superv_port_t * new_superv_port = new superv_port_t();
     new_superv_port->p_ref = port;
@@ -209,9 +216,10 @@ Superv_Component_i::add_port(uses_port * port,
   assert(uses_port_name);
 
   try {
+    Ports::PortProperties_var portproperties=port->get_port_properties();
     Engines_DSC_interface::add_uses_port(port->get_repository_id(), 
                                         uses_port_name,
-                                        port->get_port_properties());
+                                        portproperties);
     superv_port_t * new_superv_port = new superv_port_t();
     new_superv_port->u_ref = port;
     my_superv_ports[uses_port_name] = new_superv_port;
@@ -236,7 +244,7 @@ Superv_Component_i::get_port(provides_port *& port,
   assert(provides_port_name);
 
   try {
-    Engines_DSC_interface::get_provides_port(provides_port_name, false);
+    Ports::Port_var portref=Engines_DSC_interface::get_provides_port(provides_port_name, false);
     port = my_superv_ports[provides_port_name]->p_ref;
   } catch (const Engines::DSC::PortNotDefined&) {
     throw PortNotDefined( LOC(OSS()<< "Le port provides  "
@@ -255,7 +263,8 @@ Superv_Component_i::get_port(uses_port *& port,
   assert(uses_port_name);
 
   try {
-    Engines_DSC_i::get_uses_port(uses_port_name);
+    Engines::DSC::uses_port * portseq=Engines_DSC_i::get_uses_port(uses_port_name);
+    delete portseq;
     port = my_superv_ports[uses_port_name]->u_ref;
   } catch (const Engines::DSC::PortNotDefined&) {    
     throw PortNotDefined( LOC(OSS()<< "Le port uses  "
@@ -286,8 +295,10 @@ Superv_Component_i::uses_port_changed(const char* uses_port_name,
 {
   my_superv_ports_it = my_superv_ports.find(uses_port_name);
   if (my_superv_ports_it !=  my_superv_ports.end())
-    my_superv_ports[uses_port_name]->u_ref->uses_port_changed(new_uses_port,
+    my_superv_ports[uses_port_name]->u_ref->uses_port_changed(new Engines::DSC::uses_port(*new_uses_port),
                                                              message);
+  //delete the copy made by the caller
+  delete new_uses_port;
 }
 
 
index 4bac01fc3f8c942e7e0a639008a70dab7a3c6c72..174380f050558a247ac3e5eea60a0586e16f4a61 100644 (file)
@@ -32,7 +32,7 @@
 #include "provides_port.hxx"
 #include "port_factory.hxx"
 
-// default ports factories on the Kernel
+// default ports factories in the Kernel
 #include "basic_port_factory.hxx"
 #include "palm_port_factory.hxx"
 #include "calcium_port_factory.hxx"
@@ -263,6 +263,11 @@ private:
   // A Superv_Component port.
   struct superv_port_t {
     superv_port_t():u_ref(NULL),p_ref(NULL){};
+    ~superv_port_t()
+    {
+      if(u_ref)delete u_ref;
+      if(p_ref)delete p_ref;
+    };
     // For uses ports.
     uses_port * u_ref;
     // For provides ports.
@@ -346,11 +351,12 @@ Superv_Component_i::get_port( const char * port_name)
   try {
     if ( superv_port->p_ref != NULL ) {
       port = superv_port->p_ref;
-      Engines_DSC_interface::get_provides_port(port_name, false); 
+      Ports::Port_var portref=Engines_DSC_interface::get_provides_port(port_name, false); 
     } 
     else if ( superv_port->u_ref != NULL ) {
       port = superv_port->u_ref;
-      Engines_DSC_i::get_uses_port(port_name);
+      Engines::DSC::uses_port * portseq=Engines_DSC_i::get_uses_port(port_name);
+      delete portseq;
     } else {
       throw UnexpectedState( LOC(OSS()<< "Internal Error superv_port struct is inconsistent "));
     
index 4e0241f38e39e9fbe39484e36ad335ebe2d41e9f..37def271e53710ab0efe5a6d419607fdc690abeb 100644 (file)
@@ -70,20 +70,19 @@ namespace BatchLight {
     int id;
 
     // temporary directory on cluster to put input files for job
-    setDirForTmpFiles();
-    SCRUTE(_dirForTmpFiles);
+    setDirForTmpFiles(job);
 
     // export input files on cluster
-    exportInputFiles(job->getFileToExecute(),job->getFilesToExportList());
+    exportInputFiles(job);
 
     // build salome coupling script for job
-    buildSalomeCouplingScript(job->getFileToExecute());
+    buildSalomeCouplingScript(job);
 
     // build batch script for job
-    buildSalomeBatchScript(job->getNbProc());
+    buildSalomeBatchScript(job);
 
     // submit job on cluster
-    id = submit();
+    id = submit(job);
 
     // register job on map
     _jobmap[id] = job;
@@ -91,77 +90,93 @@ namespace BatchLight {
     return id;
   }
 
-  void BatchManager::setDirForTmpFiles()
+  void BatchManager::setDirForTmpFiles(BatchLight::Job* job)
   {
-    int i;
+    std::string dirForTmpFiles;
+    std::string thedate;
 
-    _dirForTmpFiles = string("Batch/");
-    Batch::Date date = Batch::Date(time(0)) ;
-    std::string thedate = date.str() ;
+    // Adding date to the directory name
+    Batch::Date date = Batch::Date(time(0));
+    thedate = date.str();
     int lend = thedate.size() ;
-    i = 0 ;
+    int i = 0 ;
     while ( i < lend ) {
       if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
         thedate[i] = '_' ;
       }
       i++ ;
     }
-    _dirForTmpFiles += thedate ;
+
+    dirForTmpFiles += string("Batch/");
+    dirForTmpFiles += thedate ;
+    job->setDirForTmpFiles(dirForTmpFiles);
   }
 
-  void BatchManager::exportInputFiles(const char *fileToExecute, const Engines::FilesList filesToExportList) throw(SALOME_Exception)
+  void BatchManager::exportInputFiles(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager::exportInFiles");
-    string command = _params.protocol;
     int status;
+    const char * fileToExecute = job->getFileToExecute();
+    const Engines::FilesList filesToExportList = job->getFilesToExportList();
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    std::string command;
+    std::string copy_command;
 
+    // Test protocol
+    if( _params.protocol == "rsh" )
+      copy_command = "rcp ";
+    else if( _params.protocol == "ssh" )
+      copy_command = "scp ";
+    else
+      throw SALOME_Exception("Unknown protocol : only rsh and ssh are known !");
+    
+    // First step : creating batch tmp files directory
+    command = _params.protocol;
     command += " ";
-
     if (_params.username != ""){
       command += _params.username;
       command += "@";
     }
-
     command += _params.hostname;
     command += " \"mkdir -p ";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles;
     command += "\"" ;
     SCRUTE(command.c_str());
     status = system(command.c_str());
-    if(status)
-      throw SALOME_Exception("Error of connection on remote host");    
-
-    if( _params.protocol == "rsh" )
-      command = "rcp ";
-    else if( _params.protocol == "ssh" )
-      command = "scp ";
-    else
-      throw SALOME_Exception("Unknown protocol");
+    if(status) {
+      std::ostringstream oss;
+      oss << status;
+      std::string ex_mess("Error of connection on remote host ! status = ");
+      ex_mess += oss.str();
+      throw SALOME_Exception(ex_mess.c_str());
+    }
 
+    // Second step : copy fileToExecute into
+    // batch tmp files directory
+    command = copy_command;
     command += fileToExecute;
     command += " ";
-
     if (_params.username != ""){
       command += _params.username;
       command += "@";
     }
-
     command += _params.hostname;
     command += ":";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles;
     SCRUTE(command.c_str());
     status = system(command.c_str());
-    if(status)
-      throw SALOME_Exception("Error of connection on remote host");    
+    if(status) {
+      std::ostringstream oss;
+      oss << status;
+      std::string ex_mess("Error of connection on remote host ! status = ");
+      ex_mess += oss.str();
+      throw SALOME_Exception(ex_mess.c_str());
+    }
     
-    int i ;
-    for ( i = 0 ; i < filesToExportList.length() ; i++ ) {
-      if( _params.protocol == "rsh" )
-       command = "rcp ";
-      else if( _params.protocol == "ssh" )
-       command = "scp ";
-      else
-       throw SALOME_Exception("Unknown protocol");
+    // Third step : copy filesToExportList into
+    // batch tmp files directory
+    for (int i = 0 ; i < filesToExportList.length() ; i++ ) {
+      command = copy_command;
       command += filesToExportList[i] ;
       command += " ";
       if (_params.username != ""){
@@ -170,11 +185,16 @@ namespace BatchLight {
       }
       command += _params.hostname;
       command += ":";
-      command += _dirForTmpFiles ;
+      command += dirForTmpFiles ;
       SCRUTE(command.c_str());
       status = system(command.c_str());
-      if(status)
-       throw SALOME_Exception("Error of connection on remote host");    
+      if(status) {
+       std::ostringstream oss;
+       oss << status;
+       std::string ex_mess("Error of connection on remote host ! status = ");
+       ex_mess += oss.str();
+       throw SALOME_Exception(ex_mess.c_str());
+      }
     }
 
     END_OF("BatchManager::exportInFiles");
@@ -207,8 +227,16 @@ namespace BatchLight {
       command += directory;
       SCRUTE(command.c_str());
       status = system(command.c_str());
-      if(status)
-       throw SALOME_Exception("Error of connection on remote host");    
+      if(status) 
+      {
+       // Try to get what we can (logs files)
+       // throw SALOME_Exception("Error of connection on remote host");    
+       std::string mess("Copy command failed ! status is :");
+       ostringstream status_str;
+       status_str << status;
+       mess += status_str.str();
+       INFOS(mess);
+      }
     }
 
     END_OF("BatchManager::importOutputFiles");
@@ -221,10 +249,8 @@ namespace BatchLight {
     strcpy(temp, "/tmp/command");
     strcat(temp, "XXXXXX");
 #ifndef WNT
-
     mkstemp(temp);
 #else
-
     char aPID[80];
     itoa(getpid(), aPID, 10);
     strcat(temp, aPID);
@@ -236,18 +262,16 @@ namespace BatchLight {
     return command;
   }
 
-  void BatchManager::RmTmpFile()
+  void BatchManager::RmTmpFile(std::string & TemporaryFileName)
   {
-    if (_TmpFileName != ""){
-      string command = "rm ";
-      command += _TmpFileName;
-      char *temp = strdup(command.c_str());
-      int lgthTemp = strlen(temp);
-      temp[lgthTemp - 3] = '*';
-      temp[lgthTemp - 2] = '\0';
-      system(temp);
-      free(temp);
-    }
+    string command = "rm ";
+    command += TemporaryFileName;
+    char *temp = strdup(command.c_str());
+    int lgthTemp = strlen(temp);
+    temp[lgthTemp - 3] = '*';
+    temp[lgthTemp - 2] = '\0';
+    system(temp);
+    free(temp);
   }
 
   MpiImpl *BatchManager::FactoryMpiImpl(string mpiImpl) throw(SALOME_Exception)
index a8ea0061a4f4ee2cedfdb0d9a54db153796eb4c7..7183c1d1bb8f6e7cfe94352050d86890ddf4d9af 100644 (file)
@@ -69,22 +69,17 @@ namespace BatchLight {
   protected:
     batchParams _params;
     MpiImpl *_mpiImpl;
-
     std::map <int,const BatchLight::Job *> _jobmap;
-    std::string _dirForTmpFiles; // repertoire temporaire sur le serveur
-    std::string _TmpFileName;
-    std::string _fileNameToExecute;
 
-    virtual int submit() throw(SALOME_Exception) = 0;
-    void setDirForTmpFiles();
-    void exportInputFiles( const char *fileToExecute, const Engines::FilesList filesToExportList ) throw(SALOME_Exception);
-    virtual void buildSalomeCouplingScript( const char *fileToExecute ) throw(SALOME_Exception) = 0;
-    virtual void buildSalomeBatchScript( const int nbproc ) throw(SALOME_Exception) = 0;
+    virtual int submit(BatchLight::Job* job) throw(SALOME_Exception) = 0;
+    void setDirForTmpFiles(BatchLight::Job* job);
+    void exportInputFiles(BatchLight::Job* job) throw(SALOME_Exception);
+    virtual void buildSalomeCouplingScript(BatchLight::Job* job) throw(SALOME_Exception) = 0;
+    virtual void buildSalomeBatchScript(BatchLight::Job* job) throw(SALOME_Exception) = 0;
 
     std::string BuildTemporaryFileName() const;
-    void RmTmpFile();
+    void RmTmpFile(std::string & TemporaryFileName);
     MpiImpl *FactoryMpiImpl(std::string mpiImpl) throw(SALOME_Exception);
-
   private:
 
   };
index bba030a0c69177070ca2ae90167359cf6826e9e9..eec063a02ba05d25b7c896872a4f3614898d42fd 100644 (file)
@@ -96,10 +96,11 @@ namespace BatchLight {
     logFile += getenv("USER");
     logFile += "/batchSalome_";
 
-    srand ( time(NULL) );
-    int ir = rand();
+    //srand ( time(NULL) );
+    //int ir = rand();
     ostringstream oss;
-    oss << ir;
+    //oss << ir;
+    oss << this << "_" << jobid;
     logFile += oss.str();
     logFile += ".log";
 
@@ -121,9 +122,10 @@ namespace BatchLight {
 
     command += _params.hostname;
     command += " \"qstat -f " ;
-    ostringstream oss2;
-    oss2 << jobid;
-    command += oss2.str();
+    //ostringstream oss2;
+    //oss2 << jobid;
+    //command += oss2.str();
+    command += _pbs_job_name[jobid];
     command += "\" > ";
     command += logFile;
     SCRUTE(command.c_str());
@@ -163,35 +165,73 @@ namespace BatchLight {
     return jstatus;
   }
 
-  void BatchManager_PBS::buildSalomeCouplingScript( const char *fileToExecute ) throw(SALOME_Exception)
+  void BatchManager_PBS::buildSalomeCouplingScript(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_PBS::buildSalomeCouplingScript");
     int status;
+    const char *fileToExecute = job->getFileToExecute();
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    int idx = dirForTmpFiles.find("Batch/");
+    std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
 
     string::size_type p1 = string(fileToExecute).find_last_of("/");
     string::size_type p2 = string(fileToExecute).find_last_of(".");
-    _fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
+    std::string TmpFileName = BuildTemporaryFileName();
 
-    _TmpFileName = BuildTemporaryFileName();
     ofstream tempOutputFile;
-    tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+    
+    // Begin
     tempOutputFile << "#! /bin/sh -f" << endl ;
     tempOutputFile << "cd " ;
     tempOutputFile << _params.applipath << endl ;
+    tempOutputFile << "export SALOME_BATCH=1\n";
     tempOutputFile << "export PYTHONPATH=~/" ;
-    tempOutputFile << _dirForTmpFiles ;
+    tempOutputFile << dirForTmpFiles ;
     tempOutputFile << ":$PYTHONPATH" << endl ;
+
+    // Test node rank
     tempOutputFile << "if test " ;
     tempOutputFile << _mpiImpl->rank() ;
     tempOutputFile << " = 0; then" << endl ;
+
+    // -----------------------------------------------
+    // Code for rank 0 : launch runAppli and a container
+    // RunAppli
     tempOutputFile << "  ./runAppli --terminal --modules=" ;
     for ( int i = 0 ; i < _params.modulesList.size() ; i++ ) {
       tempOutputFile << _params.modulesList[i] ;
       if ( i != _params.modulesList.size()-1 )
        tempOutputFile << "," ;
     }
-    tempOutputFile << " --standalone=registry,study,moduleCatalog --killall &" << endl ;
-    tempOutputFile << "  for ((ip=1; ip < ";
+    tempOutputFile << " --standalone=registry,study,moduleCatalog --ns-port-log="
+                  << filelogtemp 
+                  << " &\n";
+
+    // Wait NamingService
+    tempOutputFile << "  current=0\n"
+                  << "  stop=20\n" 
+                  << "  while ! test -f " << filelogtemp << "\n"
+                  << "  do\n"
+                  << "    sleep 2\n"
+                  << "    let current=current+1\n"
+                  << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+                  << "      echo Error Naming Service failed ! >&2"
+                  << "      exit\n"
+                  << "    fi\n"
+                  << "  done\n"
+                  << "  port=`cat " << filelogtemp << "`\n";
+    
+    // Launch a container
+    tempOutputFile << "  ./runSession SALOME_Container 'YACS_Server_'"
+                  << _mpiImpl->rank()
+                  << " > ~/" << dirForTmpFiles << "/YACS_Server_" 
+                  << _mpiImpl->rank() << "_container_log." << filelogtemp
+                  << " 2>&1 &\n";
+
+    // Wait other containers
+    tempOutputFile << "  for ((ip=0; ip < ";
     tempOutputFile << _mpiImpl->size();
     tempOutputFile << " ; ip++))" << endl;
     tempOutputFile << "  do" << endl ;
@@ -199,18 +239,43 @@ namespace BatchLight {
     tempOutputFile << "  done" << endl ;
     tempOutputFile << "  sleep 5" << endl ;
     tempOutputFile << "  ./runSession waitContainers.py $arglist" << endl ;
-    tempOutputFile << "  ./runSession python ~/" << _dirForTmpFiles << "/" << _fileNameToExecute << ".py" << endl;
-    tempOutputFile << "  ./runSession killCurrentPort" << endl;
+
+    // Launch user script
+    tempOutputFile << "  ./runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py\n";
+
+    // Stop application
+    tempOutputFile << "  rm " << filelogtemp << "\n"
+                  << "  ./runSession killSalomeWithPort.py $port\n";
+   
+    // -------------------------------------
+    // Other nodes launch a container
     tempOutputFile << "else" << endl ;
-    tempOutputFile << "  sleep 5" << endl ;
-    tempOutputFile << "  ./runSession waitNS.py" << endl ;
+    
+    // Wait NamingService
+    tempOutputFile << "  current=0\n"
+                  << "  stop=20\n" 
+                  << "  while ! test -f " << filelogtemp << "\n"
+                  << "  do\n"
+                  << "    sleep 2\n"
+                  << "    let current=current+1\n"
+                  << "    if [ \"$current\" -eq \"$stop\" ] ; then\n"
+                  << "      echo Error Naming Service failed ! >&2"
+                  << "      exit\n"
+                  << "    fi\n"
+                  << "  done\n"
+                  << "  port=`cat " << filelogtemp << "`\n";
+
+    // Launching container
     tempOutputFile << "  ./runSession SALOME_Container 'YACS_Server_'";
-    tempOutputFile << _mpiImpl->rank() << endl ;
-    tempOutputFile << "fi" << endl ;
+    tempOutputFile << _mpiImpl->rank()
+                  << " > ~/" << dirForTmpFiles << "/YACS_Server_" 
+                  << _mpiImpl->rank() << "_container_log." << filelogtemp
+                  << " 2>&1\n";
+    tempOutputFile << "fi" << endl;
     tempOutputFile.flush();
     tempOutputFile.close();
-    chmod(_TmpFileName.c_str(), 0x1ED);
-    SCRUTE(_TmpFileName.c_str()) ;
+    chmod(TmpFileName.c_str(), 0x1ED);
+    SCRUTE(TmpFileName.c_str()) ;
 
     string command;
     if( _params.protocol == "rsh" )
@@ -220,7 +285,7 @@ namespace BatchLight {
     else
       throw SALOME_Exception("Unknown protocol");
     
-    command += _TmpFileName;
+    command += TmpFileName;
     command += " ";
     if (_params.username != ""){
       command += _params.username;
@@ -228,24 +293,34 @@ namespace BatchLight {
     }
     command += _params.hostname;
     command += ":";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles ;
     command += "/runSalome_" ;
-    command += _fileNameToExecute ;
+    command += fileNameToExecute ;
     command += "_Batch.sh" ;
-    SCRUTE(_fileNameToExecute) ;
+    SCRUTE(fileNameToExecute) ;
     SCRUTE(command.c_str());
     status = system(command.c_str());
     if(status)
       throw SALOME_Exception("Error of connection on remote host");    
-    RmTmpFile();
+    RmTmpFile(TmpFileName);
     
     END_OF("BatchManager_PBS::buildSalomeCouplingScript");
   }
 
-  void BatchManager_PBS::buildSalomeBatchScript( const int nbproc ) throw(SALOME_Exception)
+  void BatchManager_PBS::buildSalomeBatchScript(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_PBS::buildSalomeBatchScript");
     int status;
+    const int nbproc = job->getNbProc();
+    std::string edt = job->getExpectedDuringTime();
+    std::string mem = job->getMemory();
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    const char *fileToExecute = job->getFileToExecute();
+    string::size_type p1 = string(fileToExecute).find_last_of("/");
+    string::size_type p2 = string(fileToExecute).find_last_of(".");
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
+    int idx = dirForTmpFiles.find("Batch/");
+    std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
 
     int nbmaxproc = _params.nbnodes * _params.nbprocpernode;
     if( nbproc > nbmaxproc ){
@@ -259,23 +334,32 @@ namespace BatchLight {
     else
       nbnodes = _params.nbnodes;
 
-    _TmpFileName = BuildTemporaryFileName();
+    std::string TmpFileName = BuildTemporaryFileName();
     ofstream tempOutputFile;
-    tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
 
     ostringstream filenameToExecute;
-    filenameToExecute << " ~/" << _dirForTmpFiles << "/runSalome_" << _fileNameToExecute << "_Batch.sh";
+    filenameToExecute << " ~/" << dirForTmpFiles << "/runSalome_" << fileNameToExecute << "_Batch.sh";
 
     tempOutputFile << "#! /bin/sh -f" << endl ;
     tempOutputFile << "#PBS -l nodes=" << nbnodes << endl ;
-    tempOutputFile << "#PBS -o ~/" << _dirForTmpFiles << "/runSalome.log${PBS_JOBID}" << endl ;
+    if (edt != "")
+      tempOutputFile << "#PBS -l walltime=" << edt  << ":00" << endl ;
+    if (mem != "")
+      tempOutputFile << "#PBS -l mem=" << mem << endl ;
+    // In some systems qsub does not correctly expand env variables
+    // like PBS_O_HOME for #PBS directives....
+    //tempOutputFile << "#PBS -o /$PBS_O_HOME/" << dirForTmpFiles << "/runSalome.output.log.${PBS_JOBID}" << endl ;
+    //tempOutputFile << "#PBS -e /$PBS_O_HOME/" << dirForTmpFiles << "/runSalome.error.log.${PBS_JOBID}" << endl ;
+    tempOutputFile << "#PBS -o runSalome.output.log." << filelogtemp << endl ;
+    tempOutputFile << "#PBS -e runSalome.error.log." << filelogtemp << endl ;
     tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbnodes);
     tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,filenameToExecute.str());
     tempOutputFile << _mpiImpl->halt();
     tempOutputFile.flush();
     tempOutputFile.close();
-    chmod(_TmpFileName.c_str(), 0x1ED);
-    SCRUTE(_TmpFileName.c_str()) ;
+    chmod(TmpFileName.c_str(), 0x1ED);
+    SCRUTE(TmpFileName.c_str()) ;
 
     string command;
     if( _params.protocol == "rsh" )
@@ -284,7 +368,7 @@ namespace BatchLight {
       command = "scp ";
     else
       throw SALOME_Exception("Unknown protocol");
-    command += _TmpFileName;
+    command += TmpFileName;
     command += " ";
     if (_params.username != ""){
       command += _params.username;
@@ -292,23 +376,37 @@ namespace BatchLight {
     }
     command += _params.hostname;
     command += ":";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles ;
     command += "/" ;
-    command += _fileNameToExecute ;
+    command += fileNameToExecute ;
     command += "_Batch.sh" ;
     SCRUTE(command.c_str());
     status = system(command.c_str());
     if(status)
       throw SALOME_Exception("Error of connection on remote host");    
-
-    RmTmpFile();
+  
+    // Adding log files into import list files
+    ostringstream file_name_output;
+    file_name_output << "~/" << dirForTmpFiles << "/" << "runSalome.output.log*";
+    ostringstream file_name_error;
+    file_name_error << "~/" << dirForTmpFiles << "/" << "runSalome.error.log*";
+    ostringstream file_container_log;
+    file_container_log << "~/" << dirForTmpFiles << "/" << "YACS_Server*";
+    job->addFileToImportList(file_name_output.str());
+    job->addFileToImportList(file_name_error.str());
+    job->addFileToImportList(file_container_log.str());
+    RmTmpFile(TmpFileName);
     END_OF("BatchManager_PBS::buildSalomeBatchScript");
-    
   }
 
-  int BatchManager_PBS::submit() throw(SALOME_Exception)
+  int BatchManager_PBS::submit(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_PBS::submit");
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    const char *fileToExecute = job->getFileToExecute();
+    string::size_type p1 = string(fileToExecute).find_last_of("/");
+    string::size_type p2 = string(fileToExecute).find_last_of(".");
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
 
     // define name of log file
     string logFile="/tmp/logs/";
@@ -339,10 +437,10 @@ namespace BatchLight {
     }
 
     command += _params.hostname;
-    command += " \"qsub " ;
-    command += _dirForTmpFiles ;
-    command += "/" ;
-    command += _fileNameToExecute ;
+    command += " \"cd " ;
+    command += dirForTmpFiles;
+    command += "; qsub " ;
+    command += fileNameToExecute ;
     command += "_Batch.sh\" > ";
     command += logFile;
     SCRUTE(command.c_str());
@@ -368,6 +466,8 @@ namespace BatchLight {
     istringstream iss(strjob);
     iss >> id;
 
+    // Ajout dans la map
+    _pbs_job_name[id] = sline;
     END_OF("BatchManager_PBS::submit");
     return id;
   }
index e7e5789c7d652c243a3b5ed59a44f09b016b41db..e0c21651b9ff3ed402f33704f1d36e87bfd023ba 100644 (file)
@@ -49,9 +49,14 @@ namespace BatchLight {
     std::string queryJob(const int & jobid); // renvoie l'etat du job
 
   private:
-    void buildSalomeCouplingScript( const char *fileToExecute ) throw(SALOME_Exception);
-    void buildSalomeBatchScript( const int nbproc ) throw(SALOME_Exception);
-    int submit() throw(SALOME_Exception);
+    void buildSalomeCouplingScript(BatchLight::Job* job) throw(SALOME_Exception);
+    void buildSalomeBatchScript(BatchLight::Job* job) throw(SALOME_Exception);
+    int submit(BatchLight::Job* job) throw(SALOME_Exception);
+
+    // Permet d'avoir la chaîne complête pour demander
+    // le statut du job
+    typedef std::map<int, std::string> _pbs_job_name_t;
+    _pbs_job_name_t _pbs_job_name;
   };
 
 }
index 57019f37c275d3c4c6c91708627d643799d1aaef..d184ca6bbc435d5960cb9d112162a37d91230f8c 100644 (file)
@@ -143,23 +143,25 @@ namespace BatchLight {
     return jstatus;
   }
 
-  void BatchManager_SLURM::buildSalomeCouplingScript( const char *fileToExecute ) throw(SALOME_Exception)
+  void BatchManager_SLURM::buildSalomeCouplingScript(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_SLURM::buildSalomeCouplingScript");
     int status;
+    const char *fileToExecute = job->getFileToExecute();
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
 
     string::size_type p1 = string(fileToExecute).find_last_of("/");
     string::size_type p2 = string(fileToExecute).find_last_of(".");
-    _fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
 
-    _TmpFileName = BuildTemporaryFileName();
+    std::string TmpFileName = BuildTemporaryFileName();
     ofstream tempOutputFile;
-    tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
     tempOutputFile << "#! /bin/sh -f" << endl ;
     tempOutputFile << "cd " ;
     tempOutputFile << _params.applipath << endl ;
     tempOutputFile << "export PYTHONPATH=~/" ;
-    tempOutputFile << _dirForTmpFiles ;
+    tempOutputFile << dirForTmpFiles ;
     tempOutputFile << ":$PYTHONPATH" << endl ;
     tempOutputFile << "if test $SLURM_PROCID = 0; then" << endl ;
     tempOutputFile << "  ./runAppli --terminal --modules=" ;
@@ -175,7 +177,7 @@ namespace BatchLight {
     tempOutputFile << "  done" << endl ;
     tempOutputFile << "  ./runSession waitNS.sh" << endl ;
     tempOutputFile << "  ./runSession waitContainers.py $arglist" << endl ;
-    tempOutputFile << "  ./runSession python ~/" << _dirForTmpFiles << "/" << _fileNameToExecute << ".py" << endl;
+    tempOutputFile << "  ./runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py" << endl;
     tempOutputFile << "  ./runSession killCurrentPort" << endl;
     tempOutputFile << "else" << endl ;
     tempOutputFile << "  ./runSession waitNS.sh" << endl ;
@@ -183,8 +185,8 @@ namespace BatchLight {
     tempOutputFile << "fi" << endl ;
     tempOutputFile.flush();
     tempOutputFile.close();
-    chmod(_TmpFileName.c_str(), 0x1ED);
-    SCRUTE(_TmpFileName.c_str()) ;
+    chmod(TmpFileName.c_str(), 0x1ED);
+    SCRUTE(TmpFileName.c_str()) ;
 
     string command;
     if( _params.protocol == "rsh" )
@@ -194,7 +196,7 @@ namespace BatchLight {
     else
       throw SALOME_Exception("Unknown protocol");
     
-    command += _TmpFileName;
+    command += TmpFileName;
     command += " ";
     if (_params.username != ""){
       command += _params.username;
@@ -202,35 +204,41 @@ namespace BatchLight {
     }
     command += _params.hostname;
     command += ":";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles ;
     command += "/runSalome_" ;
-    command += _fileNameToExecute ;
+    command += fileNameToExecute ;
     command += "_Batch.sh" ;
     SCRUTE(command.c_str());
     status = system(command.c_str());
     if(status)
       throw SALOME_Exception("Error of connection on remote host");    
-    RmTmpFile();
+    RmTmpFile(TmpFileName);
     
     END_OF("BatchManager_SLURM::buildSalomeCouplingScript");
   }
 
-  void BatchManager_SLURM::buildSalomeBatchScript( const int nbproc ) throw(SALOME_Exception)
+  void BatchManager_SLURM::buildSalomeBatchScript(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_SLURM::buildSalomeBatchScript");
     int status;
-    _TmpFileName = BuildTemporaryFileName();
+    const int nbproc = job->getNbProc();
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    std::string TmpFileName = BuildTemporaryFileName();
     ofstream tempOutputFile;
-    tempOutputFile.open(_TmpFileName.c_str(), ofstream::out );
+    tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+    const char *fileToExecute = job->getFileToExecute();
+    string::size_type p1 = string(fileToExecute).find_last_of("/");
+    string::size_type p2 = string(fileToExecute).find_last_of(".");
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
 
     tempOutputFile << "#! /bin/sh -f" << endl ;
     tempOutputFile << "#BSUB -n " << nbproc << endl ;
-    tempOutputFile << "#BSUB -o " << _dirForTmpFiles << "/runSalome.log%J" << endl ;
-    tempOutputFile << "srun ~/" << _dirForTmpFiles << "/runSalome_" << _fileNameToExecute << "_Batch.sh" << endl ;
+    tempOutputFile << "#BSUB -o " << dirForTmpFiles << "/runSalome.log%J" << endl ;
+    tempOutputFile << "srun ~/" << dirForTmpFiles << "/runSalome_" << fileNameToExecute << "_Batch.sh" << endl ;
     tempOutputFile.flush();
     tempOutputFile.close();
-    chmod(_TmpFileName.c_str(), 0x1ED);
-    SCRUTE(_TmpFileName.c_str()) ;
+    chmod(TmpFileName.c_str(), 0x1ED);
+    SCRUTE(TmpFileName.c_str()) ;
 
     string command;
     if( _params.protocol == "rsh" )
@@ -239,7 +247,7 @@ namespace BatchLight {
       command = "scp ";
     else
       throw SALOME_Exception("Unknown protocol");
-    command += _TmpFileName;
+    command += TmpFileName;
     command += " ";
     if (_params.username != ""){
       command += _params.username;
@@ -247,23 +255,28 @@ namespace BatchLight {
     }
     command += _params.hostname;
     command += ":";
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles ;
     command += "/" ;
-    command += _fileNameToExecute ;
+    command += fileNameToExecute ;
     command += "_Batch.sh" ;
     SCRUTE(command.c_str());
     status = system(command.c_str());
     if(status)
       throw SALOME_Exception("Error of connection on remote host");    
 
-    RmTmpFile();
+    RmTmpFile(TmpFileName);
     END_OF("BatchManager_SLURM::buildSalomeBatchScript");
     
   }
 
-  int BatchManager_SLURM::submit() throw(SALOME_Exception)
+  int BatchManager_SLURM::submit(BatchLight::Job* job) throw(SALOME_Exception)
   {
     BEGIN_OF("BatchManager_SLURM::submit");
+    const std::string dirForTmpFiles = job->getDirForTmpFiles();
+    const char *fileToExecute = job->getFileToExecute();
+    string::size_type p1 = string(fileToExecute).find_last_of("/");
+    string::size_type p2 = string(fileToExecute).find_last_of(".");
+    std::string fileNameToExecute = string(fileToExecute).substr(p1+1,p2-p1-1);
 
     // define name of log file
     string logFile="/tmp/logs/";
@@ -295,9 +308,9 @@ namespace BatchLight {
 
     command += _params.hostname;
     command += " \"bsub < " ;
-    command += _dirForTmpFiles ;
+    command += dirForTmpFiles ;
     command += "/" ;
-    command += _fileNameToExecute ;
+    command += fileNameToExecute ;
     command += "_Batch.sh\" > ";
     command += logFile;
     SCRUTE(command.c_str());
@@ -312,9 +325,9 @@ namespace BatchLight {
     fclose(fp);
     
     string sline(line);
-    int p1 = sline.find("<");
-    int p2 = sline.find(">");
-    string strjob = sline.substr(p1+1,p2-p1-1);
+    int p10 = sline.find("<");
+    int p20 = sline.find(">");
+    string strjob = sline.substr(p10+1,p20-p10-1);
 
     int id;
     istringstream iss(strjob);
index ed21624dd1b87bc00aa63b738848f749da384997..6024b28dee99106b19d5e7b265f115d66635ec10 100644 (file)
@@ -49,9 +49,9 @@ namespace BatchLight {
     std::string queryJob(const int & jobid); // renvoie l'etat du job
 
   protected:
-    void buildSalomeCouplingScript( const char *fileToExecute ) throw(SALOME_Exception);
-    void buildSalomeBatchScript( const int nbproc ) throw(SALOME_Exception);
-    int submit() throw(SALOME_Exception);
+    void buildSalomeCouplingScript(BatchLight::Job* job) throw(SALOME_Exception);
+    void buildSalomeBatchScript(BatchLight::Job* job) throw(SALOME_Exception);
+    int submit(BatchLight::Job* job) throw(SALOME_Exception);
 
   private:
 
index 9762a98a6da00277871fd601a46b3832f97e9f53..1980054a9abd0e2014eb1504362042e38e0fe8a1 100644 (file)
  */
 
 #include "BatchLight_Job.hxx"
+#include <sstream>
+
 using namespace std;
+using namespace BatchLight;
+
+Job::Job(const char *fileToExecute, 
+        const Engines::FilesList& filesToExport, 
+        const Engines::FilesList& filesToImport, 
+        const Engines::BatchParameters& batch_params) : _fileToExecute(fileToExecute), 
+  _filesToExport(filesToExport), 
+  _filesToImport(filesToImport), 
+  _batch_params(batch_params)
+{
+  _dirForTmpFiles = "/tmp/default_batch_tmp_directory";
+  std::string _fileNameToExecute = "";
+}
+
+Job::~Job()
+{
+  MESSAGE("Job destructor");
+}
+
+void 
+Job::addFileToImportList(std::string file_name) 
+{
+  CORBA::ULong lgth = _filesToImport.length();
+  _filesToImport.length(lgth+1);
+  _filesToImport[lgth] = CORBA::string_dup(file_name.c_str());
+}
+
+const std::string
+Job::getExpectedDuringTime() 
+{
+  std::string str(_batch_params.expected_during_time);
+  return str;
+}
+
+const std::string 
+Job::getMemory()
+{
+  std::string str(_batch_params.mem);
+  return str;
+}
+
+bool
+Job::check() {
+  bool rtn = true;
+  INFOS("Warning : batch_directory option is not currently implemented"); 
+  INFOS("Warning : currently these informations are only in the PBS batch manager"); 
+  INFOS("Job parameters are :");
+  INFOS("Directory : $HOME/Batch/$date");
 
-namespace BatchLight {
+  // check expected_during_time (check the format)
+  std::string edt_info;
+  std::string edt_value = _batch_params.expected_during_time.in();
+  if (edt_value != "") {
+    std::string begin_edt_value = edt_value.substr(0, 2);
+    std::string mid_edt_value = edt_value.substr(2, 1);
+    std::string end_edt_value = edt_value.substr(3);
+  
+    long value;
+    std::istringstream iss(begin_edt_value);
+    if (!(iss >> value)) {
+      edt_info = "Error on definition ! : " + edt_value;
+      rtn = false;
+    }
+    else if (value < 0) {
+      edt_info = "Error on definition time is negative ! : " + value;
+      rtn = false;
+    }
+    std::istringstream iss_2(end_edt_value);
+    if (!(iss_2 >> value)) {
+      edt_info = "Error on definition ! : " + edt_value;
+      rtn = false;
+    }
+    else if (value < 0) {
+      edt_info = "Error on definition time is negative ! : " + value;
+      rtn = false;
+    }
+    if (mid_edt_value != ":") {
+      edt_info = "Error on definition ! :" + edt_value;
+      rtn = false;
+    }
+  }
+  else {
+    edt_info = "No value given";
+  }
+  INFOS("Expected during time : " << edt_info);
 
-  // Constructeur
-  Job::Job(const char *fileToExecute, const Engines::FilesList& filesToExport, const Engines::FilesList& filesToImport, const int nbproc) : _fileToExecute(fileToExecute), _filesToExport(filesToExport), _filesToImport(filesToImport), _nbproc(nbproc)
-  {
-    // Nothing to do
+  // check memory (check the format)
+  std::string mem_info;
+  std::string mem_value = _batch_params.mem.in();
+  if (mem_value != "") {
+    std::string begin_mem_value = mem_value.substr(0, mem_value.length()-2);
+    long re_mem_value;
+    std::istringstream iss(begin_mem_value);
+    if (!(iss >> re_mem_value)) {
+      mem_info = "Error on definition ! : " + mem_value;
+      rtn = false;
+    }
+    else if (re_mem_value <= 0) {
+      mem_info = "Error on definition memory is negative ! : " + mem_value;
+      rtn = false;
+    }
+    std::string end_mem_value = mem_value.substr(mem_value.length()-2);
+    if (end_mem_value != "gb" and end_mem_value != "mb") {
+      mem_info = "Error on definition, type is bad ! " + mem_value;
+      rtn = false;
+    }
   }
+  else {
+    mem_info = "No value given";
+  }
+  INFOS("Memory : " << mem_info);
 
-  Job::~Job()
-  {
-    MESSAGE("Job destructor");
+  // check nb_proc
+  std::string nb_proc_info;
+  ostringstream nb_proc_value;
+  nb_proc_value << _batch_params.nb_proc;
+  if(_batch_params.nb_proc <= 0) {
+    nb_proc_info = "Bad value ! nb_proc = ";
+    nb_proc_info += nb_proc_value.str();
+    rtn = false;
+  }
+  else {
+    nb_proc_info = nb_proc_value.str();
   }
+  INFOS("Nb of processors : " << nb_proc_info);
 
+  return rtn;
 }
index 23ac8f3bb168d1088b3808186de792d83e11316d..e17e790b9192ede7f46caa541df4d83a239d5e7d 100644 (file)
@@ -39,20 +39,30 @@ namespace BatchLight {
   {
   public:
     // Constructeurs et destructeur
-    Job(const char *fileToExecute, const Engines::FilesList& filesToExport, const Engines::FilesList& filesToImport, const int nbproc);
+    Job(const char *fileToExecute, 
+       const Engines::FilesList& filesToExport, 
+       const Engines::FilesList& filesToImport, 
+       const Engines::BatchParameters& batch_params);
     virtual ~Job();
 
     const char *getFileToExecute() const { return _fileToExecute; }
     const Engines::FilesList getFilesToExportList() const { return _filesToExport; }
     const Engines::FilesList getFilesToImportList() const { return _filesToImport; }
-    const int getNbProc() const { return _nbproc; }
-    
+    void addFileToImportList(std::string file_name);
+    const CORBA::Long getNbProc() const { return _batch_params.nb_proc; }
+    const std::string getExpectedDuringTime();
+    const std::string getMemory();
+
+    const std::string getDirForTmpFiles() const { return _dirForTmpFiles;}
+    void setDirForTmpFiles(std::string dirForTmpFiles) {_dirForTmpFiles = dirForTmpFiles;
+                                                       SCRUTE(_dirForTmpFiles);}
+    bool check();                                                      
   protected:
     const char* _fileToExecute;
     const Engines::FilesList _filesToExport;
-    const Engines::FilesList _filesToImport;
-    const int _nbproc;
-
+    Engines::FilesList _filesToImport;
+    Engines::BatchParameters _batch_params;
+    std::string _dirForTmpFiles; // Tmp directory on the server
   private:
 
   };
index 3b73b7c026c07e69c6e66fb04c4737fa2e0e9dd3..a507c010db42b1b6f503d0e06411641b5ad04c75 100644 (file)
@@ -120,7 +120,7 @@ CORBA::Long SALOME_Launcher::getPID()
 CORBA::Long SALOME_Launcher::submitSalomeJob( const char * fileToExecute ,
                                              const Engines::FilesList& filesToExport ,
                                              const Engines::FilesList& filesToImport ,
-                                             const CORBA::Long NumberOfProcessors ,
+                                             const Engines::BatchParameters& batch_params,
                                              const Engines::MachineParameters& params)
 {
   MESSAGE("BEGIN OF SALOME_Launcher::submitSalomeJob");
@@ -128,22 +128,33 @@ CORBA::Long SALOME_Launcher::submitSalomeJob( const char * fileToExecute ,
   try{
     // find a cluster matching the structure params
     Engines::CompoList aCompoList ;
-    Engines::MachineList *aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+    Engines::MachineList *aMachineList = _ResManager->GetFittingResources(params, aCompoList);
+    if (aMachineList->length() == 0)
+      throw SALOME_Exception("No resources have been found with your parameters");
+
     const Engines::MachineParameters* p = _ResManager->GetMachineParameters((*aMachineList)[0]);
     string clustername(p->alias);
-    
+    INFOS("Choose cluster" <<  clustername);
+
     // search batch manager for that cluster in map or instanciate one
     std::map < string, BatchLight::BatchManager * >::const_iterator it = _batchmap.find(clustername);
-    SCRUTE(clustername);
     if(it == _batchmap.end())
-      _batchmap[clustername] = FactoryBatchManager( p );
+    {
+      _batchmap[clustername] = FactoryBatchManager(p);
+      // TODO: Add a test for the cluster !
+    }
     
-    // submit job on cluster
-    BatchLight::Job* job = new BatchLight::Job( fileToExecute, filesToExport, filesToImport, NumberOfProcessors );
+    // create and submit job on cluster
+    BatchLight::Job* job = new BatchLight::Job(fileToExecute, filesToExport, filesToImport, batch_params);
+    bool res = job->check();
+    if (!res) {
+      delete job;
+      throw SALOME_Exception("Job parameters are bad (see informations above)");
+    }
     jobId = _batchmap[clustername]->submitJob(job);
   }
   catch(const SALOME_Exception &ex){
-    MESSAGE(ex.what());
+    INFOS(ex.what());
     THROW_SALOME_CORBA_EXCEPTION(ex.what(),SALOME::INTERNAL_ERROR);
   }
   return jobId;
index 08570fe72879c9c45b668e209e62320b1dfff75c..4bc5d65ce4877ef08b2411ae897368945e310f43 100644 (file)
@@ -55,7 +55,7 @@ public:
   CORBA::Long submitSalomeJob(const char * fileToExecute ,
                              const Engines::FilesList& filesToExport ,
                              const Engines::FilesList& filesToImport ,
-                             const CORBA::Long NumberOfProcessors ,
+                             const Engines::BatchParameters& batch_params,
                              const Engines::MachineParameters& params);
 
   char* querySalomeJob( const CORBA::Long jobId, const Engines::MachineParameters& params);
index 5b1f13f938b815da616bbcbd9d15b5fe17f05d02..6481eb9956a3d9627fb4501b4b76b216118ab2c1 100644 (file)
@@ -11,6 +11,8 @@
 #if !defined SALOME_Logger_Server_include
 #define SALOME_Logger_Server_include
 
+#include <SALOMEconfig.h>
+
 #ifndef WNT
 #include <fstream.h>
 #else
index 59f355d4b44bac3f0ea81bf577890c4b4d884a63..e043680f40b8dc86a04adc97dd96c9532b7ccc00 100644 (file)
@@ -49,6 +49,7 @@ _libNOTIFICATION_la_CPPFLAGS =\
        -I$(srcdir)/../Notification \
        -I$(srcdir)/../Basics \
        -I$(srcdir)/../SALOMELocalTrace \
+       -I$(top_builddir)/salome_adm/unix \
        @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
 
 
index 3021b6c857ca6e97aa489ada3096792c52d3456d..d4eb2aa7e1ab228c33119f389551c341462ef499 100644 (file)
@@ -66,9 +66,8 @@ void NamingService_WaitForServerReadiness(SALOME_NamingService* NS,
        {
          if (serverName.length() == 0)
            {
-             char* dummyadr = NS->getIORaddr(); // to wait for naming service
+              CORBA::String_var dummyadr = NS->getIORaddr(); // to wait for naming service
              found = 1;
-              delete [] dummyadr;
              break; // naming service found
            }
          else
@@ -81,9 +80,9 @@ void NamingService_WaitForServerReadiness(SALOME_NamingService* NS,
                }
              MESSAGE("Server "<< serverName <<" not yet ready, waiting...");
 #ifndef WNT
-             int a = nanosleep(&ts_req,&ts_rem); // wait before retry
+              nanosleep(&ts_req,&ts_rem); // wait before retry
 #else
-                 Sleep(TIMESleep/1000000);
+              Sleep(TIMESleep/1000000);
 #endif
            }
        }
@@ -91,9 +90,9 @@ void NamingService_WaitForServerReadiness(SALOME_NamingService* NS,
        {
          MESSAGE("CORBA::COMM_FAILURE: Naming Service not yet ready, waiting...");
 #ifndef WNT
-         int a = nanosleep(&ts_req,&ts_rem); // wait before retry
+          nanosleep(&ts_req,&ts_rem); // wait before retry
 #else
-         Sleep(TIMESleep/1000000);
+          Sleep(TIMESleep/1000000);
 #endif
        }
     }
index bfb70a8df2df41ed61551eb5c86d478daf5fa6d2..2a9e1fca2b76c3d34d88cafb6d4c732259e3f169 100644 (file)
@@ -182,9 +182,8 @@ NamingServiceTest::testConstructorDefault()
   //CPPUNIT_ASSERT_THROW(NS.getIORaddr(),CORBA::Exception);
   NS.init_orb(_orb);
 
-  char *root = NS.getIORaddr();
+  CORBA::String_var root = NS.getIORaddr();
   CORBA::Object_var obj = _orb->string_to_object(root);
-  delete [] root;
   CPPUNIT_ASSERT(!CORBA::is_nil(obj));
 
   CosNaming::NamingContext_var rootContext =
@@ -202,10 +201,9 @@ void
 NamingServiceTest::testConstructorOrb()
 {
   SALOME_NamingService  NS(_orb);
-  char *root = NS.getIORaddr();
+  CORBA::String_var root = NS.getIORaddr();
   CORBA::Object_var obj = _orb->string_to_object(root);
   CPPUNIT_ASSERT(!CORBA::is_nil(obj));
-  delete [] root;
 
   CosNaming::NamingContext_var rootContext =
     CosNaming::NamingContext::_narrow(obj);
@@ -1208,9 +1206,8 @@ NamingServiceTest::testDestroyFullDirectory()
 void
 NamingServiceTest::testGetIorAddr()
 {
-  char *root = _NS.getIORaddr();
+  CORBA::String_var root = _NS.getIORaddr();
   CORBA::Object_var obj = _orb->string_to_object(root);
-  delete [] root;
   CPPUNIT_ASSERT(!CORBA::is_nil(obj)); 
 }
 
index 2cb2d3010d750a05b42394a71b09a93d18fd8ca1..271a3776ff9429be5e2e4d11c71584f5642361e5 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef _COS_NOTIFY_H_
 #define _COS_NOTIFY_H_
 
+#include <SALOMEconfig.h>
+
 #ifndef COS_USES_BOA
 #include <COS/TimeBase.hh>
 #include <COS/CosNotification.hh>
index 74fb69e07264dbb745f20db56c965f807008a8b1..1259fbd1c1f68d5b88ba8cdc80ff70a23089085b 100644 (file)
@@ -57,6 +57,7 @@ libSalomeNotification_la_CPPFLAGS =\
        -I$(srcdir)/../Basics \
        -I$(srcdir)/../SALOMELocalTrace \
        -I$(srcdir)/../Utils \
+       -I$(top_builddir)/salome_adm/unix \
        @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
 
 
index f282ac73515099a32713646ef29594b46ba6782c..ea88da8f8de8b99f184482e23d9734fc8d62fd65 100644 (file)
@@ -473,7 +473,7 @@ bool isPythonContainer(const char* ContainerName)
  *  see BuildTempFileToLaunchRemoteContainer()
  *
  *  Else rely on distant configuration. Command is under the form (example):
- *  ssh user@machine distantPath/runRemote.sh hostNS portNS \
+ *  ssh user@machine distantPath/runRemote.sh hostNS portNS workingdir \
  *                   SALOME_Container containerName &"
 
  *  - where user is ommited if not specified in CatalogResources,
@@ -483,6 +483,7 @@ bool isPythonContainer(const char* ContainerName)
  *    use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
  *  - where portNS is the port used by CORBA naming server (set by scripts to
  *    use to launch SALOME and servers in $APPLI: runAppli.sh, runRemote.sh)
+ *  - where workingdir is the requested working directory for the container
  */ 
 //=============================================================================
 
@@ -514,7 +515,7 @@ SALOME_ResourcesManager::BuildCommandToLaunchRemoteContainer
             nbproc = params.nb_node * params.nb_proc_per_node;
         }
 
-      // "ssh user@machine distantPath/runRemote.sh hostNS portNS \
+      // "ssh user@machine distantPath/runRemote.sh hostNS portNS workingdir \
       //  SALOME_Container containerName &"
 
       if (resInfo.Protocol == rsh)
@@ -550,6 +551,13 @@ SALOME_ResourcesManager::BuildCommandToLaunchRemoteContainer
       ASSERT(getenv("NSPORT"));
       command += getenv("NSPORT"); // port of CORBA name server
 
+      command += " '";
+      std::string wdir=params.workingdir.in();
+      if(wdir == "$TEMPDIR")
+        wdir="\\$TEMPDIR";
+      command += wdir; // requested working directory
+      command += "'"; 
+
       if(params.isMPI)
        {
          command += " mpirun -np ";
@@ -570,13 +578,6 @@ SALOME_ResourcesManager::BuildCommandToLaunchRemoteContainer
       command += idc;
       command += " -";
       AddOmninamesParams(command);
-      command += " > /tmp/";
-      command += _NS->ContainerName(params);
-      command += "_";
-      command += GetHostname();
-      command += "_";
-      command += getenv( "USER" ) ;
-      command += ".log 2>&1 &" ;
 
       MESSAGE("command =" << command);
     }
@@ -629,10 +630,32 @@ SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer
 
   else
     {
+      command="";
+      std::string wdir=params.workingdir.in();
+      std::cerr << wdir << std::endl;
+      if(wdir != "")
+        {
+          // a working directory is requested
+          if(wdir == "$TEMPDIR")
+            {
+              // a new temporary directory is requested
+              char dir[]="/tmp/salomeXXXXXX";
+              char* mdir=mkdtemp(dir);
+              if(mdir==NULL)
+                std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
+              else
+                command="cd "+std::string(dir)+";";
+            }
+          else
+            {
+              // a permanent directory is requested use it or create it
+              command="mkdir -p " + wdir + " && cd " + wdir + ";";
+            }
+        }
       if (isPythonContainer(params.container_name))
-        command = "SALOME_ContainerPy.py ";
+        command += "SALOME_ContainerPy.py ";
       else
-        command = "SALOME_Container ";
+        command += "SALOME_Container ";
     }
 
   command += _NS->ContainerName(params);
@@ -641,13 +664,7 @@ SALOME_ResourcesManager::BuildCommandToLaunchLocalContainer
   command += idc;
   command += " -";
   AddOmninamesParams(command);
-  command += " > /tmp/";
-  command += _NS->ContainerName(params);
-  command += "_";
-  command += GetHostname();
-  command += "_";
-  command += getenv( "USER" ) ;
-  command += ".log 2>&1 &" ;
+
   MESSAGE("Command is ... " << command);
   return command;
 }
@@ -717,13 +734,6 @@ SALOME_ResourcesManager::BuildCommand
   command += containerName;
   command += " -";
   AddOmninamesParams(command);
-  command += " > /tmp/";
-  command += containerName;
-  command += "_";
-  command += machine;
-  command += "_";
-  command += getenv( "USER" ) ;
-  command += ".log 2>&1 &" ;
 
   SCRUTE( command );
   return command;
@@ -823,11 +833,9 @@ void SALOME_ResourcesManager::AddOmninamesParams(string& command) const
     //}
     //command += nameservice ;
 
-    char *iorstr = _NS->getIORaddr();
+    CORBA::String_var iorstr = _NS->getIORaddr();
     command += "ORBInitRef NameService=";
     command += iorstr;
-    //It's in fact a CORBA::String allocated with new [] !!!
-    delete [] iorstr;
   }
 
 
@@ -839,8 +847,9 @@ void SALOME_ResourcesManager::AddOmninamesParams(string& command) const
 
 void SALOME_ResourcesManager::AddOmninamesParams(ofstream& fileStream) const
   {
+    CORBA::String_var iorstr = _NS->getIORaddr();
     fileStream << "ORBInitRef NameService=";
-    fileStream << _NS->getIORaddr();
+    fileStream << iorstr;
   }
 
 
@@ -987,14 +996,7 @@ SALOME_ResourcesManager::BuildTempFileToLaunchRemoteContainer
   _CommandForRemAccess = command;
   command += " ";
   command += _TmpFileName;
-  command += " > ";
-  command += "/tmp/";
-  command += _NS->ContainerName(params);
-  command += "_";
-  command += machine;
-  command += "_";
-  command += getenv( "USER" ) ;
-  command += ".log 2>&1 &";
+
   SCRUTE(command);
 
   return command;
index da3a87e2e081394ffb304ed5774e9173cfa56a77..1a61bc49603a6395a42e109a20c0e024aa7b2fc9 100644 (file)
 #ifndef __SALOMEDS_DRIVER_I_H__
 #define __SALOMEDS_DRIVER_I_H__
 
+#include <SALOMEconfig.h>
+
 #include <omniORB4/CORBA.h>
 #include "SALOMEDSImpl_Driver.hxx"
 #include "SALOMEDSImpl_SComponent.hxx"
 #include "SALOMEDSImpl_SObject.hxx"
 
-#include <SALOMEconfig.h>   
 #include CORBA_SERVER_HEADER(SALOMEDS) 
 #include CORBA_SERVER_HEADER(SALOME_Component)
 
index 73163eea427259b939ec0fd08dbe0e8f2f420545..b1286b9159ce0e64d7e34e80849e5aea333deed2 100644 (file)
@@ -24,6 +24,8 @@
 //  Module : KERNEL
 //  $Header$
 
+#include <SALOMEconfig.h>
+
 #include <iostream>
 #include <sstream>
 #include <fstream>
index d429d0daa3f4f8b7727635434a848f87ba46d2c5..9ae866266b03151f06d82d74ba8ff601adff591e 100644 (file)
@@ -29,6 +29,8 @@
 # if !defined( __DESTRUCTEUR_GENERIQUE__H__ )
 # define __DESTRUCTEUR_GENERIQUE__H__
 
+#include <SALOMEconfig.h>
+
 #include "SALOME_Utils.hxx"
 
 #include <list>
index 672d630c3180bf11b21c863bf8c316c754cc32eb..e4f8c97f174fc9029ef7a8af177e81859757b977 100644 (file)
@@ -29,6 +29,8 @@
 # if ! defined( __ORB_INIT_HXX__ )
 # define __ORB_INIT_HXX__
 
+#include <SALOMEconfig.h>
+
 #include "SALOME_Utils.hxx"
 
 #include "omniORB4/CORBA.h"