From 6d16b0dcdb01b27a37c62c7796269541bbffd4d2 Mon Sep 17 00:00:00 2001 From: ribes Date: Fri, 18 Jul 2008 09:16:55 +0000 Subject: [PATCH] - Boucherie --- bin/Makefile.am | 78 ++-- bin/NSparam.py | 27 +- bin/addToKillList.py | 101 +++-- bin/envSalome.py | 2 +- bin/killSalome.py | 58 ++- bin/killSalomeWithPort.py | 179 +++++--- bin/launchConfigureParser.py | 13 +- bin/nameserver.py | 15 +- bin/orbmodule.py | 3 +- bin/runNS.py | 2 +- bin/runSalome.py | 189 +++++---- bin/salome_session.py | 49 ++- bin/salome_utilities.py | 346 +++++++++++++++ bin/setenv.py | 28 +- bin/shutdownSalome.py | 5 +- configure.ac | 31 +- idl/SALOME_ModuleCatalog.idl | 3 +- idl/SALOME_Session.idl | 17 + salome_adm/unix/Makefile.am | 6 +- salome_adm/unix/config_files/check_lsf.m4 | 2 +- salome_adm/unix/config_files/check_withihm.m4 | 65 ++- src/Basics/BasicsGenericDestructor.cxx | 1 + src/Batch/Batch_JobInfo_LSF.cxx | 2 +- src/Batch/Makefile.am | 2 +- src/Container/Component_i.cxx | 59 ++- src/Container/Container_i.cxx | 177 +++++++- src/Container/SALOME_ComponentPy.py | 5 +- src/Container/SALOME_Component_i.hxx | 8 + src/Container/SALOME_Container.py | 4 +- src/Container/SALOME_ContainerManager.cxx | 80 +++- src/Container/SALOME_ContainerManager.hxx | 9 +- src/Container/SALOME_ContainerPy.py | 61 +-- src/DSC/DSC_Basic/DSC_i.cxx | 13 + src/DSC/DSC_Basic/DSC_i.hxx | 6 + src/DSC/DSC_Python/calcium.i | 28 +- src/DSC/DSC_User/Datastream/Calcium/Calcium.c | 145 +++---- .../DSC_User/Datastream/Calcium/Calcium.cxx | 2 +- .../Calcium/CalciumCouplingPolicy.cxx | 12 + .../Calcium/CalciumCouplingPolicy.hxx | 6 + .../Calcium/CalciumCxxInterface.hxx | 158 ++++--- .../Calcium/CalciumGenericProvidesPort.hxx | 43 +- .../Datastream/Calcium/CalciumInterface.hxx | 44 +- .../Datastream/Calcium/CalciumPortTraits.hxx | 15 +- .../Datastream/Calcium/Copy2CorbaSpace.hxx | 21 +- .../Datastream/Calcium/Copy2UserSpace.hxx | 151 +++---- .../DSC_User/Datastream/Calcium/Makefile.am | 1 + src/DSC/DSC_User/Datastream/Calcium/calcium.h | 1 + .../DSC_User/Datastream/Calcium/calciumE.h | 401 ++++++++++++++++++ .../DSC_User/Datastream/Calcium/calciumf.c | 2 +- .../Datastream/CorbaTypeManipulator.hxx | 53 ++- src/DSC/DSC_User/Superv_Component_i.cxx | 14 + src/DSC/DSC_User/Superv_Component_i.hxx | 6 + src/Launcher/Launcher.cxx | 5 +- .../SALOME_ModuleCatalog_Acomponent_impl.hxx | 2 +- .../SALOME_ModuleCatalog_Handler.cxx | 2 + .../SALOME_ModuleCatalog_impl.cxx | 6 +- src/NOTIFICATION_SWIG/Makefile.am | 2 - src/NamingService/SALOME_NamingServicePy.py | 52 ++- src/Registry/RegistryService.hxx | 2 +- src/Registry/SALOME_Registry_Server.cxx | 1 + src/ResourcesManager/ResourcesManager.cxx | 24 +- .../SALOME_ResourcesCatalog_Handler.cxx | 45 +- .../SALOME_ResourcesManager.cxx | 4 +- src/SALOMELocalTrace/LocalTraceBufferPool.hxx | 2 +- src/SALOMELocalTrace/utilities.h | 5 + src/Utils/Utils_DESTRUCTEUR_GENERIQUE.cxx | 3 + src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx | 2 +- 67 files changed, 2119 insertions(+), 787 deletions(-) create mode 100644 bin/salome_utilities.py create mode 100644 src/DSC/DSC_User/Datastream/Calcium/calciumE.h diff --git a/bin/Makefile.am b/bin/Makefile.am index b8086e529..077743e33 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -32,40 +32,44 @@ include $(top_srcdir)/salome_adm/unix/make_common_starter.am # # These files are data, module or lib files -dist_salomescript_DATA= \ - VERSION \ - orbmodule.py \ - salomeConsole.py \ - salome_session.py +dist_salomescript_DATA = \ + config_appli.xml \ + salome.launch \ + VERSION # These files are executable scripts -dist_salomescript_SCRIPTS=\ - envSalome.py \ - runIDLparser \ - runSalome.py \ - killSalome.py \ - killSalomeWithPort.py \ - runSalome \ - runSalome.csh \ - runNS.sh \ - createAppli.sh \ - appli_install.sh \ - appli_clean.sh \ - appli_gen.py \ - virtual_salome.py \ - config_appli.xml \ - launchConfigureParser.py \ - showNS.py \ - addToKillList.py \ - NSparam.py \ - setenv.py \ - launchSalome.py \ - nameserver.py \ - server.py \ - waitNS.sh \ - waitNS.py \ - waitContainers.py \ - shutdownSalome.py +dist_salomescript_SCRIPTS = \ + addToKillList.py \ + appli_clean.sh \ + appli_gen.py \ + appli_install.sh \ + createAppli.sh \ + envSalome.py \ + killSalome.py \ + killSalomeWithPort.py \ + launchConfigureParser.py \ + launchSalome.py \ + nameserver.py \ + NSparam.py \ + orbmodule.py \ + runIDLparser \ + runNS.py \ + runNS.sh \ + runSalome \ + runSalome.csh \ + runSalome.ksh \ + runSalome.py \ + salomeConsole.py \ + salome_session.py \ + salome_utilities.py \ + server.py \ + setenv.py \ + showNS.py \ + shutdownSalome.py \ + virtual_salome.py \ + waitContainers.py \ + waitNS.py \ + waitNS.sh EXTRA_DIST = appliskel @@ -74,21 +78,17 @@ dist-hook: DISTCLEANFILES = $(top_builddir)/bin/salome/Makefile.am -clean-local: - rm -rf $(top_builddir)/bin/salome/appliskel - cd $(top_builddir)/bin/salome; \ - rm -f $(dist_salomescript_DATA) $(dist_salomescript_SCRIPTS) - # This is an ugly target to avoid exploring the appliskel subdirectory. install-exec-local: $(INSTALL) -d $(DESTDIR)$(salomescriptdir) $(RM) -rf $(DESTDIR)$(salomescriptdir)/appliskel 1> /dev/null 2>&1 cp -r $(srcdir)/appliskel $(DESTDIR)$(salomescriptdir) + chmod a+x -R $(DESTDIR)$(salomescriptdir)/appliskel find $(DESTDIR)$(salomescriptdir) -name CVS -prune -exec rm -rf {} \; uninstall-local: if test -d $(DESTDIR)$(salomescriptdir)/appliskel; then \ find $(DESTDIR)$(salomescriptdir)/appliskel -exec chmod +w {} ';' ; \ - rm -rf $(DESTDIR)$(salomescriptdir)/appliskel; \ - fi; + rm -rf $(DESTDIR)$(salomescriptdir)/appliskel; \ + fi; diff --git a/bin/NSparam.py b/bin/NSparam.py index 652e6da66..2f93c9e54 100755 --- a/bin/NSparam.py +++ b/bin/NSparam.py @@ -20,7 +20,6 @@ # import sys,os -import string def getNSparams(info=""): """ @@ -32,25 +31,8 @@ def getNSparams(info=""): elif info==port print host else print 2 strings on stdout on one line: host port """ - my_port="" - my_host="" - if os.environ.has_key("OMNIORB_CONFIG"): - file = open(os.environ["OMNIORB_CONFIG"], "r") - s = file.readline() - while len(s): - l = string.split(s, ":") - if string.split(l[0], " ")[0] == "ORBInitRef" or \ - string.split(l[0], " ")[0] == "InitRef" : - my_port = l[len(l)-1] - if my_port[-1] == '\n': - my_port = my_port[:-1] - pass - my_host = l[len(l)-2] - break; - pass - s = file.readline() - pass - pass + from salome_utilities import getORBcfgInfo + my_version, my_host, my_port = getORBcfgInfo() if info=='host': # keep print, stdout used in shell print my_host @@ -80,9 +62,10 @@ if __name__ == "__main__": getNSparams('port') pass else: - getNSparams('') + getNSparams() pass pass else: - getNSparams('') + getNSparams() pass + pass diff --git a/bin/addToKillList.py b/bin/addToKillList.py index 537dfaf3d..548a8958d 100755 --- a/bin/addToKillList.py +++ b/bin/addToKillList.py @@ -25,78 +25,87 @@ from launchConfigureParser import verbose ########## adds to the kill list of SALOME one more process ########## def findFileDict(): - if os.environ.has_key('NSPORT'): - my_port = os.environ['NSPORT'] - pass - else: - my_port = 2809 - try: - file = open(os.environ["OMNIORB_CONFIG"], "r") - s = file.read() - while len(s): - l = string.split(s, ":") - if string.split(l[0], " ")[0] == "ORBInitRef" or string.split(l[0], " ")[0] == "InitRef" : - my_port = int(l[len(l)-1]) - pass - s = file.read() - pass - pass - except: - pass - pass - if verbose(): print "myport = ", my_port - return my_port + """ + Detect current SALOME session's port number. + Returns port number. + """ + from salome_utilities import getPortNumber + port = getPortNumber() + if verbose(): print "myport = ", port + return port -def addToKillList(command_pid, command): - my_port = findFileDict() +def addToKillList(command_pid, command, port=None): + """ + Add the process to the SALOME processes dictionary file. + Parameters: + - command_pid : command PID + - command : command (string or list of strings) + - [port] : SALOME port number; if this parameter is None (default), + it is detected automatically + """ + # retrieve current processes dictionary from killSalomeWithPort import getPiDict - filedict=getPiDict(my_port) + if port is None: port=findFileDict() + filedict=getPiDict(port) try: fpid=open(filedict, 'r') process_ids=pickle.load(fpid) fpid.close() except: - process_ids=[{}] + process_ids=[] pass - - already_in=0 + # check if PID is already in dictionary + already_in=False for process_id in process_ids: - if verbose(): print process_id for pid, cmd in process_id.items(): - #print "see process %s : %s"% (pid, cmd[0]) - if pid == command_pid: - already_in=1 - pass + if int(pid) == int(command_pid): + already_in=True + break pass + if already_in: break pass - - command=(command.split(" "))[0] - if already_in == 0: + # add process to the dictionary + if not already_in: + import types + if type(command) == types.ListType: command=" ".join([str(c) for c in command]) + command=command.split()[0] try: - process_ids.append({command_pid: [command]}) - fpid=open(filedict,'w') + if verbose(): print "addToKillList: %s : %s" % ( str(command_pid), command ) + process_ids.append({int(command_pid): [command]}) + dir = os.path.dirname(filedict) + if not os.path.exists(dir): os.makedirs(dir, 0777) + fpid = open(filedict,'w') pickle.dump(process_ids, fpid) fpid.close() except: - print "addToKillList: can not add command %s to the kill list"% filedict + if verbose(): print "addToKillList: can not add command %s : %s to the kill list" % ( str(command_pid), command ) pass pass pass -def killList(): - my_port = findFileDict() +def killList(port=None): + """ + Kill all the processes listed in the SALOME processes dictionary file. + - [port] : SALOME port number; if this parameter is None (default), + it is detected automatically + """ + # retrieve processes dictionary from killSalomeWithPort import getPiDict - filedict=getPiDict(my_port) + if port is None: port=findFileDict() + # new-style dot-prefixed pidict file + filedict=getPiDict(port, hidden=True) + # provide compatibility with old-style pidict file (not dot-prefixed) + if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False) try: fpid=open(filedict, 'r') process_ids=pickle.load(fpid) fpid.close() except: - process_ids=[{}] + process_ids=[] pass - + # kill processes for process_id in process_ids: - print process_id + #print process_id for pid, cmd in process_id.items(): print "stop process %s : %s"% (pid, cmd[0]) try: @@ -106,11 +115,11 @@ def killList(): pass pass pass + # remove processes dictionary file os.remove(filedict) pass - - if __name__ == "__main__": if verbose(): print sys.argv addToKillList(sys.argv[1], sys.argv[2]) + pass diff --git a/bin/envSalome.py b/bin/envSalome.py index 1d0d61cb6..ed153d41b 100755 --- a/bin/envSalome.py +++ b/bin/envSalome.py @@ -39,6 +39,6 @@ sys.argv = argv[1:] #args, modules_list, modules_root_dir = setenv.get_config() #runSalome.set_env(args, modules_list, modules_root_dir) -setenv.main(); +setenv.main(True); os.execvp(argv[0],argv) diff --git a/bin/killSalome.py b/bin/killSalome.py index 2f1388182..ed9164cf5 100755 --- a/bin/killSalome.py +++ b/bin/killSalome.py @@ -19,36 +19,54 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import os, string, sys, re +import os, sys, re, signal from killSalomeWithPort import killMyPort, getPiDict def killAllPorts(): + """ + Kill all SALOME sessions belonging to the user. + """ user = os.getenv('USER') - filedict = "^%s$"%(getPiDict('(\d*)',full=False)) - fnamere = re.compile(filedict) - for file in os.listdir(os.getenv("HOME")): - mo = re.match(fnamere,file) - if mo and len(mo.groups()): - killMyPort(mo.groups()[0]) + # new-style dot-prefixed pidict file + fpidict = getPiDict('(\d*)',hidden=True) + dirpidict = os.path.dirname(fpidict) + fpidict = os.path.basename(fpidict) + fnamere = re.compile("^%s$" % fpidict) + for f in os.listdir(dirpidict): + mo = fnamere.match(f) + try: + killMyPort(mo.group(1)) + except: + pass pass - - if not sys.platform == 'win32': - cmd = "pid=`ps -fea | grep '"+os.getenv('USER')+"' | grep 'ghs3d' | grep 'f /tmp/GHS3D_' | grep -v 'grep' | awk '{print $2}'` ; echo $pid > /tmp/logs/"+os.getenv('USER')+"/_"+"Pid_ghs3d.log" - a = os.system(cmd) + # provide compatibility with old-style pidict file (not dot-prefixed) + fpidict = getPiDict('(\d*)',hidden=False) + dirpidict = os.path.dirname(fpidict) + fpidict = os.path.basename(fpidict) + fnamere = re.compile("^%s$" % fpidict) + for f in os.listdir(dirpidict): + mo = fnamere.match(f) try: - fpidomniNames=open('/tmp/logs/'+os.getenv('USER')+"/_"+"Pid_ghs3d.log") - prc = fpidomniNames.read() - fpidomniNames.close() - if prc != None : - for field in prc.split(" ") : - field = field.strip() - if field != None and len(field) != 0: - os.system('kill -9 '+field) - except: + killMyPort(mo.group(1)) + except: + pass + pass + # kill other processes + if sys.platform != 'win32': + import commands + cmd = "ps -fea | grep '%s' | grep 'ghs3d' | grep 'f /tmp/GHS3D_' | grep -v 'grep' | awk '{print $2}'" % user + prc = commands.getoutput(cmd) + for field in prc.split(): + try: + os.kill(int(field), signal.SIGKILL) + except: + pass pass pass + pass if __name__ == "__main__": killAllPorts() + pass diff --git a/bin/killSalomeWithPort.py b/bin/killSalomeWithPort.py index 79c168279..2308505a0 100755 --- a/bin/killSalomeWithPort.py +++ b/bin/killSalomeWithPort.py @@ -22,47 +22,69 @@ import os, sys, pickle, signal, commands from launchConfigureParser import verbose -def getPiDict(port,appname='salome',full=True): - from Utils_Identity import getShortHostName - - # get hostname by special function in all cases to - # have always same result in lower case at win32 - host = getShortHostName() - if not host: - host = os.getenv("HOSTNAME") - if not host: - host = os.getenv("HOST") - - filedict = [] - filedict.append( os.getenv('USER') ) # user name - filedict.append( host ) # host name - filedict.append( str(port) ) # port number - filedict.append( appname.upper() ) # application name - filedict.append( 'pidict' ) # constant part +def getPiDict(port,appname='salome',full=True,hidden=True): + """ + Get file with list of SALOME processes. + This file is located in the user's home directory + and named .___SALOME_pidict + where + is user name + is host name + is port number - filedict = '_'.join(filedict) + Parameters: + - port : port number + - appname : application name (default is 'SALOME') + - full : if True, full path to the file is returned, otherwise only file name is returned + - hidden : if True, file name is prefixed with . (dot) symbol; this internal parameter is used + to support compatibility with older versions of SALOME + """ + from salome_utilities import generateFileName, getTmpDir + dir = "" if full: - filedict = os.getenv("HOME") + '/' + filedict - return filedict + # full path to the pidict file is requested + if hidden: + # new-style dot-prefixed pidict files + # are in the system-dependant temporary diretory + dir = getTmpDir() + else: + # old-style non-dot-prefixed pidict files + # are in the user's home directory + dir = os.getenv("HOME") + pass + pass + return generateFileName(dir, + suffix="pidict", + hidden=hidden, + with_username=True, + with_hostname=True, + with_port=port, + with_app=appname.upper()) def appliCleanOmniOrbConfig(port): """ - remove omniorb config files related to the port in SALOME application: + Remove omniorb config files related to the port in SALOME application: - ${HOME}/${APPLI}/.omniORB_${HOSTNAME}_${NSPORT}.cfg - ${HOME}/${APPLI}/.omniORB_last.cfg the last is removed only if the link points to the first file. """ - from Utils_Identity import getShortHostName - appli=os.environ.get("APPLI") + from salome_utilities import generateFileName + home = os.getenv("HOME") + appli = os.getenv("APPLI") if appli is None: #Run outside application context pass else: - home = os.environ['HOME'] - home='%s/%s'%(home,appli) - hostname=getShortHostName() - omniorb_config = '%s/.omniORB_%s_%s.cfg'%(home,hostname, str(port)) - last_running_config = '%s/.omniORB_last.cfg'%(home) + dir = os.path.join(home, appli) + omniorb_config = generateFileName(dir, prefix="omniORB", + extension="cfg", + hidden=True, + with_hostname=True, + with_port=port) + last_running_config = generateFileName(dir, prefix="omniORB", + suffix="last", + extension="cfg", + hidden=True) if os.access(last_running_config,os.F_OK): pointedPath = os.readlink(last_running_config) if pointedPath[0] != '/': @@ -75,77 +97,100 @@ def appliCleanOmniOrbConfig(port): os.remove(omniorb_config) pass pass + pass ########## kills all salome processes with the given port ########## def killMyPort(port): - filedict=getPiDict(port) - found = 0 + """ + Kill SALOME session running on the specified port. + Parameters: + - port - port number + """ + # new-style dot-prefixed pidict file + filedict = getPiDict(port, hidden=True) + # provide compatibility with old-style pidict file (not dot-prefixed) + if not os.path.exists(filedict): filedict = getPiDict(port, hidden=False) + # try: - fpid=open(filedict, 'r') - found = 1 - except: - print "file %s giving SALOME process id is not readable"% filedict - pass - - if found: + fpid = open(filedict, 'r') + # + from salome_utilities import generateFileName + fpidomniNames = generateFileName(os.path.join('/tmp/logs', os.getenv('USER')), + prefix="", + suffix="Pid_omniNames", + extension="log", + with_port=port) if not sys.platform == 'win32': - cmd = 'pid=`ps -eo pid,command | egrep "[0-9] omniNames -start '+str(port)+'"` ; echo $pid > /tmp/logs/'+os.getenv('USER')+"/_"+port+'_Pid_omniNames.log' + cmd = 'pid=`ps -eo pid,command | egrep "[0-9] omniNames -start %s"` ; echo $pid > %s' % ( str(port), fpidomniNames ) a = os.system(cmd) + pass try: - fpidomniNames=open('/tmp/logs/'+os.getenv('USER')+"/_"+port+'_Pid_omniNames.log') - prc = fpidomniNames.read() - fpidomniNames.close() - if prc != None : - for field in prc.split(" ") : - if field == "omniNames" : - if pidfield != "egrep" : - if sys.platform == "win32": - import win32pm - print 'stop process '+pidfield+' : omniNames' - win32pm.killpid(int(pidfield),0) - else: - if verbose(): print 'stop process '+pidfield+' : omniNames' - os.system('kill -9 '+pidfield) - pidfield = field + fpidomniNamesFile = open(fpidomniNames) + lines = fpidomniNamesFile.readlines() + fpidomniNamesFile.close() + os.remove(fpidomniNames) + for l in lines: + try: + pidfield = l.split()[0] # pid should be at the first position + if sys.platform == "win32": + import win32pm + if verbose(): print 'stop process '+pidfield+' : omniNames' + win32pm.killpid(int(pidfield),0) + else: + if verbose(): print 'stop process '+pidfield+' : omniNames' + os.kill(int(pidfield),signal.SIGKILL) + pass + pass + except: + pass + pass + pass except: pass - + # try: process_ids=pickle.load(fpid) fpid.close() for process_id in process_ids: - for pid, cmd in process_id.items(): if verbose(): print "stop process %s : %s"% (pid, cmd[0]) try: if sys.platform == "win32": - import win32pm - win32pm.killpid(int(pid),0) + import win32pm + win32pm.killpid(int(pid),0) else: - os.kill(int(pid),signal.SIGKILL) + os.kill(int(pid),signal.SIGKILL) + pass + pass except: if verbose(): print " ------------------ process %s : %s not found"% (pid, cmd[0]) pass - pass + pass # for pid, cmd ... + pass # for process_id ... + pass # try... except: pass - + # os.remove(filedict) cmd='ps -eo pid,command | egrep "[0-9] omniNames -start '+str(port)+'" | sed -e "s%[^0-9]*\([0-9]*\) .*%\\1%g"' pid = commands.getoutput(cmd) a = "" - while pid != "" and len(a.split(" ")) < 2: - a = commands.getoutput("pid=`ps -eo pid,command | egrep \"[0-9] omniNames -start "+str(port)+"\" | sed -e \"s%[^0-9]*\([0-9]*\) .*%\\1%g\"`; kill -9 $pid") - pid = commands.getoutput("ps -eo pid,command | egrep \"[0-9] omniNames -start "+str(port)+"\" | sed -e \"s%[^0-9]*\([0-9]*\) .*%\\1%g\"") - print pid - + while pid and len(a.split()) < 2: + a = commands.getoutput("kill -9 " + pid) + pid = commands.getoutput(cmd) + #print pid + pass pass - + except: + print "Cannot find or open SALOME PIDs file for port", port + pass + # appliCleanOmniOrbConfig(port) pass - if __name__ == "__main__": for port in sys.argv[1:]: killMyPort(port) + pass + pass diff --git a/bin/launchConfigureParser.py b/bin/launchConfigureParser.py index 399c40ef7..74b3cd0a1 100755 --- a/bin/launchConfigureParser.py +++ b/bin/launchConfigureParser.py @@ -701,9 +701,16 @@ def get_env(theAdditionalOptions=[], appname="SalomeApp"): dirs += re.split(';', os.getenv(config_var)) else: dirs += re.split('[;|:]', os.getenv(config_var)) - + + gui_available = True if os.getenv("GUI_ROOT_DIR") and os.path.isdir( os.getenv("GUI_ROOT_DIR") + "/share/salome/resources/gui" ): dirs += [os.getenv("GUI_ROOT_DIR") + "/share/salome/resources/gui"] + pass + else: + gui_available = False + if os.getenv("KERNEL_ROOT_DIR") and os.path.isdir( os.getenv("KERNEL_ROOT_DIR") + "/bin/salome/appliskel" ): + dirs += [os.getenv("KERNEL_ROOT_DIR") + "/bin/salome/appliskel"] + pass os.environ[config_var] = separator.join(dirs) dirs.reverse() # reverse order, like in "path" variable - FILO-style processing @@ -800,6 +807,10 @@ def get_env(theAdditionalOptions=[], appname="SalomeApp"): args[gui_nam] = cmd_opts.gui if cmd_opts.batch is not None: args[batch_nam] = True + + if not gui_available: + args[gui_nam] = False + if args[gui_nam]: args["session_gui"] = True if cmd_opts.desktop is not None: diff --git a/bin/nameserver.py b/bin/nameserver.py index dd03c51a3..99ec4c3b2 100755 --- a/bin/nameserver.py +++ b/bin/nameserver.py @@ -4,6 +4,7 @@ import sys, os, re, socket #import commands from server import * from Utils_Identity import getShortHostName +from launchConfigureParser import verbose # ----------------------------------------------------------------------------- @@ -45,12 +46,12 @@ class NamingServer(Server): #os.system("touch " + upath + "/dummy") for fname in os.listdir(upath): try: - os.remove(upath + "/" + fname) + if not fname.startswith("."): os.remove(upath + "/" + fname) except: pass #os.system("rm -f " + upath + "/omninames* " + upath + "/dummy " + upath + "/*.log") - print "Name Service... ", + if verbose(): print "Name Service... ", #hname=os.environ["HOST"] #commands.getoutput("hostname") if sys.platform == "win32": hname=getShortHostName(); @@ -60,7 +61,7 @@ class NamingServer(Server): f=open(os.environ["OMNIORB_CONFIG"]) ss=re.findall("NameService=corbaname::" + hname + ":\d+", f.read()) - print "ss = ", ss, + if verbose(): print "ss = ", ss, f.close() sl=ss[0] ll = sl.split(':') @@ -74,15 +75,15 @@ class NamingServer(Server): #print "port=", aPort if sys.platform == "win32": #print "start omniNames -start " + aPort + " -logdir " + upath - self.CMD=['omniNames -start ' , aPort , ' -logdir ' , '\"' + upath + '\"'] + self.CMD=['omniNames -start ' , aPort , ' -logdir ' , '\"' + upath + '\"', ' -errlog', upath+'/omniNameErrors.log'] #os.system("start omniNames -start " + aPort + " -logdir " + upath) else: #self.CMD=['omniNames -start ' , aPort , ' -logdir ' , upath , ' &'] - self.CMD=['omniNames','-start' , aPort, '-logdir' , upath ] + self.CMD=['omniNames','-start' , aPort, '-logdir' , upath, '-errlog', upath+'/omniNameErrors.log'] #os.system("omniNames -start " + aPort + " -logdir " + upath + " &") - print "... ok" - print "to list contexts and objects bound into the context with the specified name : showNS " + if verbose(): print "... ok" + if verbose(): print "to list contexts and objects bound into the context with the specified name : showNS " def initArgs(self): diff --git a/bin/orbmodule.py b/bin/orbmodule.py index 9f3c66324..ffb211fab 100755 --- a/bin/orbmodule.py +++ b/bin/orbmodule.py @@ -20,6 +20,7 @@ import sys,os,time import string from nameserver import * from omniORB import CORBA +from launchConfigureParser import verbose # Import the stubs for the Naming service import CosNaming @@ -47,7 +48,7 @@ class client: return except (CORBA.TRANSIENT,CORBA.OBJECT_NOT_EXIST,CORBA.COMM_FAILURE): self.rootContext = None - print "Launch Naming Service++", + if verbose(): print "Launch Naming Service++", # On lance le Naming Server (doit etre dans le PATH) NamingServer(args).run() diff --git a/bin/runNS.py b/bin/runNS.py index 444760369..601c7b00d 100755 --- a/bin/runNS.py +++ b/bin/runNS.py @@ -39,7 +39,7 @@ def startOmni(): #os.system("touch " + upath + "/dummy") for fname in os.listdir(upath): try: - os.remove(upath + "/" + fname) + if not fname.startswith("."): os.remove(upath + "/" + fname) except: pass #os.system("rm -f " + upath + "/omninames* " + upath + "/dummy " + upath + "/*.log") diff --git a/bin/runSalome.py b/bin/runSalome.py index f20b50794..2a8aa66b1 100755 --- a/bin/runSalome.py +++ b/bin/runSalome.py @@ -19,7 +19,7 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import sys, os, string, glob, time, pickle +import sys, os, string, glob, time, pickle, re import orbmodule import setenv from server import * @@ -204,10 +204,22 @@ class LoggerServer(Server): def __init__(self,args): self.args=args self.initArgs() - if sys.platform == "win32": - self.CMD=['SALOME_Logger_Server', os.environ["HOME"] + "/logger.log"]; - else: - self.CMD=['SALOME_Logger_Server', 'logger.log'] + from salome_utilities import generateFileName + if sys.platform == "win32": dirpath = os.environ["HOME"] + else: dirpath = "/tmp" + logfile = generateFileName( dirpath, + prefix="logger", + extension="log", + with_username=True, + with_hostname=True, + with_port=True) + print "===========================================================" + print "Logger server: put log to the file:" + print logfile + print "===========================================================" + self.CMD=['SALOME_Logger_Server', logfile] + pass + pass # end of LoggerServer class # --- @@ -418,10 +430,8 @@ def startSalome(args, modules_list, modules_root_dir): # Notify Server launch # - if verbose(): print "Notify Server to launch" - if sys.platform != "win32": - print "Notify Server to launch" + if verbose(): print "Notify Server to launch" myServer=NotifyServer(args,modules_root_dir) myServer.run() @@ -597,6 +607,7 @@ def startSalome(args, modules_list, modules_root_dir): # set PYTHONINSPECT variable if args['pinter']: os.environ["PYTHONINSPECT"]="1" + import readline return clt @@ -622,22 +633,14 @@ def useSalome(args, modules_list, modules_root_dir): #print process_id + from addToKillList import addToKillList from killSalomeWithPort import getPiDict - filedict = getPiDict(args['port']) - process_ids = [] - try: - fpid=open(filedict, 'r') - process_ids=pickle.load(fpid) - fpid.close() - except: + filedict = getPiDict(args['port']) + for pid, cmd in process_id.items(): + addToKillList(pid, cmd, args['port']) pass - - fpid=open(filedict, 'w') - process_ids.append(process_id) - pickle.dump(process_ids,fpid) - fpid.close() - + if verbose(): print """ Saving of the dictionary of Salome processes in %s To kill SALOME processes from a console (kill all sessions from all ports): @@ -713,89 +716,89 @@ def registerEnv(args, modules_list, modules_root_dir): def searchFreePort(args, save_config=1): print "Searching for a free port for naming service:", + # + if sys.platform == "win32": + tmp_file = os.getenv('TEMP'); + else: + tmp_file = '/tmp' + tmp_file = os.path.join(tmp_file, '.netstat_%s'%os.getpid()) + # + ###status = os.system("netstat -ltn | grep -E :%s > /dev/null 2>&1"%(NSPORT)) + os.system( "netstat -a -n > %s" % tmp_file ); + f = open( tmp_file, 'r' ); + ports = f.readlines(); + f.close(); + os.remove( tmp_file ); + # + def portIsUsed(port, data): + regObj = re.compile( "tcp.*:([0-9]+).*:.*listen", re.IGNORECASE ); + for item in data: + try: + p = int(regObj.match(item).group(1)) + if p == port: return True + pass + except: + pass + pass + return False + # NSPORT=2810 - limit=NSPORT - limit=limit+10 + limit=NSPORT+100 + # while 1: - import os - import re - from os import getpid - from os import system - - if sys.platform == "win32": - tmp_file = os.getenv('TEMP'); - else: - tmp_file = '/tmp/' - tmp_file += 'hostname_%s'%(getpid()) - -# status = os.system("netstat -ltn | grep -E :%s > /dev/null 2>&1"%(NSPORT)) - - system( "netstat -a -n > %s" % tmp_file ); - - f = open( tmp_file, 'r' ); - lines = f.readlines(); - f.close(); - - pattern = "tcp.*:([0-9]+).*:.*listen"; - regObj = re.compile( pattern, re.IGNORECASE ); - - status = 1; - for item in lines: - m = regObj.search( item ) - if m: - try: - p = int( m.group(1) ) - if p == NSPORT: - status = 0; - break; - except: - pass - pass - - if status == 1: + if not portIsUsed(NSPORT, ports): print "%s - OK"%(NSPORT) # - system('hostname > %s'%(tmp_file)) - f = open(tmp_file) - myhost = f.read() - myhost = myhost[:-1] - f.close() - - os.remove( tmp_file ); - + from salome_utilities import generateFileName, getHostName + hostname = getHostName() # - home = os.environ['HOME'] - appli=os.environ.get("APPLI") - if appli is not None: - home='%s/%s'%(home,appli) - pass + home = os.getenv("HOME") + appli = os.getenv("APPLI") + if appli is not None: home = os.path.join(home, appli) # - os.environ['OMNIORB_CONFIG'] = '%s/.omniORB_%s_%s.cfg'%(home, myhost, NSPORT) - initref = "NameService=corbaname::%s:%s"%(myhost, NSPORT) - os.environ['NSPORT'] = "%s"%(NSPORT) - os.environ['NSHOST'] = "%s"%(myhost) - f = open(os.environ['OMNIORB_CONFIG'], "w") + omniorb_config = generateFileName(home, prefix="omniORB", + extension="cfg", + hidden=True, + with_hostname=True, + with_port=NSPORT) + orbdata = [] + initref = "NameService=corbaname::%s:%s"%(hostname, NSPORT) import CORBA if CORBA.ORB_ID == "omniORB4": - initref += "\ngiopMaxMsgSize = 2097152000 # 2 GBytes"; - initref += "\ntraceLevel = 0 # critical errors only"; - f.write("InitRef = %s\n"%(initref)) + orbdata.append("InitRef = %s"%(initref)) + orbdata.append("giopMaxMsgSize = 2097152000 # 2 GBytes") + orbdata.append("traceLevel = 0 # critical errors only") else: - initref += "\nORBgiopMaxMsgSize = 2097152000 # 2 GBytes"; - initref += "\nORBtraceLevel = 0 # critical errors only"; - f.write("ORBInitRef %s\n"%(initref)) + orbdata.append("ORBInitRef %s"%(initref)) + orbdata.append("ORBgiopMaxMsgSize = 2097152000 # 2 GBytes") + orbdata.append("ORBtraceLevel = 0 # critical errors only") pass + orbdata.append("") + f = open(omniorb_config, "w") + f.write("\n".join(orbdata)) f.close() + # + os.environ['OMNIORB_CONFIG'] = omniorb_config + os.environ['NSPORT'] = "%s"%(NSPORT) + os.environ['NSHOST'] = "%s"%(hostname) args['port'] = os.environ['NSPORT'] # if save_config: - from os import system - if sys.platform == "win32": - import shutil - shutil.copyfile( os.environ['OMNIORB_CONFIG'], "%s/.omniORB_last.cfg"%( home ) ) - else: - system('ln -s -f %s %s/.omniORB_last.cfg'%(os.environ['OMNIORB_CONFIG'], home)) - pass + last_running_config = generateFileName(home, prefix="omniORB", + suffix="last", + extension="cfg", + hidden=True) + try: + if sys.platform == "win32": + import shutil + shutil.copyfile(omniorb_config, last_running_config) + else: + os.remove(last_running_config) + os.symlink(omniorb_config, last_running_config) + pass + pass + except: + pass break print "%s"%(NSPORT), if NSPORT == limit: @@ -825,14 +828,16 @@ def no_main(): def main(): """Salome launch as a main application""" import sys - print "runSalome running on ",os.getenv('HOSTNAME') + from salome_utilities import getHostName + print "runSalome running on %s" % getHostName() args, modules_list, modules_root_dir = setenv.get_config() kill_salome(args) save_config = True if args.has_key('save_config'): save_config = args['save_config'] searchFreePort(args, save_config) - setenv.main() + #setenv.main() + setenv.set_env(args, modules_list, modules_root_dir) clt = useSalome(args, modules_list, modules_root_dir) return clt,args diff --git a/bin/salome_session.py b/bin/salome_session.py index 870b53bc4..64e13c951 100644 --- a/bin/salome_session.py +++ b/bin/salome_session.py @@ -39,48 +39,55 @@ def getShortHostName(): socket.gethostname() gives short or complete Hostname, depending on defined aliases. """ - return string.split(socket.gethostname(),'.')[0] + from salome_utilities import getShortHostName + return getShortHostName() def searchFreePort(): + """ + Search free port for SALOME session. + Returns first found free port number. + """ print "Searching a free port for naming service:", - NSPORT=2810 - limit=NSPORT - limit=limit+100 + from salome_utilities import generateFileName, getHostName + hostname = getHostName() + NSPORT = 2810 + limit = NSPORT+100 while 1: print "%s "%(NSPORT), status = os.system("netstat -ltn | grep -E :%s"%(NSPORT)) if status: - home = os.environ['HOME'] - appli=os.environ.get("APPLI") - if appli is None: - #Run outside application context - home=home - else: - home='%s/%s'%(home,appli) - hostname=getShortHostName() - omniorb_config = '%s/.omniORB_%s_%s.cfg'%(home,hostname, NSPORT) - os.environ['OMNIORB_CONFIG'] = omniorb_config + home = os.getenv("HOME") + appli = os.getenv("APPLI") + if appli is not None: home = os.path.join(home, appli) + omniorb_config = generateFileName(home, prefix="omniORB", + extension="cfg", + hidden=True, + with_hostname=True, + with_port=NSPORT) f = open(omniorb_config, "w") f.write("ORBInitRef NameService=corbaname::%s:%s\n"%(hostname, NSPORT)) f.close() - last_running_config = '%s/.omniORB_last.cfg'%(home, hostname) + os.environ['OMNIORB_CONFIG'] = omniorb_config + last_running_config = generateFileName(home, prefix="omniORB", + suffix="last", + extension="cfg", + hidden=True) os.environ['LAST_RUNNING_CONFIG'] = last_running_config if os.access(last_running_config,os.F_OK): os.unlink(last_running_config) pass os.symlink(omniorb_config,last_running_config) - # LAST_RUNNING_CONFIG=${HOME}/${APPLI}/.omniORB_${myhost}_last.cfg print "- Ok" break if NSPORT == limit: msg = "" - msg += "I Can't find a free port to launch omniNames\n" - msg += "I suggest you to kill the running servers and try again.\n" + msg += "Can not find a free port to launch omniNames\n" + msg += "Kill the running servers and try again.\n" raise msg - NSPORT=NSPORT+1 + NSPORT = NSPORT+1 pass - os.environ['NSHOST']=hostname - os.environ['NSPORT']=str(NSPORT) + os.environ['NSHOST'] = hostname + os.environ['NSPORT'] = str(NSPORT) return NSPORT diff --git a/bin/salome_utilities.py b/bin/salome_utilities.py new file mode 100644 index 000000000..b4349cd20 --- /dev/null +++ b/bin/salome_utilities.py @@ -0,0 +1,346 @@ +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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 : salome_utilities.py +# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +# +# --- + +""" +Set of utility functions used by SALOME python scripts. +""" + +# +# Exported functions +# +__all__ = [ + 'getORBcfgInfo', + 'getHostFromORBcfg', + 'getPortFromORBcfg', + 'getUserName', + 'getHostName', + 'getShortHostName', + 'getAppName', + 'getPortNumber', + 'getTmpDir', + 'generateFileName', + ] + +# --- + +def _try_bool( arg ): + """ + Check if specified parameter represents boolean value and returns its value. + String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc + are supported. + If does not represent a boolean, an exception is raised. + """ + import types + if type( arg ) == types.BooleanType : + return arg + elif type( arg ) == types.StringType : + v = str( arg ).lower() + if v in [ "yes", "y", "true" ]: return True + elif v in [ "no", "n", "false" ]: return False + pass + raise Exception("Not boolean value") + +# --- + +def getORBcfgInfo(): + """ + Get omniORB current configuration. + Returns a list of three values: [ orb_version, host_name, port_number ]. + + The information is retrieved from the omniORB configuration file defined + by the OMNIORB_CONFIG environment variable. + If omniORB configuration file can not be accessed, a list of three empty + strings is returned. + """ + import os, re + ret = [ "", "", "" ] + try: + f = open( os.getenv( "OMNIORB_CONFIG" ) ) + lines = f.readlines() + f.close() + regvar = re.compile( "(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$" ) + for l in lines: + try: + m = regvar.match( l ) + if m: + if m.group(1) is None: + ret[0] = "4" + else: + ret[0] = "3" + pass + ret[1] = m.group(2) + ret[2] = m.group(3) + break + pass + except: + pass + pass + pass + except: + pass + return ret + +# --- + +def getHostFromORBcfg(): + """ + Get current omniORB host. + """ + return getORBcfgInfo()[1] +# --- + +def getPortFromORBcfg(): + """ + Get current omniORB port. + """ + return getORBcfgInfo()[2] + +# --- + +def getUserName(): + """ + Get user name: + 1. try USER environment variable + 2. if fails, return 'unknown' as default user name + """ + import os + return os.getenv( "USER", "unknown" ) # 'unknown' is default user name + +# --- + +def getHostName(): + """ + Get host name: + 1. try socket python module gethostname() function + 2. if fails, try HOSTNAME environment variable + 3. if fails, try HOST environment variable + 4. if fails, return 'unknown' as default host name + """ + import os + try: + import socket + host = socket.gethostname() + except: + host = None + pass + if not host: host = os.getenv("HOSTNAME") + if not host: host = os.getenv("HOST") + if not host: host = "unknown" # 'unknown' is default host name + return host + +# --- + +def getShortHostName(): + """ + Get short host name: + 1. try socket python module gethostname() function + 2. if fails, try HOSTNAME environment variable + 3. if fails, try HOST environment variable + 4. if fails, return 'unknown' as default host name + """ + try: + return getHostName().split('.')[0] + except: + pass + return "unknown" # 'unknown' is default host name + +# --- + +def getAppName(): + """ + Get application name: + 1. try APPNAME environment variable + 2. if fails, return 'SALOME' as default application name + """ + import os + return os.getenv( "APPNAME", "SALOME" ) # 'SALOME' is default user name + +# --- + +def getPortNumber(): + """ + Get current naming server port number: + 1. try NSPORT environment variable + 1. if fails, try to parse config file defined by OMNIORB_CONFIG environment variable + 2. if fails, return 2809 as default port number + """ + import os + try: + return int( os.getenv( "NSPORT" ) ) + except: + pass + port = getPortFromORBcfg() + if port is not None: return port + return 2809 # '2809' is default port number + +# --- + +def getTmpDir(): + """ + Get directory to be used for the temporary files. + """ + import os, sys + if sys.platform == "win32": + # for Windows: temporarily using home directory for tmp files; + # to be replaced with TEMP environment variable later... + dir = os.getenv("HOME") + else: + # for Linux: use /tmp/logs/{user} folder + dir = os.path.join( '/tmp', 'logs', getUserName() ) + pass + return dir + +# --- + +def generateFileName( dir, prefix = None, suffix = None, extension = None, + unique = False, separator = "_", hidden = False, **kwargs ): + """ + Generate file name by sepecified parameters. If necessary, file name + can be generated to be unique. + + Parameters: + - dir : directory path + - prefix : file prefix (not added by default) + - suffix : file suffix (not added by default) + - extension : file extension (not added by default) + - unique : if this parameter is True, the unique file name is generated: + in this case, if the file with the generated name already exists + in the directory, an integer suffix is added to the end of the + file name. This parameter is False by default. + - separator : separator of the words ('_' by default) + - hidden : if this parameter is True, the file name is prepended by . (dot) + symbol. This parameter is False by default. + + Other keyword parameters are: + - with_username : 'add user name' flag/option: + * boolean value can be passed to determine user name automatically + * string value to be used as user name + - with_hostname : 'add host name' flag/option: + * boolean value can be passed to determine host name automatically + * string value to be used as host name + - with_port : 'add port number' flag/option: + * boolean value can be passed to determine port number automatically + * string value to be used as port number + - with_app : 'add application name' flag/option: + * boolean value can be passed to determine application name automatically + * string value to be used as application name + All parameters are optional. + """ + supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ] + from launchConfigureParser import verbose + filename = [] + # separator + if separator is None: + separator = "" + pass + else: + separator = str( separator ) + pass + # prefix (if specified) + if prefix is not None: + filename.append( str( prefix ) ) + pass + # additional keywords + ### check unsupported parameters + for kw in kwargs: + if kw not in supported and verbose(): + print 'Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw + pass + pass + ### process supported keywords + for kw in supported: + if kw not in kwargs: continue + ### user name + if kw == 'with_username': + try: + # auto user name ? + if _try_bool( kwargs[kw] ): filename.append( getUserName() ) + pass + except: + # user name given as parameter + filename.append( kwargs[kw] ) + pass + pass + ### host name + elif kw == 'with_hostname': + try: + # auto host name ? + if _try_bool( kwargs[kw] ): filename.append( getShortHostName() ) + pass + except: + # host name given as parameter + filename.append( kwargs[kw] ) + pass + pass + ### port number + elif kw == 'with_port': + try: + # auto port number ? + if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) ) + pass + except: + # port number given as parameter + filename.append( str( kwargs[kw] ) ) + pass + pass + ### application name + elif kw == 'with_app': + try: + # auto application name ? + if _try_bool( kwargs[kw] ): filename.append( getAppName() ) + pass + except: + # application name given as parameter + filename.append( kwargs[kw] ) + pass + pass + pass + # suffix (if specified) + if suffix is not None: + filename.append( str( suffix ) ) + pass + # raise an exception if file name is empty + if not filename: + raise Exception("Empty file name") + # + if extension is not None and extension.startswith("."): extension = extension[1:] + # + import os + name = separator.join( filename ) + if hidden: name = "." + name # add dot for hidden files + if extension: name = name + "." + str( extension ) # add extension if defined + name = os.path.join( dir, name ) + if unique: + # create unique file name + index = 0 + while os.path.exists( name ): + index = index + 1 + name = separator.join( filename ) + separator + str( index ) + if hidden: name = "." + name # add dot for hidden files + if extension: name = name + "." + str( extension ) # add extension if defined + name = os.path.join( dir, name ) + pass + pass + return name diff --git a/bin/setenv.py b/bin/setenv.py index 86a4803ba..4d06f3885 100755 --- a/bin/setenv.py +++ b/bin/setenv.py @@ -75,7 +75,7 @@ def get_lib_dir(): # ----------------------------------------------------------------------------- -def get_config(): +def get_config(silent=False): """ Get list of modules, paths. @@ -116,12 +116,14 @@ def get_config(): for module in modules_list : module_variable=module+"_ROOT_DIR" if not os.environ.has_key(module_variable): - print "*******************************************************" - print "*" - print "* Environment variable",module_variable,"must be set" - print "* Module", module, "will be not available" - print "*" - print "********************************************************" + if not silent: + print "*******************************************************" + print "*" + print "* Environment variable",module_variable,"must be set" + print "* Module", module, "will be not available" + print "*" + print "********************************************************" + pass to_remove_list.append(module) continue pass @@ -147,7 +149,7 @@ def get_config(): # ----------------------------------------------------------------------------- -def set_env(args, modules_list, modules_root_dir): +def set_env(args, modules_list, modules_root_dir, silent=False): """Add to the PATH-variables modules specific paths""" python_version="python%d.%d" % sys.version_info[0:2] @@ -261,7 +263,7 @@ def set_env(args, modules_list, modules_root_dir): salome_subdir,"resources","kernel") if "GEOM" in modules_list: - if verbose(): print "GEOM OCAF Resources" + if verbose() and not silent: print "GEOM OCAF Resources" # set CSF_PluginDefaults variable only if it is not customized # by the user @@ -273,16 +275,16 @@ def set_env(args, modules_list, modules_root_dir): os.environ["CSF_GEOMDS_ResourcesDefaults"] \ = os.path.join(modules_root_dir["GEOM"],"share", salome_subdir,"resources","geom") - if verbose(): print "GEOM Shape Healing Resources" + if verbose() and not silent: print "GEOM Shape Healing Resources" os.environ["CSF_ShHealingDefaults"] \ = os.path.join(modules_root_dir["GEOM"],"share", salome_subdir,"resources","geom") # ----------------------------------------------------------------------------- -def main(): - args, modules_list, modules_root_dir = get_config() - set_env(args, modules_list, modules_root_dir) +def main(silent=False): + args, modules_list, modules_root_dir = get_config(silent=silent) + set_env(args, modules_list, modules_root_dir, silent=silent) return args # ----------------------------------------------------------------------------- diff --git a/bin/shutdownSalome.py b/bin/shutdownSalome.py index 491266662..9f9cd6d80 100755 --- a/bin/shutdownSalome.py +++ b/bin/shutdownSalome.py @@ -1,5 +1,8 @@ #!/usr/bin/env python +import time import salome salome.salome_init() salome.lcc.shutdownServers() -salome.SALOME_LifeCycleCORBA_killOmniNames() +#give some time to shutdown to complete +time.sleep(1) +salome.LifeCycleCORBA.killOmniNames() diff --git a/configure.ac b/configure.ac index e487aa532..ce460dfa2 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ # ================================================================ # #AC_PREREQ(2.59) -AC_INIT([Salome2 Project], [4.1.2], [paul.rascle@edf.fr], [SalomeKer]) +AC_INIT([Salome2 Project], [4.1.3], [paul.rascle@edf.fr], [SalomeKer]) # AC_CONFIG_AUX_DIR defines an alternative directory where to find the auxiliary # scripts such as config.guess, install-sh, ... @@ -14,7 +14,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([tar-pax]) #AC_CONFIG_HEADER([config.h]) -XVERSION=0x040102 +XVERSION=0x040103 AC_SUBST(XVERSION) # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.) @@ -475,39 +475,12 @@ else AC_SUBST(SETX) SETX="set -x" fi -echo -echo --------------------------------------------- -echo copying resource files, shell scripts, and -echo xml files -echo --------------------------------------------- -echo - - -mkdir -p bin/salome -cd bin/salome -for i in `find $ROOT_SRCDIR/bin` -do - local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR/bin,.,"` - case "$local_bin" in - *.in | *~) ;; - . | */CVS | */CVS/* | ./salome) ;; - ./appliskel |./appliskel/env.d) $INSTALL -d $local_bin ; echo $local_bin ;; - *) $INSTALL $i $local_bin; echo $local_bin ;; - esac -done -cd $ROOT_BUILDDIR - echo echo --------------------------------------------- echo generating Makefiles and configure files echo --------------------------------------------- echo -AC_OUTPUT_COMMANDS([ \ - chmod +x ./bin/*; \ - chmod +x ./bin/salome/* \ -]) - # This list is initiated using autoscan and must be updated manually # when adding a new file .in to manage. When you execute # autoscan, the Makefile list is generated in the output file configure.scan. diff --git a/idl/SALOME_ModuleCatalog.idl b/idl/SALOME_ModuleCatalog.idl index dfc8764f6..9231f7e39 100644 --- a/idl/SALOME_ModuleCatalog.idl +++ b/idl/SALOME_ModuleCatalog.idl @@ -171,7 +171,8 @@ Implementation type enum ImplType { SO, /* component implemented as a dynamic library loadable with dlopen */ PY, /* component implemented as a python module loadable with import */ - EXE /* component implemented as an executable */ + EXE, /* component implemented as an executable */ + CEXE /* component to be loaded by a container which executable is given in the catalog */ } ; /*! diff --git a/idl/SALOME_Session.idl b/idl/SALOME_Session.idl index 041df52a7..9ca58aa22 100644 --- a/idl/SALOME_Session.idl +++ b/idl/SALOME_Session.idl @@ -113,5 +113,22 @@ module SALOME Restores a state of the study at theSavePoint */ boolean restoreVisualState(in long theSavePoint); +/*! + Emit a qt signal from the session GUI desktop window. + This method can be used to send a message to the GUI from the standalone + container. + Caution: this method can block the Session and the calling container + if it is called when container processes some request from the GUI + (mutual lock takes place). + In such a case it is recommended to use oneway method. +*/ + void emitMessage(in string theMessage); +/*! + Emit a qt signal from the session GUI desktop window. + This method can be used to send a message to the GUI from the standalone + container. + This method never blocks the Session and the calling container. +*/ + oneway void emitMessageOneWay(in string theMessage); } ; } ; diff --git a/salome_adm/unix/Makefile.am b/salome_adm/unix/Makefile.am index b2d2a9a5f..0597e7822 100644 --- a/salome_adm/unix/Makefile.am +++ b/salome_adm/unix/Makefile.am @@ -34,7 +34,7 @@ DEPRECATED_FILES=\ # rules for install and build (see make_common_starter.am) salomeadmux_DATA = SALOMEconfig.h.in salomeinclude_DATA = SALOMEconfig.h -BUILT_SOURCES=SALOMEconfig.h SALOMEconfig.h.in +BUILT_SOURCES=SALOMEconfig.ref SALOMEconfig.h SALOMEconfig.h.in mostlyclean-local: -rm -rf SALOMEconfig.h SALOMEconfig.h.in @@ -45,9 +45,11 @@ SALOMEconfig.h.in : SALOMEconfig.ref.in # test if SALOMEconfig.ref has changed (contents), at build time SALOMEconfig.h: $(top_builddir)/salome_adm/unix/SALOMEconfig.ref @if ! [ -a $@ ]; then \ + echo cp -p $< $@; \ cp -p $< $@; \ fi; \ - if ! cmp $< $@; then \ + if ! cmp -s $< $@; then \ + echo cp -p $< $@; \ cp -p $< $@; \ fi; diff --git a/salome_adm/unix/config_files/check_lsf.m4 b/salome_adm/unix/config_files/check_lsf.m4 index a4faddb3c..7f140f7cd 100755 --- a/salome_adm/unix/config_files/check_lsf.m4 +++ b/salome_adm/unix/config_files/check_lsf.m4 @@ -49,7 +49,7 @@ AC_DEFUN([CHECK_LSF], else LSF_LDFLAGS="-L${LSF_LIBDIR}" fi - LSF_LIBS="" + LSF_LIBS="-lbat -llsf" saved_LDFLAGS=${LDFLAGS} saved_LIBS=${LIBS} LDFLAGS="${LDFLAGS} ${LSF_LDFLAGS}" diff --git a/salome_adm/unix/config_files/check_withihm.m4 b/salome_adm/unix/config_files/check_withihm.m4 index e4b412c0d..3e3aba71f 100644 --- a/salome_adm/unix/config_files/check_withihm.m4 +++ b/salome_adm/unix/config_files/check_withihm.m4 @@ -22,47 +22,38 @@ dnl AC_DEFUN([CHECK_WITHIHM],[ +AC_ARG_WITH(gui, + [ --with-gui build package with GUI support [[default=yes]]]) AC_ARG_WITH(ihm, - --with-ihm [default=yes], - WITHIHM="yes",WITHIHM="no") - -if test "${with_ihm}" = yes; then - - echo - echo --------------------------------------------- - echo testing WITH_IHM : yes - echo --------------------------------------------- - echo - WITHIHM="yes" - if test "${with_ihm}" = "yes";then - withihm_ok=yes - fi - -elif test "${with_ihm}" = no; then - - echo - echo --------------------------------------------- - echo testing WITH_IHM : no - echo --------------------------------------------- - echo - WITHIHM="no" - if test "${with_ihm}" = "no";then - withihm_ok=no - fi - + [ --with-ihm obsolete, use --with-gui instead]) + +if test "${with_gui}" == "yes" || test "${with_gui}" == "no" ; then + WITHGUI="${with_gui}" + WITHIHM=$WITHGUI +elif test "x${with_gui}" != "x" ; then + AC_MSG_FAILURE(wrong value for --with-gui or --without-gui option) +elif test "${with_ihm}" == "yes" || test "${with_ihm}" == "no" ; then + WITHIHM="${with_ihm}" + WITHGUI=$WITHIHM +elif test "x${with_ihm}" != "x" ; then + AC_MSG_FAILURE(wrong value for --with-ihm or --without-ihm option) else + WITHIHM="yes" + WITHGUI="yes" +fi - echo - echo --------------------------------------------- - echo testing WITH_IHM : yes - echo --------------------------------------------- - echo - WITHIHM="yes" - if test "${with_ihm}" = "yes";then - withihm_ok=yes - fi +echo +echo --------------------------------------------- +echo testing if GUI support is enabled : ${WITHGUI} +echo --------------------------------------------- +echo + +withihm_ok=$WITHGUI +withgui_ok=$WITHGUI -fi AC_SUBST(WITHIHM) +AC_SUBST(WITHGUI) ])dnl + +AC_DEFUN([CHECK_WITHGUI],[CHECK_WITHIHM]) diff --git a/src/Basics/BasicsGenericDestructor.cxx b/src/Basics/BasicsGenericDestructor.cxx index 9c1e21300..deca0e9c9 100644 --- a/src/Basics/BasicsGenericDestructor.cxx +++ b/src/Basics/BasicsGenericDestructor.cxx @@ -172,6 +172,7 @@ void HouseKeeping( void ) delete GENERIC_DESTRUCTOR::Destructors; GENERIC_DESTRUCTOR::Destructors = 0; + atExitSingletonDone = false ; DEVTRACE("HouseKeeping() very end "); return ; } diff --git a/src/Batch/Batch_JobInfo_LSF.cxx b/src/Batch/Batch_JobInfo_LSF.cxx index 0e4715af7..2ae986cd0 100644 --- a/src/Batch/Batch_JobInfo_LSF.cxx +++ b/src/Batch/Batch_JobInfo_LSF.cxx @@ -84,7 +84,7 @@ namespace Batch { _param[TEXT] = jobInfo.numReasons ? lsb_pendreason(jobInfo.numReasons, jobInfo.reasonTb, p_jInfoHead, - p_ld) : ""; + p_ld,0) : ""; // _param[TMPDIR] = jobInfo.; _param[USEDCPUTIME] = static_cast(jobInfo.cpuTime); // _param[USEDDISKSIZE] = jobInfo.; diff --git a/src/Batch/Makefile.am b/src/Batch/Makefile.am index b936e299a..c6c2cbf86 100644 --- a/src/Batch/Makefile.am +++ b/src/Batch/Makefile.am @@ -203,7 +203,7 @@ LIB_SRC += \ Batch_Job_LSF.cxx LIB_CPPFLAGS += ${LSF_INCLUDES} -LIB_LIBADD += ${LSF_LIBDIR} ${LSF_LIBS} +LIB_LIBADD += ${LSF_LDFLAGS} ${LSF_LIBS} endif diff --git a/src/Container/Component_i.cxx b/src/Container/Component_i.cxx index cfeeefc9b..885750da9 100644 --- a/src/Container/Component_i.cxx +++ b/src/Container/Component_i.cxx @@ -106,6 +106,7 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, _poa = PortableServer::POA::_duplicate(poa); _contId = contId ; CORBA::Object_var o = _poa->id_to_reference(*contId); // container ior... + _container=Engines::Container::_narrow(o); const CORBA::String_var ior = _orb->object_to_string(o); _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); @@ -114,6 +115,56 @@ Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, //SCRUTE(pd_refCount); } +//============================================================================= +/*! + * Standard Constructor for standalone Component, used in derived class + * Connection to Registry and Notification + * \param orb Object Request broker given by Container + * \param poa Portable Object Adapter from Container (normally root_poa) + * \param container container CORBA reference + * \param instanceName unique instance name for this object (see Container_i) + * \param interfaceName component class name + * \param notif use of notification + */ +//============================================================================= + +Engines_Component_i::Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : + _instanceName(instanceName), + _interfaceName(interfaceName), + _myConnexionToRegistry(0), + _notifSupplier(0), + _ThreadId(0) , + _ThreadCpuUsed(0) , + _Executed(false) , + _graphName("") , + _nodeName(""), + _studyId(-1), + _CanceledThread(false) +{ + MESSAGE("Component constructor with instanceName "<< _instanceName); + _orb = CORBA::ORB::_duplicate(orb); + _poa = PortableServer::POA::_duplicate(poa); + _container=Engines::Container::_duplicate(container); + try + { + _contId=_poa->reference_to_id(container); + } + catch(PortableServer::POA::WrongAdapter) + { + //not created by this poa + _contId = 0; + } + const CORBA::String_var ior = _orb->object_to_string(_container); + _myConnexionToRegistry = new RegistryConnexion(0, 0, ior,"theSession", _instanceName.c_str()); + _notifSupplier = new NOTIFICATION_Supplier(instanceName, notif); +} + + //============================================================================= /*! * Standard constructor for parallel component @@ -244,8 +295,8 @@ void Engines_Component_i::destroy() delete _myConnexionToRegistry; _myConnexionToRegistry = 0 ; - _poa->deactivate_object(*_id) ; - delete(_id) ; + if(_id) + delete(_id) ; //SCRUTE(pd_refCount); _thisObj->_remove_ref(); //SCRUTE(pd_refCount); @@ -261,9 +312,7 @@ void Engines_Component_i::destroy() Engines::Container_ptr Engines_Component_i::GetContainerRef() { - // MESSAGE("Engines_Component_i::GetContainerRef"); - CORBA::Object_var o = _poa->id_to_reference(*_contId) ; - return Engines::Container::_narrow(o); + return Engines::Container::_duplicate(_container); } //============================================================================= diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index 41e2b5b61..d574fa95c 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -337,6 +337,78 @@ void Engines_Container_i::Shutdown() } } +/* int checkifexecutable(const char *filename) + * + * Return non-zero if the name is an executable file, and + * zero if it is not executable, or if it does not exist. + */ + +int checkifexecutable(const char *filename) +{ + int result; + struct stat statinfo; + + result = stat(filename, &statinfo); + if (result < 0) return 0; + if (!S_ISREG(statinfo.st_mode)) return 0; + + if (statinfo.st_uid == geteuid()) return statinfo.st_mode & S_IXUSR; + if (statinfo.st_gid == getegid()) return statinfo.st_mode & S_IXGRP; + return statinfo.st_mode & S_IXOTH; +} + + +/* int findpathof(char *pth, const char *exe) + * + * Find executable by searching the PATH environment variable. + * + * const char *exe - executable name to search for. + * char *pth - the path found is stored here, space + * needs to be available. + * + * If a path is found, returns non-zero, and the path is stored + * in pth. If exe is not found returns 0, with pth undefined. + */ + +int findpathof(char *pth, const char *exe) +{ + char *searchpath; + char *beg, *end; + int stop, found; + int len; + + if (strchr(exe, '/') != NULL) { + if (realpath(exe, pth) == NULL) return 0; + return checkifexecutable(pth); + } + + searchpath = getenv("PATH"); + if (searchpath == NULL) return 0; + if (strlen(searchpath) <= 0) return 0; + + beg = searchpath; + stop = 0; found = 0; + do { + end = strchr(beg, ':'); + if (end == NULL) { + stop = 1; + strncpy(pth, beg, PATH_MAX); + len = strlen(pth); + } else { + strncpy(pth, beg, end - beg); + pth[end - beg] = '\0'; + len = end - beg; + } + if (pth[len - 1] != '/') strncat(pth, "/", 1); + strncat(pth, exe, PATH_MAX - len); + found = checkifexecutable(pth); + if (!stop) beg = end + 1; + } while (!stop && !found); + + return found; +} + + //============================================================================= /*! @@ -424,9 +496,16 @@ Engines_Container_i::load_component_Library(const char* componentName) return true; } } + // Try to find an executable + std::string executable=aCompName+".exe"; + char path[PATH_MAX+1]; + if (findpathof(path, executable.c_str())) + return true; + INFOS( "Impossible to load component: " << componentName ); INFOS( "Can't load shared library: " << impl_name ); INFOS( "Can't import Python module: " << componentName ); + INFOS( "Can't execute program: " << executable ); return false; } @@ -504,12 +583,7 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, #else string impl_name = genericRegisterName +string("Engine.dll"); #endif - if (_library_map.count(impl_name) == 0) - { - INFOS("shared library " << impl_name <<" must be loaded before creating instance"); - return Engines::Component::_nil() ; - } - else + if (_library_map.count(impl_name) != 0) // C++ component { void* handle = _library_map[impl_name]; iobject = createInstance(genericRegisterName, @@ -517,6 +591,97 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName, studyId); return iobject._retn(); } + + // If it's not a Python or a C++ component try to launch a standalone component + // in a sub directory + // This component is implemented in an executable with name genericRegisterName.exe + // It must register itself in Naming Service. The container waits some time (10 s max) + // it's registration. + + _numInstanceMutex.lock() ; // lock on the instance number + _numInstance++ ; + int numInstance = _numInstance ; + _numInstanceMutex.unlock() ; + + char aNumI[12]; + sprintf( aNumI , "%d" , numInstance ) ; + string instanceName = aCompName + "_inst_" + aNumI ; + string component_registerName = _containerName + "/" + instanceName; + + //check if an entry exist in naming service + CORBA::Object_var nsobj = _NS->Resolve(component_registerName.c_str()); + if ( !CORBA::is_nil(nsobj) ) + { + // unregister the registered component + _NS->Destroy_Name(component_registerName.c_str()); + //kill or shutdown it ??? + } + + // first arg container ior string + // second arg container name + // third arg instance name + + Engines::Container_var pCont= _this(); + CORBA::String_var sior = _orb->object_to_string(pCont); + + std::string command; + command="mkdir -p "; + command+=instanceName; + command+=";cd "; + command+=instanceName; + command+=";"; + command+=genericRegisterName ; + command+=".exe"; + command+=" "; + command+= sior; // container ior string + command+=" "; + command+=_containerName; //container name + command+=" "; + command+=instanceName; //instance name + command+=" &"; + MESSAGE("SALOME_Container::create_component_instance command=" << command); + // launch component with a system call + int status=system(command.c_str()); + + if (status == -1) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status -1)"); + return Engines::Component::_nil(); + } + else if (WEXITSTATUS(status) == 217) + { + MESSAGE("SALOME_Container::create_component_instance system failed " << "(system command status 217)"); + return Engines::Component::_nil(); + } + else + { + int count=20; + CORBA::Object_var obj = CORBA::Object::_nil() ; + while ( CORBA::is_nil(obj) && count ) + { +#ifndef WNT + sleep( 1 ) ; +#else + Sleep(1000); +#endif + count-- ; + MESSAGE( count << ". Waiting for component " << genericRegisterName); + obj = _NS->Resolve(component_registerName.c_str()); + } + + if(CORBA::is_nil(obj)) + { + MESSAGE("SALOME_Container::create_component_instance failed"); + return Engines::Component::_nil(); + } + else + { + MESSAGE("SALOME_Container::create_component_instance successful"); + iobject=Engines::Component::_narrow(obj); + _listInstances_map[instanceName] = iobject; + return iobject._retn(); + } + } } //============================================================================= diff --git a/src/Container/SALOME_ComponentPy.py b/src/Container/SALOME_ComponentPy.py index 5d071b8e4..77f89ac47 100755 --- a/src/Container/SALOME_ComponentPy.py +++ b/src/Container/SALOME_ComponentPy.py @@ -147,8 +147,9 @@ class SALOME_ComponentPy_i (Engines__POA.Component): def destroy(self): MESSAGE( "SALOME_ComponentPy_i::destroy" ) - id = self._poa.servant_to_id(self) - self._poa.deactivate_object(id) + #id = self._poa.servant_to_id(self) + #self._poa.deactivate_object(id) + return #------------------------------------------------------------------------- diff --git a/src/Container/SALOME_Component_i.hxx b/src/Container/SALOME_Component_i.hxx index 03234c307..3d49b89c5 100644 --- a/src/Container/SALOME_Component_i.hxx +++ b/src/Container/SALOME_Component_i.hxx @@ -61,6 +61,13 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + //Constructor for standalone component + Engines_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); // Consructeur pour composant parallele: ne pas faire appel au registry Engines_Component_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, @@ -147,6 +154,7 @@ protected: PortableServer::POA_var _poa; PortableServer::ObjectId * _id; PortableServer::ObjectId * _contId; + Engines::Container_var _container; Engines_Component_i * _thisObj ; RegistryConnexion *_myConnexionToRegistry; NOTIFICATION_Supplier* _notifSupplier; diff --git a/src/Container/SALOME_Container.py b/src/Container/SALOME_Container.py index 179150954..405d1f963 100644 --- a/src/Container/SALOME_Container.py +++ b/src/Container/SALOME_Container.py @@ -64,8 +64,8 @@ class SALOME_Container_i: #------------------------------------------------------------------------- - def __del__(self ): - self._orb.destroy() + #def __del__(self ): + # self._orb.destroy() def import_component(self, componentName): MESSAGE( "SALOME_Container_i::import_component" ) diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx index 52802a144..8d887aed8 100644 --- a/src/Container/SALOME_ContainerManager.cxx +++ b/src/Container/SALOME_ContainerManager.cxx @@ -19,6 +19,7 @@ // #include "SALOME_ContainerManager.hxx" #include "SALOME_NamingService.hxx" +#include "SALOME_ModuleCatalog.hh" #include "OpUtil.hxx" #include #include @@ -199,7 +200,7 @@ Engines::Container_ptr SALOME_ContainerManager:: StartContainer(const Engines::MachineParameters& params, const Engines::MachineList& possibleComputers, - Engines::ResPolicy policy) + Engines::ResPolicy policy,const std::string& container_exe) { #ifdef WITH_PACO_PARALLEL std::string parallelLib(params.parallelLib); @@ -259,9 +260,9 @@ StartContainer(const Engines::MachineParameters& params, return Engines::Container::_nil(); } else if(theMachine==GetHostname()) - command = BuildCommandToLaunchLocalContainer(params,id); + command = BuildCommandToLaunchLocalContainer(params,id,container_exe); else - command = BuildCommandToLaunchRemoteContainer(theMachine,params,id); + command = BuildCommandToLaunchRemoteContainer(theMachine,params,id,container_exe); RmTmpFile(); @@ -279,10 +280,19 @@ StartContainer(const Engines::MachineParameters& params, CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str()); if ( !CORBA::is_nil(obj) ) { - // unregister the registered container if it exists - _NS->Destroy_Name(containerNameInNS.c_str()); - // unregister component instances ??? - //Engines::Container_var cont=Engines::Container::_narrow(obj); + // shutdown the registered container if it exists + Engines::Container_var cont=Engines::Container::_narrow(obj); + if(!CORBA::is_nil(cont)) + { + try + { + cont->Shutdown(); + } + catch(CORBA::Exception&) + { + INFOS("CORBA::Exception ignored."); + } + } } //redirect stdout and stderr in a file @@ -349,7 +359,53 @@ StartContainer(const Engines::MachineParameters& params, const Engines::CompoList& componentList) { Engines::MachineList_var possibleComputers = _ResManager->GetFittingResources(params,componentList); - return StartContainer(params,possibleComputers,policy); + + // Look into ModulCatalog if a specific container must be launched + CORBA::String_var container_exe; + int found=0; + try + { + CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var Catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; + if (CORBA::is_nil (Catalog)) + return Engines::Container::_nil(); + // Loop through component list + for(int i=0;iGetComponent(compoi); + if (CORBA::is_nil (compoInfo)) + { + continue; + } + SALOME_ModuleCatalog::ImplType impl=compoInfo->implementation_type(); + container_exe=compoInfo->implementation_name(); + if(impl==SALOME_ModuleCatalog::CEXE) + { + if(found) + { + INFOS("ContainerManager Error: you can't have 2 CEXE component in the same container" ); + return Engines::Container::_nil(); + } + found=1; + } + } + } + catch (ServiceUnreachable&) + { + INFOS("Caught exception: Naming Service Unreachable"); + return Engines::Container::_nil(); + } + catch (...) + { + INFOS("Caught unknown exception."); + return Engines::Container::_nil(); + } + + if(found) + return StartContainer(params,possibleComputers,policy,container_exe.in()); + else + return StartContainer(params,possibleComputers,policy); } #ifdef WITH_PACO_PARALLEL @@ -738,7 +794,7 @@ bool isPythonContainer(const char* ContainerName) string SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer (const string& machine, - const Engines::MachineParameters& params, const long id) + const Engines::MachineParameters& params, const long id,const std::string& container_exe) { string command; int nbproc; @@ -822,7 +878,7 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer command += " SALOME_MPIContainer "; } else - command += " SALOME_Container "; + command += " " +container_exe+ " "; command += _NS->ContainerName(params); command += " -id "; @@ -845,7 +901,7 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer -(const Engines::MachineParameters& params, const long id) +(const Engines::MachineParameters& params, const long id,const std::string& container_exe) { _TmpFileName = ""; string command; @@ -906,7 +962,7 @@ SALOME_ContainerManager::BuildCommandToLaunchLocalContainer if (isPythonContainer(params.container_name)) command += "SALOME_ContainerPy.py "; else - command += "SALOME_Container "; + command += container_exe + " "; } command += _NS->ContainerName(params); diff --git a/src/Container/SALOME_ContainerManager.hxx b/src/Container/SALOME_ContainerManager.hxx index d8be68833..869b9c235 100644 --- a/src/Container/SALOME_ContainerManager.hxx +++ b/src/Container/SALOME_ContainerManager.hxx @@ -47,7 +47,8 @@ public: Engines::Container_ptr StartContainer(const Engines::MachineParameters& params, const Engines::MachineList& possibleComputer, - Engines::ResPolicy policy); + Engines::ResPolicy policy, + const std::string& container_exe="SALOME_Container"); Engines::Container_ptr StartContainer(const Engines::MachineParameters& params, @@ -88,9 +89,11 @@ protected: long GetIdForContainer(void); std::string BuildCommandToLaunchRemoteContainer(const std::string& machine, - const Engines::MachineParameters& params, const long id); + const Engines::MachineParameters& params, const long id, + const std::string& container_exe="SALOME_Container"); - std::string BuildCommandToLaunchLocalContainer(const Engines::MachineParameters& params, const long id); + std::string BuildCommandToLaunchLocalContainer(const Engines::MachineParameters& params, const long id, + const std::string& container_exe="SALOME_Container"); std::string BuildTempFileToLaunchRemoteContainer(const std::string& machine, const Engines::MachineParameters& params) throw(SALOME_Exception); diff --git a/src/Container/SALOME_ContainerPy.py b/src/Container/SALOME_ContainerPy.py index 1694bc79d..41cfcaeee 100755 --- a/src/Container/SALOME_ContainerPy.py +++ b/src/Container/SALOME_ContainerPy.py @@ -304,35 +304,42 @@ class SALOME_ContainerPy_i (Engines__POA.Container): #------------------------------------------------------------------------- def Shutdown(self): + self._naming_service.Destroy_Name(self._containerName); + self._naming_service.Destroy_FullDirectory(self._containerName); self._orb.shutdown(0) pass -#============================================================================= - -#initialise the ORB and find the root POA -print "Starting ",sys.argv[1] -orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) -poa = orb.resolve_initial_references("RootPOA") -print "ORB and POA initialized" - -#create an instance of SALOME_ContainerPy_i and a Container reference -#containerName = "FactoryServerPy" -MESSAGE( str(sys.argv) ) -containerName = sys.argv[1] -cpy_i = SALOME_ContainerPy_i(orb, poa, containerName) -print "SALOME_ContainerPy_i instance created ",cpy_i -cpy_o = cpy_i._this() -print "SALOME_ContainerPy_i instance activated ",cpy_o - -#activate the POA -poaManager = poa._get_the_POAManager() -poaManager.activate() - -#Block for ever -orb.run() - - - - + def _get_logfilename(self): + return self._logfilename + def _set_logfilename(self,logfilename): + self._logfilename=logfilename + def _get_workingdir(self): + return os.getcwd() +#============================================================================= +if __name__ == "__main__": + #initialise the ORB and find the root POA + if verbose():print "Starting ",sys.argv[1] + orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) + poa = orb.resolve_initial_references("RootPOA") + if verbose():print "ORB and POA initialized" + + #create an instance of SALOME_ContainerPy_i and a Container reference + #containerName = "FactoryServerPy" + MESSAGE( str(sys.argv) ) + containerName = sys.argv[1] + cpy_i = SALOME_ContainerPy_i(orb, poa, containerName) + if verbose():print "SALOME_ContainerPy_i instance created ",cpy_i + cpy_o = cpy_i._this() + if verbose():print "SALOME_ContainerPy_i instance activated ",cpy_o + sys.stdout.flush() + sys.stderr.flush() + + #activate the POA + poaManager = poa._get_the_POAManager() + poaManager.activate() + + #Block for ever + orb.run() + if verbose():print "SALOME_ContainerPy_i shutdown" diff --git a/src/DSC/DSC_Basic/DSC_i.cxx b/src/DSC/DSC_Basic/DSC_i.cxx index bf67a554c..2daa87423 100644 --- a/src/DSC/DSC_Basic/DSC_i.cxx +++ b/src/DSC/DSC_Basic/DSC_i.cxx @@ -42,5 +42,18 @@ Engines_DSC_i(CORBA::ORB_ptr orb, #endif } +Engines_DSC_i:: +Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_Component_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + std::cerr << "--Engines_DSC_i: MARK 1 --" << instanceName << "----" << std::endl; +#endif +} + Engines_DSC_i::~Engines_DSC_i() {} diff --git a/src/DSC/DSC_Basic/DSC_i.hxx b/src/DSC/DSC_Basic/DSC_i.hxx index 6a495f9ce..a66be1d56 100644 --- a/src/DSC/DSC_Basic/DSC_i.hxx +++ b/src/DSC/DSC_Basic/DSC_i.hxx @@ -56,6 +56,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Engines_DSC_i(); diff --git a/src/DSC/DSC_Python/calcium.i b/src/DSC/DSC_Python/calcium.i index dddf3aa06..73fd47ed3 100644 --- a/src/DSC/DSC_Python/calcium.i +++ b/src/DSC/DSC_Python/calcium.i @@ -38,6 +38,7 @@ struct omniORBpyAPI { }; omniORBpyAPI* api; + PyObject* dsc ; %} @@ -60,6 +61,9 @@ struct omniORBpyAPI { PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API"); api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi); Py_DECREF(pyapi); + + PyObject* engines = PyImport_ImportModule("Engines"); + dsc = PyObject_GetAttrString(engines, "DSC"); %} %include @@ -570,6 +574,10 @@ TYPEMAP_INPLACE3(double, PyArray_DOUBLE) { $1=(CORBA::Boolean)PyInt_AsLong($input); } +%typemap(out) CORBA::Boolean +{ + $result=PyInt_FromLong($1 ? 1 : 0); +} %define CORBAPTR(type) %typemap(in) type##_ptr @@ -630,17 +638,29 @@ CORBAPTR(PortableServer::POA) } catch(Engines::DSC::PortNotDefined& _e) { Py_BLOCK_THREADS - PyErr_SetString(PyExc_ValueError,"Port not defined"); + PyObject* excc = PyObject_GetAttrString(dsc, "PortNotDefined"); + PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL); + PyErr_SetObject(excc, exci); + Py_XDECREF(excc); + Py_XDECREF(exci); return NULL; } catch(Engines::DSC::PortNotConnected& _e) { Py_BLOCK_THREADS - PyErr_SetString(PyExc_ValueError,"Port not connected"); + PyObject* excc = PyObject_GetAttrString(dsc, "PortNotConnected"); + PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL); + PyErr_SetObject(excc, exci); + Py_XDECREF(excc); + Py_XDECREF(exci); return NULL; } catch(Engines::DSC::BadPortType& _e) { Py_BLOCK_THREADS - PyErr_SetString(PyExc_ValueError,"Bad port type"); + PyObject* excc = PyObject_GetAttrString(dsc, "BadPortType"); + PyObject* exci = PyEval_CallObject(excc, (PyObject *)NULL); + PyErr_SetObject(excc, exci); + Py_XDECREF(excc); + Py_XDECREF(exci); return NULL; } catch (SALOME_Exception &e) { @@ -650,6 +670,7 @@ CORBAPTR(PortableServer::POA) } catch (SALOME::SALOME_Exception &e) { Py_BLOCK_THREADS + //This one should be converted into a python corba exception PyErr_SetString(PyExc_RuntimeError,e.details.text); return NULL; } @@ -750,6 +771,7 @@ class PySupervCompo:public Superv_Component_i 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); + CORBA::Boolean is_connected(const char* port_name) throw (Engines::DSC::PortNotDefined); // End of DSC interface for python components diff --git a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c index cba14ca11..e7c051448 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c +++ b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c @@ -34,7 +34,9 @@ typedef int InfoType; typedef char bool; -/* INTERFACES DE LECTURE en 0 copie */ +/************************************/ +/* 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 */ @@ -50,8 +52,11 @@ typedef char bool; int * nRead, _type _qual ** data ) { \ size_t _nRead; \ long _i=*i; \ + fflush(stdout); \ + fflush(stderr); \ + fprintf(stderr,"Beginning of ecp_" #_name " : %s %d %f\n",nomvar,*i,*ti); \ + \ \ - /* std::cerr << "-------- CalciumInterface(C Part) MARK 1 ------------------" << std::endl; */ \ InfoType info = ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \ nomvar, bufferLength, &_nRead, \ data ); \ @@ -70,20 +75,54 @@ typedef char bool; return info; \ }; \ void ecp_##_name##_free ( _type _qual * data) { \ - ecp_lecture_##_typeName##_free(data); \ + 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,int,bool,); CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); /* CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]); */ +/* L'interface de cette routine diffère de celle obtenue par la macro : + CALCIUM_LECT_INTERFACE_C_. + Le paramètre supplémentaire strSize indique la taille fixe et identique + des chaînes stockées dans data (les ports CALCIUM n'en n'ont pas besoin) +*/ +InfoType ecp_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); + + + InfoType info = ecp_lecture_str (component, mode, ti, tf, &_i, + nomvar, bufferLength, &_nRead, + data);/*, strSize ); + strSize est inutile pour les ports CALCIUM + qui gèrent des tailles quelconques de chaines. */ + 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; +}; + +void ecp_lch_free (char* * data) { \ + ecp_lecture_str_free(data); \ +}; -/* INTERFACES DE LECTURE avec recopie */ +/**************************************/ +/* INTERFACES DE LECTURE AVEC RECOPIE */ +/**************************************/ #define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \ InfoType cp_##_name (void * component, int mode, \ @@ -99,12 +138,12 @@ CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; \ \ InfoType info = ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \ - nomvar, bufferLength, &_nRead, \ + nomvar, bufferLength, &_nRead, \ &data ); \ if(mode == CP_SEQUENTIEL) \ *i = _i; \ *nRead=_nRead; \ - fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,*i); \ + fprintf(stderr,"End of cp_" #_name " : %s %d \n",nomvar,*i); \ fflush(stdout); \ fflush(stderr); \ \ @@ -115,7 +154,11 @@ CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,); }; - +/* L'interface de cette routine diffère de celle obtenue par la macro : + CALCIUM_LECT_INTERFACE_C_. + Le paramètre supplémentaire strSize indique la taille fixe et identique + des chaînes stockées dans data (les ports CALCIUM n'en n'ont pas besoin) +*/ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, char * nomvar, int bufferLength, int * nRead, char ** data, int strSize) { @@ -129,7 +172,9 @@ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, InfoType info = ecp_lecture_str (component, mode, ti, tf, &_i, nomvar, bufferLength, &_nRead, - &data);/*, strSize );*/ + &data);/*, strSize ); + strSize est inutile pour les ports CALCIUM + qui gèrent des tailles quelconques de chaines. */ if(mode == CP_SEQUENTIEL) *i = _i; *nRead=_nRead; @@ -139,50 +184,22 @@ InfoType cp_lch(void * component, int mode, float * ti, float * tf, int * i, 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,int,bool,); CALCIUM_LECT_INTERFACE_C_(lcp,float,float,cplx,); #define STAR * /* CALCIUM_LECT_INTERFACE_C_(lch,float,char,STAR); */ + +/**********************************************/ /* INTERFACES DE DÉBUT ET DE FIN DE COUPLAGE */ +/**********************************************/ InfoType cp_cd (void * component, char * instanceName) { /* TODO : Trouver le nom de l'instance SALOME*/ @@ -198,7 +215,10 @@ 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, \ @@ -223,6 +243,15 @@ InfoType cp_fin (void * component, int code) { }; \ +/* 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,int,bool,); +CALCIUM_ECR_INTERFACE_C_(ecp,float,float,cplx,); + InfoType cp_ech(void * component, int mode, float t, int i, char * nomvar, int nbelem, @@ -243,38 +272,4 @@ InfoType cp_ech(void * component, int mode, float t, int i, 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; jreference_to_id(contain), instanceName, interfaceName) + Superv_Component_i(orb, poa,contain, instanceName, interfaceName) { } diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx index 2a18b69e3..6835898f9 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.cxx @@ -38,12 +38,18 @@ void CalciumCouplingPolicy::setDependencyType (CalciumTypes::DependencyType depe CalciumTypes::DependencyType CalciumCouplingPolicy::getDependencyType () const { return _dependencyType;} void CalciumCouplingPolicy::setStorageLevel (size_t storageLevel) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setStorageLevel: " << storageLevel << std::endl; +#endif if ( storageLevel < 1 && (storageLevel != CalciumTypes::UNLIMITED_STORAGE_LEVEL) ) throw CalciumException(CalciumTypes::CPRENA,LOC("Un niveau < 1 n'est pas autorisé")); _storageLevel = storageLevel; } size_t CalciumCouplingPolicy::getStorageLevel () const {return _storageLevel;} void CalciumCouplingPolicy::setDateCalSchem (CalciumTypes::DateCalSchem dateCalSchem) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setDateCalSchem: " << dateCalSchem << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Il est impossible de positionner un schéma temporel sur un port qui n'est pas en dépendance temporelle")); _dateCalSchem = dateCalSchem; @@ -52,6 +58,9 @@ void CalciumCouplingPolicy::setDateCalSchem (CalciumTypes::DateCalSchem da CalciumTypes::DateCalSchem CalciumCouplingPolicy::getDateCalSchem () const { return _dateCalSchem; } void CalciumCouplingPolicy::setAlpha(double alpha) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setAlpha: " << alpha << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Il est impossible de positionner alpha sur un port qui n'est pas en dépendance temporelle")); @@ -72,6 +81,9 @@ void CalciumCouplingPolicy::setDeltaT(double deltaT ) { double CalciumCouplingPolicy::getDeltaT() const {return _deltaT;} void CalciumCouplingPolicy::setInterpolationSchem (CalciumTypes::InterpolationSchem interpolationSchem) { +#ifdef _DEBUG_ + std::cerr << "CalciumCouplingPolicy::setInterpolationSchem: " << interpolationSchem << std::endl; +#endif if ( _dependencyType != CalciumTypes::TIME_DEPENDENCY ) throw CalciumException(CalciumTypes::CPITVR,LOC("Le paramètre InterpolationSchem sur un port qui n'est pas en dépendance temporelle n'a pas de sens")); _interpolationSchem=interpolationSchem; diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx index 1fe1c0e5b..4ae601ad7 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx @@ -244,6 +244,12 @@ struct CalciumCouplingPolicy::BoundedDataIdProcessor< Type dataOut = DataManipulator::create(dataSize); InnerType * const OutIt = DataManipulator::getPointer(dataOut); +#ifdef _DEBUG_ + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : interpolationSchem : " << _couplingPolicy._interpolationSchem << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : alpha : " << _couplingPolicy._alpha << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : datecalschem : " << _couplingPolicy._dateCalSchem << std::endl; + std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : storageLevel : " << _couplingPolicy._storageLevel << std::endl; +#endif if ( timeDiff == 0.0 || _couplingPolicy._interpolationSchem == CalciumTypes::L0_SCHEM ) { std::copy(InIt1,InIt1+dataSize,OutIt); } else { diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx index 39565be08..207f2e749 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx @@ -54,11 +54,20 @@ struct IsSameType { }; +#include namespace CalciumInterface { /********************* INTERFACE DE DECONNEXION *****************/ + static void + ecp_cd (Superv_Component_i & component, std::string & instanceName) + { + /* TODO : Trouver le nom de l'instance SALOME*/ + if (instanceName.empty()) instanceName="UNDEFINED"; + + } + static void ecp_fin (Superv_Component_i & component, bool provideLastGivenValue) { @@ -66,8 +75,8 @@ namespace CalciumInterface { std::vector::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 + //Récupérer le type de réel du port est un peu difficile + //car l'interface ne donne aucune indication // uses_port *myUsesPort; calcium_uses_port* myCalciumUsesPort; @@ -127,10 +136,10 @@ namespace CalciumInterface { { typedef typename ProvidesPortTraits::PortType PortType; typedef typename PortType::DataManipulator DataManipulator; - typedef typename DataManipulator::Type DataType; // Attention != T + typedef typename DataManipulator::Type DataType; // Attention != T1 typedef typename DataManipulator::InnerType InnerType; - DeleteTraits::value >::apply(dataPtr); + DeleteTraits::value, DataManipulator >::apply(dataPtr); } template static void @@ -142,31 +151,15 @@ namespace CalciumInterface { /********************* INTERFACES DE LECTURE *****************/ - // T1 est le type de données - template 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 (component,dependencyType,ti,tf, - i,nomVar,bufferLength,nRead,data); - - } // T1 est le type de données - // T2 est un de type Calcium permettant de sélectionner le port correspondant + // T2 est un de type Calcium permettant de sélectionner le port CORBA correspondant // T1 et T2 sont dissociés pour discriminer le cas des nombres complexes // -> Les données des nombres complexes sont de type float mais // le port à utiliser est le port cplx template static void ecp_lecture ( Superv_Component_i & component, - CalciumTypes::DependencyType dependencyType, + int const & dependencyType, double & ti, double const & tf, long & i, @@ -182,7 +175,9 @@ namespace CalciumInterface { typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::Type CorbaDataType; // Attention != T1 typedef typename DataManipulator::InnerType InnerType; - + CalciumTypes::DependencyType _dependencyType= + static_cast(dependencyType); + CorbaDataType corbaData; #ifdef _DEBUG_ @@ -228,21 +223,21 @@ namespace CalciumInterface { LOC(OSS()<<"Le mode de dépendance de la variable " << nomVar << " est indéfini.")); - if ( ( portDependencyType != dependencyType ) && - ( dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) + 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é.")); - if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) { + 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 ) { + else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) { corbaData = port->get(0, i); #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl; @@ -269,30 +264,41 @@ namespace CalciumInterface { 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 + // Si les types T1 et InnerType sont différents, il faudra effectuer tout de même une recopie if (!IsSameType::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 T1 et InnerType sont les mêmes - Copy2UserSpace< IsSameType::value >::apply(data,corbaData,nRead); + // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes. + // Copy2UserSpace : + // La raison d'être du foncteur Copy2UserSpace est que le compilateur n'acceptera + // pas une expresion d'affectation sur des types incompatibles même + // si cette expression se trouve dans une branche non exécuté d'un test + // sur la compatibilité des types. + // En utilisant le foncteur Copy2UserSpace, seul la spécialisation en adéquation + // avec la compatibilité des types sera compilée + Copy2UserSpace< IsSameType::value, DataManipulator >::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 : - // DataManipulator::delete_data(corbaData); + // DataManipulator::delete_data(corbaData); + // ni DataManipulator::getPointer(corbaData,true); qui détruit la sequence lorsque l'on + // prend la propriété du buffer // old : Dans les deux cas la structure CORBA n'est plus utile // old : Si !IsSameType::value l'objet CORBA est détruit avec son contenu // old : Dans l'autre cas seul la coquille CORBA est détruite - // L'utilisateur devra appeler ecp_free (version modifiée) qui déterminera s'il est necessaire - // de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété + // L'utilisateur devra appeler ecp_free qui déterminera s'il est necessaire + // de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété } else { nRead = std::min < size_t > (corbaDataSize,bufferLength); #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl; #endif - Copy2UserSpace::apply(data,corbaData,nRead); + Copy2UserSpace::apply(data,corbaData,nRead); + DataManipulator::copy(corbaData,data,nRead); + #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl; #endif @@ -312,53 +318,68 @@ namespace CalciumInterface { return; } + // T1 est le type de données + template static void + ecp_lecture ( Superv_Component_i & component, + int const & dependencyType, + double & ti, + double const & tf, + long & i, + const string & nomVar, + size_t bufferLength, + size_t & nRead, + T1 * &data ) + { + ecp_lecture (component,dependencyType,ti,tf, + i,nomVar,bufferLength,nRead,data); + + } /********************* INTERFACES D'ECRITURE *****************/ - template 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 (component,dependencyType,t,i,nomVar,bufferLength,data); - } - + // T1 : DataType + // T2 : PortType template static void ecp_ecriture ( Superv_Component_i & component, - CalciumTypes::DependencyType dependencyType, + int const & dependencyType, double const & t, long const & i, const string & nomVar, size_t bufferLength, - T1 & data ) + T1 const & data ) { assert(&component); - //typedef typename StarTrait::NonStarType T; - typedef typename UsesPortTraits::PortType PortType; - typedef typename ProvidesPortTraits::PortType ProvidesPortType; - typedef typename ProvidesPortType::DataManipulator DataManipulator; + //typedef typename StarTrait::NonStarType T; + typedef typename boost::remove_all_extents< T2 >::type T2_without_extent; + typedef typename boost::remove_all_extents< T1 >::type T1_without_extent; + + typedef typename UsesPortTraits ::PortType UsesPortType; + typedef typename ProvidesPortTraits::PortType ProvidesPortType;// pour obtenir un manipulateur de données + 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; + typedef typename DataManipulator::Type CorbaDataType; // Attention != T1 + typedef typename DataManipulator::InnerType InnerType; + + T1_without_extent const & _data = data; + + CalciumTypes::DependencyType _dependencyType= + static_cast(dependencyType); #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 ")); - PortType * port; + UsesPortType * port; #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl; #endif try { - port = component.Superv_Component_i::get_port< PortType > (nomVar.c_str()); + port = component.Superv_Component_i::get_port< UsesPortType > (nomVar.c_str()); #ifdef _DEBUG_ std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl; #endif @@ -393,12 +414,12 @@ namespace CalciumInterface { // throw (CalciumException(CalciumTypes::CPIT,ex)); // } - if ( dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY ) + 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 ) + 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.")); @@ -408,7 +429,7 @@ namespace CalciumInterface { // 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 ) +// if ( portDependencyType != _dependencyType ) // throw CalciumException(CalciumTypes::CPITVR, // LOC(OSS()<<"Le mode de dépendance de la variable " // << nomVar << " ne correspond pas au mode demandé.")); @@ -437,7 +458,7 @@ namespace CalciumInterface { // OLD : la séquence locale. Or la méthode put récupère le buffer directement // OLD : qui est alors le buffer utilisateur. Il pourrait alors arriver que : // OLD : * Le recepteur efface le buffer emetteur - // OLD : * Le port lui-même efface le buffer de l'ulisateur ! + // OLD : * Le port lui-même efface le buffer de l'utilisateur ! // OLD : Cette copie est effectuée dans GenericPortUses::put // OLD : en fonction de la collocalisation ou non. // - OLD :En cas de connection multiples d'un port uses distant vers plusieurs port provides @@ -445,10 +466,10 @@ namespace CalciumInterface { // OLD : Il faut effectuer une copie dans le port provides. // OLD : Cette copie est effectuée dans GenericPortUses::put // OLD : en fonction de la collocalisation ou non. - Copy2CorbaSpace::value >::apply(corbaData,data,bufferLength); + Copy2CorbaSpace::value, DataManipulator >::apply(corbaData,_data,bufferLength); //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté - if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) { + if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) { try { port->put(*corbaData,t, -1); @@ -463,7 +484,7 @@ namespace CalciumInterface { std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl; #endif } - else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) { + else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) { try { port->put(*corbaData,-1, i); @@ -493,7 +514,18 @@ namespace CalciumInterface { #endif return; - } + }; + + template static void + ecp_ecriture ( Superv_Component_i & component, + int const & dependencyType, + double const & t, + long const & i, + const string & nomVar, + size_t bufferLength, + T1 const & data ) { + ecp_ecriture (component,dependencyType,t,i,nomVar,bufferLength,data); + }; }; diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx index b419e3869..9d90dfb7f 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumGenericProvidesPort.hxx @@ -27,6 +27,8 @@ #ifndef _CALCIUM_GENERIC_PROVIDES_PORT_HXX_ #define _CALCIUM_GENERIC_PROVIDES_PORT_HXX_ +#include + #include "PortProperties_i.hxx" #include "calcium_provides_port.hxx" @@ -55,17 +57,31 @@ class specificPortName : public virtual CorbaInterface , \ public virtual POA_Ports::PortProperties, \ public GenericProvidesPort< __VA_ARGS__ , CalciumCouplingPolicy, calcium_provides_port > { \ + private : \ + omni_mutex _disconnect_mutex; \ + int _mustnotdisconnect; \ public : \ typedef __VA_ARGS__ DataManipulator; \ typedef DataManipulator::Type CorbaDataType; \ typedef GenericPort< DataManipulator , \ CalciumCouplingPolicy > Port; \ + specificPortName () : _mustnotdisconnect(0) {}; \ \ virtual ~ specificPortName (); \ \ inline void disconnect(bool provideLastGivenValue) { \ - Port::disconnect(provideLastGivenValue); \ - } \ + _disconnect_mutex.lock(); \ + if(_mustnotdisconnect > 1) \ + { \ + _mustnotdisconnect--; \ + } \ + else if(_mustnotdisconnect == 1) \ + { \ + _mustnotdisconnect--; \ + Port::disconnect(provideLastGivenValue); \ + } \ + _disconnect_mutex.unlock(); \ + } \ inline void setDependencyType(CalciumTypes::DependencyType dependencyType) { \ Port::setDependencyType(dependencyType); \ } \ @@ -128,15 +144,20 @@ virtual CORBA::Any* get_property(const char* name) \ throw (Ports::NotDefined); \ \ - virtual void provides_port_changed(int connection_nbr, \ - const Engines::DSC::Message message) { \ - if ( !connection_nbr && (message == Engines::DSC::RemovingConnection) ) \ - { \ - disconnect(false); \ - } \ - } \ - }; \ - + virtual void provides_port_changed(int connection_nbr, \ + const Engines::DSC::Message message) { \ + if ( message == Engines::DSC::AddingConnection) \ + { \ + _disconnect_mutex.lock(); \ + _mustnotdisconnect++; \ + _disconnect_mutex.unlock(); \ + } \ + else if ( message == Engines::DSC::RemovingConnection ) \ + { \ + disconnect(false); \ + } \ + } \ + }; \ diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx index 62994aa97..5732b6601 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx @@ -29,7 +29,7 @@ #ifndef _CALCIUM_INTERFACE_HXX_ #define _CALCIUM_INTERFACE_HXX_ -//Interface C++ +//Interface CALCIUM des utilisateurs en C++ #include "CalciumCxxInterface.hxx" #include "CalciumException.hxx" @@ -37,6 +37,9 @@ #include +//Ce fichier déclare et défini l'interfaçage entre l'API utilisteur C et C++ +//Les procédures déclarées n'ont pas vocation à être utilisées directement (celà est +// cependant possible). //#define _DEBUG_ #ifdef _DEBUG_ @@ -47,6 +50,9 @@ // Interface C/C++ +// L'utilisateur CALCIUM n'a normalement pas a utliser cette interface +// En C/C++ il utilisera celle définie dans Calcium.c +// En C++/CORBA directement celle de CalciumCxxInterface // En CALCIUM l'utilisation de données de type double // implique des dates de type double, pour les autres @@ -91,30 +97,28 @@ ecp_fin_ (void * component, int code) { double _tf=*tf; \ size_t _nRead=0; \ size_t _bufferLength=bufferLength; \ - CalciumTypes::DependencyType _dependencyType= \ - static_cast(dependencyType); \ \ if ( IsSameType< _name , cplx >::value ) _bufferLength*=2; \ DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1 ------------------" ) \ try { \ CalciumInterface::ecp_lecture< _type, _name >( *_component, \ - _dependencyType, \ + dependencyType, \ _ti, _tf, *i, \ nomvar, \ _bufferLength, _nRead, *data); \ } catch ( const CalciumException & ex) { \ DEBTRACE( ex.what() ); \ return ex.getInfo(); \ - } catch ( ... ) { \ - std::cerr << "Unexpected exception " << std::endl; \ - return CalciumTypes::CPATAL; \ + } catch ( ... ) { \ + std::cerr << "Unexpected exception " << std::endl; \ + return CalciumTypes::CPATAL; \ } \ if ( IsSameType< _name , cplx >::value ) { *nRead=_nRead/2; \ DEBTRACE( "-------- CalciumInterface(lecture Inter Part) IsSameType cplx -------------" ) \ DEBTRACE( "-------- CalciumInterface(lecture Inter Part) _nRead : " << _nRead ) \ DEBTRACE( "-------- CalciumInterface(lecture Inter Part) *nRead : " << *nRead ) \ } else *nRead = _nRead; \ - if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) \ + if (dependencyType == CalciumTypes::CP_SEQUENTIEL ) \ *ti=(CalTimeType< _type _qual >::TimeType)(_ti); \ DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) \ return CalciumTypes::CPOK; \ @@ -139,10 +143,9 @@ ecp_fin_ (void * component, int code) { DEBTRACE( "-------- CalciumInterface(ecriture Inter Part) MARK 1 ------------------" ) \ try { \ /*printf("-------- CalciumInterface(ecriture Inter Part), cp_name : Nom de la var. de type %s : %s\n",#_type,nomvar);*/ \ - std::string essai(nomvar); \ - DEBTRACE( "----------->-" << nomvar ) \ + DEBTRACE( "----------->-" << nomvar ) \ CalciumInterface::ecp_ecriture< _type, _name >( *_component, \ - static_cast(dependencyType), \ + dependencyType, \ _t,i,nomvar,_bufferLength,*data); \ } catch ( const CalciumException & ex) { \ std::cerr << ex.what() << std::endl; \ @@ -159,24 +162,29 @@ ecp_fin_ (void * component, int code) { #define STAR * // Le premier argument est utilisée : -// - comme suffixe dans la définition des noms ecp_lecture_ ecp_ecriture_ ecp_free_ +// - comme suffixe dans la définition des noms ecp_lecture_ , ecp_ecriture_ et ecp_free_ // - comme second argument template à l'appel de la méthode C++ correspondante -// ( le port correspondant est alors obtenu par un trait) +// ( le type de 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 +// (pour typer les données passées en paramètre ) +// Notons que dans le cas CALCIUM_C2CPP_INTERFACE_(int,int,), le type int n'existe pas +// en CORBA, le port CALCIUM correspondant utilise une séquence de long. La méthode +// C++ CALCIUM de lecture repère cette différence de type et charge +// le manipulateur de données d'effectuer une recopie (qui fonctionne si les types sont compatibles). CALCIUM_C2CPP_INTERFACE_(int,int,); CALCIUM_C2CPP_INTERFACE_(float,float, ); CALCIUM_C2CPP_INTERFACE_(double,double,); -CALCIUM_C2CPP_INTERFACE_(bool,bool,); +// Fonctionne mais essai suivant pour simplification de Calcium.c CALCIUM_C2CPP_INTERFACE_(bool,bool,); +CALCIUM_C2CPP_INTERFACE_(bool,int,); 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, @@ -187,7 +195,7 @@ CALCIUM_C2CPP_INTERFACE_(str,char*,); // double _tf=*tf; // size_t _nRead=0; // size_t _bufferLength=bufferLength; -// CalciumTypes::DependencyType _dependencyType= +// CalciumTypes::DependencyType dependencyType= // static_cast(dependencyType); // // - GERER POINTEUR NULL : NOTHING TODO @@ -196,7 +204,7 @@ CALCIUM_C2CPP_INTERFACE_(str,char*,); // DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1 ------------------" ) // try { // CalciumInterface::ecp_lecture< char*, char* >( *_component, -// _dependencyType, +// dependencyType, // _ti, _tf, *i, // nomvar, // _bufferLength, _nRead, *data); @@ -207,7 +215,7 @@ CALCIUM_C2CPP_INTERFACE_(str,char*,); // *nRead = _nRead; -// if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) +// if (dependencyType == CalciumTypes::CP_SEQUENTIEL ) // *ti=(float)(_ti); // DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) ; diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx index d05cc440d..874345e3a 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx @@ -32,9 +32,10 @@ #include "Superv_Component_i.hxx" // PROVIDES PORT TRAITS -struct UnknownProvidesPortType {}; +template struct UnknownProvidesPortType {}; + template struct ProvidesPortTraits { - typedef UnknownProvidesPortType PortType; + typedef UnknownProvidesPortType PortType; }; template <> struct ProvidesPortTraits { typedef calcium_integer_port_provides PortType; @@ -57,24 +58,22 @@ struct cplx {}; template <> struct ProvidesPortTraits { typedef calcium_complex_port_provides PortType; }; -// Défénition du type str pour obtenir le type de port +// Définition du type str pour obtenir le type de port // correspondant struct str {}; template <> struct ProvidesPortTraits { typedef calcium_string_port_provides PortType; }; - template <> struct ProvidesPortTraits { - 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 struct UnknownUsesPortType {}; template struct UsesPortTraits { - typedef UnknownUsesPortType PortType; + typedef UnknownUsesPortType PortType; }; template <> struct UsesPortTraits { typedef calcium_integer_port_uses PortType; diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx index 21f338497..0ff10190d 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx @@ -33,22 +33,25 @@ #include #include "CalciumPortTraits.hxx" -template +template struct Copy2CorbaSpace { template - static void apply( T1 * & corbaData, T2 & data, size_t nRead){ + static void apply( T1 * & corbaData, T2 const & data, size_t nRead){ typedef typename ProvidesPortTraits::PortType PortType; //typedef typename UsesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; + //ESSAI: typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; #ifdef _DEBUG_ std::cerr << "-------- Copy2CorbaSpace MARK 1 ------------------" << std::endl; #endif - // Crée le type corba à partir du data sans lui en donner la propriété - corbaData = DataManipulator::create(nRead,&data,false); + // Crée le type corba à partir du data sans lui en donner la propriété. + // Le const_cast supprime le caractère const du type T2 const & de data car + // DataManipulator::create n'a pas le caractère const sur son paramètre data pour le + // cas de figure où la propriété de la donnée lui est donnée. + corbaData = DataManipulator::create(nRead,const_cast (&data),false); #ifdef _DEBUG_ std::cerr << "-------- Copy2CorbaSpace MARK 2 --(dataPtr : " << DataManipulator::getPointer(corbaData,false)<<")----------------" << std::endl; @@ -58,15 +61,15 @@ struct Copy2CorbaSpace { }; // Cas ou il faut effectuer une recopie -template <> struct -Copy2CorbaSpace { +template struct +Copy2CorbaSpace { template - static void apply( T1 * & corbaData, T2 & data, size_t nRead){ + static void apply( T1 * & corbaData, T2 const & data, size_t nRead){ typedef typename ProvidesPortTraits::PortType PortType; // typedef typename UsesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; +//ESSAI: typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; corbaData = DataManipulator::create(nRead); diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx index be959838e..eab7a2a5d 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx @@ -38,37 +38,48 @@ //Les demandes de copies vers l'espace utilisateur //proviennent d'une procédure de lecture + //Cas du zero copie -template +template struct Copy2UserSpace{ template 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::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); + typedef typename DataManipulator::InnerType InnerType; + + // OLD:Devient propriétaire des données contenues dans la structure CORBA + // OLD:(allouées par allocbuff() pour une séquence) + // OLD:Le client est propriétaire des données. + // OLD:Il doit cependant être attentif au fait que s'il les modifie, + // OLD:une nouvelle demande de lecture lui fournira les données modifiées. + // OLD:TODO : Si plusieurs lecteurs demandent la même donnée, + // OLD: ? qui devient le propriétaire? --> Forcément le premier car + // OLD: ensuite la séquence n'est plus propriétaire et rendra un pointeur NULL. + // OLD: NO: Le port devrait resté propriétaire du contenu de la séquence + // OLD: NO: L'utilisateur doit de toute les façons utiliser les données reçues en + // OLD: NO: lecture seulement car si une nouvelle demande de lecture est formulée + // OLD: NO: pour ces données, les eventuelles modifications seraient visibles ! + // OLD:YES : La solution de donner la propriété à l'utilisateur est convenable car si + // OLD:le port déréférence ces données (garbage collecteur, niveau) le buffer + // OLD:reste disponible à l'ulisateur en lecture et écriture + // OLD:Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK) + // OLD:du coup quid d'une nouvelle demande de lecture : A TESTER + + // Le PORT doit être capable de répondre aux demandes de lecture + // multiples d'une donnée pour une même estampille et doit donc garder un pointeur valide + // sur le buffer. Il se pose cependant un problème s'il décide + // de supprimer la donnée alors que des client utilise le buffer (historique) ! + // La seule façon de gérer proprement cette situation est d'utiliser un shared_pointer (TODO). + // Pour l'instant l'utilisateur du mode zero copie doit s'assurer que le niveau d'historique + // utilisé par le port est compatible avec son utilisation des buffers. Il doit + // être également conscient que s'il modifie le buffer, il est modifier pour tous les + // utilisateurs actuels et futurs. + + //REF: InnerType * dataPtr = DataManipulator::getPointer(corbaData,true); + // Laisse la propriété des données à la structure CORBA + // (buffer allouée par allocbuff() pour une séquence) + InnerType * dataPtr = DataManipulator::getPointer(corbaData,false); // Cette ligne poserait uun problème dans la méthode appelante, si elle // ne testait pas que les types utilisateurs et CORBA sont identiques : @@ -85,60 +96,57 @@ struct Copy2UserSpace{ }; // Cas où il faut effectuer une recopie -template <> -struct Copy2UserSpace { +template +struct Copy2UserSpace { //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead template 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::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; typedef typename DataManipulator::InnerType InnerType; #ifdef _DEBUG_ 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 MARK 1a --dataPtr("<(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 MARK 1b --data("<(std::cerr," ")); - for (int i=0; i< DataManipulator::size(corbaData); ++i) - fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); - std::cerr << std::endl; + // 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 MARK 1a --dataPtr("<(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; + //Cette affichage peut provoquer la détection d'écriture d'un espace non initailisé. + std::cerr << "-------- Copy2UserSpace MARK 1b --data("<(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. + // 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. + // 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); - DataManipulator::copy(corbaData,data,nRead); + //std::copy(dataPtr,dataPtr+nRead,data); + DataManipulator::copy(corbaData,data,nRead); #ifdef _DEBUG_ - tmpData = data; - std::cerr << "-------- Copy2UserSpace MARK 1c --data("<(std::cerr," ")); - for (int i=0; i< DataManipulator::size(corbaData); ++i) - fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); - std::cerr << std::endl; + tmpData = data; + std::cerr << "-------- Copy2UserSpace MARK 1c --data("<(std::cerr," ")); + for (int i=0; i< DataManipulator::size(corbaData); ++i) + fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]); + std::cerr << std::endl; #endif } @@ -147,31 +155,24 @@ struct Copy2UserSpace { // Désallocation des buffers si necessaire -template +template struct DeleteTraits { template static void apply(T * dataPtr) { - typedef typename ProvidesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; - //typedef typename DataManipulator::Type DataType; // Attention != T + 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 : // 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 ? - } }; // Désalocation du buffer intermédiaire -// dans le cas de types utilisateur/CORBA différents -template <> -struct DeleteTraits{ +// dans le cas d'un type Utilisateur différent du type CORBA +template +struct DeleteTraits< false, DataManipulator > { template static void apply(T * dataPtr) { delete[] dataPtr; } diff --git a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am index 3bdabe92a..3792dc9a2 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am +++ b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am @@ -57,6 +57,7 @@ salomeinclude_HEADERS = calcium_port_factory.hxx \ calcium.h \ Calcium.hxx \ calciumP.h \ + calciumE.h \ version.h \ calcium.hf diff --git a/src/DSC/DSC_User/Datastream/Calcium/calcium.h b/src/DSC/DSC_User/Datastream/Calcium/calcium.h index b90d5499f..a1d87b295 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/calcium.h +++ b/src/DSC/DSC_User/Datastream/Calcium/calcium.h @@ -29,6 +29,7 @@ #ifndef __CALCIUM_H #define __CALCIUM_H +#include #include #include diff --git a/src/DSC/DSC_User/Datastream/Calcium/calciumE.h b/src/DSC/DSC_User/Datastream/Calcium/calciumE.h new file mode 100644 index 000000000..49c9e57d8 --- /dev/null +++ b/src/DSC/DSC_User/Datastream/Calcium/calciumE.h @@ -0,0 +1,401 @@ +/* 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.h + * Author : Eric Fayolle (EDF) + * Module : KERNEL + */ + +/* Outils d'Aide au Couplage de Code de Calcul : $Id$ */ + +#ifndef __CALCIUM_E_H +#define __CALCIUM_E_H + +#include + +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) +#define CPNeedPrototype 1 +#else +#define CPNeedPrototype 0 +#endif + + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* */ +/* */ +/* Fonctions de connexion */ +/* */ +/* */ +extern int ecp_cd( +/* ----- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + char * /* S Nom de l instance appelante*/ +#endif +); + + +/* */ +/* */ +/* Fonction de deconnexion */ +/* */ +/* */ +extern int ecp_fin( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Directive de continuation */ + /* CP_CONT ou CP_ARRET */ +#endif +); + +/* */ +/* */ +/* Fonctions de libération du buffer 0 copy */ +/* */ + + extern void ecp_len_free( +#if CPNeedPrototype + int * +#endif + ); + extern void ecp_lre_free( +#if CPNeedPrototype + float * +#endif + ); + extern void ecp_ldb_free( +#if CPNeedPrototype + double * +#endif + ); + extern void ecp_llo_free( +#if CPNeedPrototype + int * +#endif + ); + extern void ecp_lcp_free( +#if CPNeedPrototype + float * +#endif + ); + extern void ecp_lch_free( +#if CPNeedPrototype + char ** +#endif + ); + + + +/* */ +/* */ +/* Fonctions de lecture bloquante 0 copy */ +/* */ +/* */ +extern int ecp_len( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d'entiers pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_lre( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_ldb( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + double* /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + double* /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + double**/* E/S Tableau de doubles pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_lcp( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues (dimension = 2 * le nombre */ + /* de valeurs lues) */ +#endif +); + +extern int ecp_llo( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d 'entier pour stocker les */ + /* valeurs lues (remplace le logiques) */ +#endif +); + +extern int ecp_lch( +/* ------ */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + char **[]/*E/S Tableau de chaines pour stocker les */ + /* valeurs lues (remplace le logiques) */, + int /* E Taille des chaines du tablaeu */ +#endif +); + + + +/* */ +/* */ +/* Fonctions de lecture non bloquantes */ +/* */ +/* */ +extern int ecp_nlen( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int ** /* E/S Tableau d'entiers pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nlre( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nldb( +/* ------- */ + +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + double */* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + double */* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + double**/* E/S Tableau de doubles pour stocker les */ + /* valeurs lues */ +#endif +); + +extern int ecp_nlcp( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + float **/* E/S Tableau de flottants pour stocker les */ + /* valeurs lues (dimension = 2 * le nombre */ + /* de valeurs lues) */ +#endif +); + +extern int ecp_nllo( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + int **/* E/S Tableau d 'entier pour stocker les */ + /* valeurs lues (remplace le logiques) */ +#endif +); + +extern int ecp_nlch( +/* ------- */ +#if CPNeedPrototype + void * component /* Pointeur de type Superv_Component_i* sur le */ + /* composant SALOME Supervisable */, + int /* E Type de dependance ou de lecture */ + /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */, + float * /* E/S Borne inf de l'intervalle de lecture */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + float * /* E Borne Sup de l'intervalle de lecture */, + int * /* E/S Pas d'iteration a lire */ + /* Retourne le pas lu dans le cas de */ + /* lecture sequentielle */, + char * /* E Nom de la variable a lire */, + int /* E Nombre max de valeurs a lire */, + int * /* S Nombre de valeurs rellement lues */, + char **[]/* E/S Tableau de chaines pour stocker les */ + /* valeurs lues (remplace le logiques) */, + int /* E Taille des chaines du tablaeu */ +#endif +); + + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + + +#endif diff --git a/src/DSC/DSC_User/Datastream/Calcium/calciumf.c b/src/DSC/DSC_User/Datastream/Calcium/calciumf.c index 557e1ed1a..442470f49 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/calciumf.c +++ b/src/DSC/DSC_User/Datastream/Calcium/calciumf.c @@ -116,7 +116,7 @@ void F_FUNC(cplch,CPLCH)(long *compo,int *dep,float *ti,float *tf,int *iter,STR_ *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]); + strncpy(&tab[index * STR_LEN(tab)], tabChaine[index], strlen(tabChaine[index])); fprintf(stderr,"End of CPLCH: %s %f %f \n",cnom,*ti,*tf); if (tabChaine != (char **) NULL) { diff --git a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx index c0adc1853..cbaa6470e 100644 --- a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx +++ b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx @@ -208,19 +208,25 @@ 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 (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 & ) + // La séquence reçue (mais pas le buffer) sera désallouée au retour + // de la méthode CORBA qui a reçu le type CorbaInType en paramètre + // (ex: GenericPort::put) + // REM : Le mapping CORBA du type séquence 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) + // OLD : ATTENTION TESTER p194 si le pointeur est null (release flag==false) + // OLD : -> La séquence n'était pas propriétaire des données ! // 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). + // En collocalité release() renvoie false car + // l'appelé n'est pas propriétaire de la séquence. On effectue alors + // une copie pour éviter de perturber les structures de données de l'appelant. + // En non collocalisé on recrée une séquence avec le buffer de la première dont on + // a demandé la propriété. - // 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 @@ -228,8 +234,8 @@ public: InnerType * p_data = const_cast(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). + // Les données de la nouvelle 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 1(0 copy) bis ------"<< p_data <<"------------" << std::endl; #endif @@ -265,9 +271,13 @@ public: return new seq_T (data); } - // 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 !) + // 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 + // (son pointeur de buffer interne est aussi réinitialisé) + // On détruit également explicitement la séquence (mais pas le buffer !) + // Si ownerShip=False, la séquence reste propriétaire du buffer + // et l'utilisateur devra appeler delete_data sur la séquence contenante pour + // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool ownerShip = false) { InnerType * p_data; if (ownerShip) { @@ -278,9 +288,8 @@ public: return p_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 de désallouer le buffer dont on détient le pointeur après appel + // à la méthode getPointer avec ownerShip=True static inline void relPointer(InnerType * dataPtr) { seq_T::freebuf(dataPtr); } @@ -290,7 +299,7 @@ public: return seq_T::allocbuf(size); } - // Operation de création de la séquence corba soit + // Opération 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 ) @@ -317,7 +326,7 @@ public: 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 + // Le mode de recopie suivant 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 : @@ -331,6 +340,10 @@ public: } // Copie le contenu de la séquence de char* dans le buffer idata de taille isize + // La généralisation de la recopie profonde est difficile du fait que CORBA ne renvoie pas + // pas des objets de haut niveau de type std::vector (avec des interfaces d'accès identiques) + // mais un type simple C comme char *Tab[N]. On doit alors utiliser une méthode de recopie spécifique + // comme l'appel C strcpy. static inline void copy( Type data, char* * const idata, size_t isize ) { char* *dataPtr = getPointer(data,false); @@ -415,9 +428,13 @@ public: delete data; } - // Récupère un pointeur sur les données de type InnerType contenue dans la séquence - // si ownership=True, l'utilisateur devra appeler relPointer - // si ownership=False, l'utilisateur devra appeler delete_data sur la séquence contenante + // 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 + // (son pointeur de buffer interne est aussi réinitialisé) + // On détruit également explicitement la séquence (mais pas le buffer !) + // Si ownerShip=False, la séquence reste propriétaire du buffer + // et l'utilisateur devra appeler delete_data sur la séquence contenante pour + // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) { InnerType * p_data; if (getOwnerShip) { diff --git a/src/DSC/DSC_User/Superv_Component_i.cxx b/src/DSC/DSC_User/Superv_Component_i.cxx index 3f2a3e972..4a6449990 100644 --- a/src/DSC/DSC_User/Superv_Component_i.cxx +++ b/src/DSC/DSC_User/Superv_Component_i.cxx @@ -50,6 +50,20 @@ Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, register_factory("PALM", new palm_port_factory()); register_factory("CALCIUM", new calcium_port_factory()); } +Superv_Component_i::Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_DSC_i(orb, poa, container, instanceName, interfaceName) +{ +#ifdef _DEBUG_ + 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()); + register_factory("CALCIUM", new calcium_port_factory()); +} Superv_Component_i::~Superv_Component_i() diff --git a/src/DSC/DSC_User/Superv_Component_i.hxx b/src/DSC/DSC_User/Superv_Component_i.hxx index 174380f05..2c8467e05 100644 --- a/src/DSC/DSC_User/Superv_Component_i.hxx +++ b/src/DSC/DSC_User/Superv_Component_i.hxx @@ -65,6 +65,12 @@ public: const char *instanceName, const char *interfaceName, bool notif = false); + Superv_Component_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool notif = false); virtual ~Superv_Component_i(); // Exceptions declarations. diff --git a/src/Launcher/Launcher.cxx b/src/Launcher/Launcher.cxx index 5caf6a4ce..8a92e1d87 100644 --- a/src/Launcher/Launcher.cxx +++ b/src/Launcher/Launcher.cxx @@ -334,7 +334,10 @@ string Launcher_cpp::buildSalomeCouplingScript(const string fileToExecute, const // ----------------------------------------------- // Code for rank 0 : launch runAppli and a container // RunAppli - tempOutputFile << " ./runAppli --terminal --modules=" ; + if(params.ModulesList.size()>0) + tempOutputFile << " ./runAppli --terminal --modules=" ; + else + tempOutputFile << " ./runAppli --terminal "; for ( int i = 0 ; i < params.ModulesList.size() ; i++ ) { tempOutputFile << params.ModulesList[i] ; if ( i != params.ModulesList.size()-1 ) diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx b/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx index e693d70f4..0c8661430 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_Acomponent_impl.hxx @@ -137,7 +137,7 @@ public: //! method to define if a component is implemented in a dyn lib a python module or an executable /*! - \return an enum SO or PY or EXE + \return an enum SO or PY or EXE or CEXE */ virtual SALOME_ModuleCatalog::ImplType implementation_type(); diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx b/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx index 5fd1ff4e4..88fd5e7bc 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_Handler.cxx @@ -413,6 +413,8 @@ void SALOME_ModuleCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) _aModule.constraint = ""; _aModule.icon=""; _aModule.interfaces.resize(0); + _aModule.implementationType =""; + _aModule.implementationName =""; xmlNodePtr aComponentSubNode = aComponentNode->xmlChildrenNode; while(aComponentSubNode != NULL) diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx b/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx index c63e0cdea..efb997978 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_impl.cxx @@ -36,9 +36,9 @@ using namespace std; #include "utilities.h" #ifdef _DEBUG_ -static int MYDEBUG = 1; +static int MYDEBUG = 0; #else -static int MYDEBUG = 1; +static int MYDEBUG = 0; #endif static const char* SEPARATOR = "::"; @@ -747,6 +747,8 @@ void SALOME_ModuleCatalogImpl::duplicate C_corba.type = ComponentTypeConvert[C_parser.type]; if(C_parser.implementationType == "EXE") C_corba.implementationType=SALOME_ModuleCatalog::EXE; + else if(C_parser.implementationType == "CEXE") + C_corba.implementationType=SALOME_ModuleCatalog::CEXE; else if(C_parser.implementationType == "PY") C_corba.implementationType=SALOME_ModuleCatalog::PY; else diff --git a/src/NOTIFICATION_SWIG/Makefile.am b/src/NOTIFICATION_SWIG/Makefile.am index e043680f4..d171e39a5 100644 --- a/src/NOTIFICATION_SWIG/Makefile.am +++ b/src/NOTIFICATION_SWIG/Makefile.am @@ -56,8 +56,6 @@ _libNOTIFICATION_la_CPPFLAGS =\ _libNOTIFICATION_la_LDFLAGS = -module _libNOTIFICATION_la_LIBADD = ../Notification/libSalomeNotification.la -# @PYTHON_LIBS@ - swig_wrap.cpp : $(SWIG_SOURCES) $(SWIG) $(SWIG_FLAGS) -o $@ $< diff --git a/src/NamingService/SALOME_NamingServicePy.py b/src/NamingService/SALOME_NamingServicePy.py index e4a44d309..81ad8d15a 100644 --- a/src/NamingService/SALOME_NamingServicePy.py +++ b/src/NamingService/SALOME_NamingServicePy.py @@ -32,6 +32,7 @@ import sys import time from omniORB import CORBA import CosNaming +import string from string import * from SALOME_utilities import * @@ -88,7 +89,7 @@ class SALOME_NamingServicePy_i(object): #delete first '/' before split Path=Path[1:] - result_resolve_path = split(Path,'/') + result_resolve_path = string.split(Path,'/') if len(result_resolve_path)>1: # A directory is treated (not only an object name) # We had to test if the directory where ObjRef should be recorded @@ -156,7 +157,7 @@ class SALOME_NamingServicePy_i(object): #delete first '/' before split Path=Path[1:] - result_resolve_path = split(Path,'/') + result_resolve_path = string.split(Path,'/') _context_name=[] for i in range(len(result_resolve_path)-1): _context_name.append(CosNaming.NameComponent(result_resolve_path[i],"dir")) @@ -189,7 +190,7 @@ class SALOME_NamingServicePy_i(object): #delete first '/' before split Path=Path[1:] - result_resolve_path = split(Path,'/') + result_resolve_path = string.split(Path,'/') _context_name = [] for i in range(len(result_resolve_path)): _context_name[CosNaming.NameComponent(result_resolve_path[i],"dir")] @@ -204,7 +205,46 @@ class SALOME_NamingServicePy_i(object): MESSAGE ( "Create_Directory : CosNaming.NamingContext.CannotProceed" ) except (CORBA.TRANSIENT,CORBA.OBJECT_NOT_EXIST,CORBA.COMM_FAILURE): MESSAGE ( "Create_Directory : CORBA.TRANSIENT,CORBA.OBJECT_NOT_EXIST,CORBA.COMM_FAILURE" ) - - - + def Destroy_Name(self,Path): + resolve_path=string.split(Path,'/') + if resolve_path[0] == '': del resolve_path[0] + dir_path=resolve_path[:-1] + context_name=[] + for e in dir_path: + context_name.append(CosNaming.NameComponent(e,"dir")) + context_name.append(CosNaming.NameComponent(resolve_path[-1],"object")) + + try: + self._root_context.unbind(context_name) + except CosNaming.NamingContext.NotFound, ex: + return + except CORBA.Exception,ex: + return + + def Destroy_FullDirectory(self,Path): + context_name=[] + for e in string.split(Path,'/'): + if e == '':continue + context_name.append(CosNaming.NameComponent(e,"dir")) + + try: + context=self._root_context.resolve(context_name) + except CosNaming.NamingContext.NotFound, ex: + return + except CORBA.Exception,ex: + return + + bl,bi=context.list(0) + if bi is not None: + ok,b=bi.next_one() + while(ok): + for s in b.binding_name : + if s.kind == "object": + context.unbind([s]) + elif s.kind == "dir": + context.unbind([s]) + ok,b=bi.next_one() + + context.destroy() + self._root_context.unbind(context_name) diff --git a/src/Registry/RegistryService.hxx b/src/Registry/RegistryService.hxx index 9b26f41f8..bc6097fcd 100644 --- a/src/Registry/RegistryService.hxx +++ b/src/Registry/RegistryService.hxx @@ -89,7 +89,7 @@ public : void SessionName( const char *sessionName ) ; - void SetOrb( CORBA::ORB_ptr orb ) { _orb = orb; return; } + void SetOrb( CORBA::ORB_ptr orb ) { _orb = CORBA::ORB::_duplicate(orb); return; } void Shutdown() { if(!CORBA::is_nil(_orb)) _orb->shutdown(0); } diff --git a/src/Registry/SALOME_Registry_Server.cxx b/src/Registry/SALOME_Registry_Server.cxx index 50e608f31..8183340c2 100644 --- a/src/Registry/SALOME_Registry_Server.cxx +++ b/src/Registry/SALOME_Registry_Server.cxx @@ -170,6 +170,7 @@ int main( int argc , char **argv ) ptrRegistry->SessionName( ptrSessionName ) ; ptrRegistry->SetOrb(orb); varComponents = ptrRegistry->_this() ; + ptrRegistry->_remove_ref(); //let poa manage registryservice deletion // The RegistryService must not already exist. try diff --git a/src/ResourcesManager/ResourcesManager.cxx b/src/ResourcesManager/ResourcesManager.cxx index 0d11897a7..ddf3712ff 100644 --- a/src/ResourcesManager/ResourcesManager.cxx +++ b/src/ResourcesManager/ResourcesManager.cxx @@ -30,6 +30,8 @@ #include #include +#include "utilities.h" + #define MAX_SIZE_FOR_HOSTNAME 256; using namespace std; @@ -44,7 +46,7 @@ ResourcesManager_cpp:: ResourcesManager_cpp(const char *xmlFilePath) : _path_resources(xmlFilePath) { - cerr << "ResourcesManager_cpp constructor" << endl; + MESSAGE ( "ResourcesManager_cpp constructor" ); } //============================================================================= @@ -60,7 +62,7 @@ ResourcesManager_cpp(const char *xmlFilePath) : ResourcesManager_cpp::ResourcesManager_cpp() { - cerr << "ResourcesManager_cpp constructor" << endl; + MESSAGE ( "ResourcesManager_cpp constructor" ); _isAppliSalomeDefined = (getenv("APPLI") != 0); if (_isAppliSalomeDefined) @@ -78,7 +80,7 @@ ResourcesManager_cpp::ResourcesManager_cpp() } ParseXmlFile(); - cerr << "ResourcesManager_cpp constructor end"; + MESSAGE ( "ResourcesManager_cpp constructor end" ); } //============================================================================= @@ -89,7 +91,7 @@ ResourcesManager_cpp::ResourcesManager_cpp() ResourcesManager_cpp::~ResourcesManager_cpp() { - cerr << "ResourcesManager_cpp destructor" << endl; + MESSAGE ( "ResourcesManager_cpp destructor" ); } //============================================================================= @@ -116,7 +118,7 @@ ResourcesManager_cpp::GetFittingResources(const machineParams& params, ParseXmlFile(); const char *hostname = params.hostname.c_str(); - cerr << "GetFittingResources " << hostname << " " << GetHostname().c_str() << endl; + INFOS ( "GetFittingResources " << hostname << " " << GetHostname().c_str() ); if (hostname[0] != '\0'){ // cerr << "ResourcesManager_cpp::GetFittingResources : hostname specified" << endl; @@ -155,7 +157,7 @@ ResourcesManager_cpp::GetFittingResources(const machineParams& params, } if(cpt==0){ // --- user specified an unknown hostame so notify him. - cerr << "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" << endl; + MESSAGE ( "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" ); throw ResourcesException("unknown host"); } } @@ -271,7 +273,7 @@ void ResourcesManager_cpp::WriteInXmlFile() if (aFile == NULL) { - cerr << "Error opening file !" << endl; + INFOS ( "Error opening file !" ); return; } @@ -286,14 +288,14 @@ void ResourcesManager_cpp::WriteInXmlFile() int isOk = xmlSaveFile(aFilePath, aDoc); if (!isOk) - cerr << "Error while XML file saving." << endl; + INFOS ( "Error while XML file saving." ); // Free the document xmlFreeDoc(aDoc); fclose(aFile); - cerr << "WRITING DONE!" << endl; + INFOS ( "WRITING DONE!" ); } //============================================================================= @@ -317,7 +319,7 @@ const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile() if (aDoc != NULL) handler->ProcessXmlDocument(aDoc); else - cerr << "ResourcesManager_cpp: could not parse file "<< aFilePath << endl; + INFOS ( "ResourcesManager_cpp: could not parse file "<< aFilePath ); // Free the document xmlFreeDoc(aDoc); @@ -325,7 +327,7 @@ const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile() fclose(aFile); } else - cerr << "ResourcesManager_cpp: file "< #include +#include "utilities.h" using namespace std; +#ifdef _DEBUG_ +static int MYDEBUG = 1; +#else +static int MYDEBUG = 0; +#endif + //============================================================================= /*! * Constructor @@ -97,6 +104,8 @@ SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) { +// if (MYDEBUG) cout << "Begin parse document" << endl; + // Empty private elements _resources_list.clear(); @@ -298,22 +307,26 @@ void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc) aCurNode = aCurNode->next; } -#ifdef _DEBUG_ - for (map::const_iterator iter = - _resources_list.begin(); - iter != _resources_list.end(); - iter++) - { - std::cerr << (*iter).second.HostName << std::endl; - std::cerr << (*iter).second.Alias << std::endl; - std::cerr << (*iter).second.UserName << std::endl; - std::cerr << (*iter).second.AppliPath << std::endl; - std::cerr << (*iter).second.OS << std::endl; - std::cerr << (*iter).second.Protocol << std::endl; - std::cerr << (*iter).second.Mode << std::endl; - } -#endif - + // For debug only + if (MYDEBUG) + { + for (map::const_iterator iter = + _resources_list.begin(); + iter != _resources_list.end(); + iter++) + { + SCRUTE((*iter).second.HostName); + SCRUTE((*iter).second.Alias); + SCRUTE((*iter).second.UserName); + SCRUTE((*iter).second.AppliPath); + SCRUTE((*iter).second.OS); + SCRUTE((*iter).second.Protocol); + SCRUTE((*iter).second.Mode); + } + +// cout << "This is the end of document" << endl; +// } + } } diff --git a/src/ResourcesManager/SALOME_ResourcesManager.cxx b/src/ResourcesManager/SALOME_ResourcesManager.cxx index 2d6224d75..90f273d69 100644 --- a/src/ResourcesManager/SALOME_ResourcesManager.cxx +++ b/src/ResourcesManager/SALOME_ResourcesManager.cxx @@ -218,12 +218,12 @@ Engines::MachineParameters* SALOME_ResourcesManager::GetMachineParameters(const p_ptr->mpiImpl = "mpich2"; else if( resource.mpi == openmpi ) p_ptr->mpiImpl = "openmpi"; + else if( resource.mpi == slurm ) + p_ptr->mpiImpl = "slurm"; if( resource.Batch == pbs ) p_ptr->batch = "pbs"; else if( resource.Batch == lsf ) p_ptr->batch = "lsf"; - else if( resource.Batch == slurm ) - p_ptr->batch = "slurm"; return p_ptr; } diff --git a/src/SALOMELocalTrace/LocalTraceBufferPool.hxx b/src/SALOMELocalTrace/LocalTraceBufferPool.hxx index bd55a1dc2..27dbf891a 100644 --- a/src/SALOMELocalTrace/LocalTraceBufferPool.hxx +++ b/src/SALOMELocalTrace/LocalTraceBufferPool.hxx @@ -26,7 +26,7 @@ #include "SALOME_LocalTrace.hxx" -#define TRACE_BUFFER_SIZE 256 // number of entries in circular buffer +#define TRACE_BUFFER_SIZE 512 // number of entries in circular buffer // must be power of 2 #define MAX_TRACE_LENGTH 1024 // messages are truncated at this size diff --git a/src/SALOMELocalTrace/utilities.h b/src/SALOMELocalTrace/utilities.h index c20c835a0..8aced915f 100644 --- a/src/SALOMELocalTrace/utilities.h +++ b/src/SALOMELocalTrace/utilities.h @@ -55,6 +55,11 @@ #define MESS_END std::endl; LocalTraceBufferPool::instance()->insert(NORMAL_MESS, os.str().c_str()); #define MESS_ABORT std::endl; LocalTraceBufferPool::instance()->insert(ABORT_MESS, os.str().c_str()); +// Macroses for messages with separated structure in c++ file in _DUBUG mode +#define MESSAGE_BEGIN(msg) {std::ostringstream ss; ss <<__FILE__ <<" ["<<__LINE__<<"] : "<< msg; LocalTraceBufferPool::instance()->insert(NORMAL_MESS, ss.str().c_str());} +#define MESSAGE_ADD(msg) {std::ostringstream ss; ss << msg; LocalTraceBufferPool::instance()->insert(NORMAL_MESS, ss.str().c_str());} +#define MESSAGE_END(msg) {std::ostringstream ss; ss << msg << std::endl; LocalTraceBufferPool::instance()->insert(NORMAL_MESS, ss.str().c_str());} + // --- Some macros are always defined (without _DEBUG_): for use with release version #define INFOS(msg) {MESS_BEGIN("- Trace ") << msg << MESS_END} diff --git a/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.cxx b/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.cxx index 61239063a..71818af97 100644 --- a/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.cxx +++ b/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.cxx @@ -36,6 +36,7 @@ extern "C" # include "Utils_DESTRUCTEUR_GENERIQUE.hxx" //# include "utilities.h" +# include "LocalTraceBufferPool.hxx" void Nettoyage(); #ifdef _DEBUG_ @@ -83,6 +84,8 @@ public : DESTRUCTEUR_GENERIQUE_::Destructeurs = new std::list ; // Destructeur alloue dynamiquement (cf. ci-dessous) , // il est utilise puis detruit par la fonction Nettoyage + //To be sure the trace singleton will be the last one to be destroyed initialize it here before calling atexit + LocalTraceBufferPool::instance(); int cr = atexit( Nettoyage ); // execute Nettoyage lors de exit, aprs la destruction des donnees statiques ! assert(cr==0) ; ATEXIT_Done = true ; diff --git a/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx b/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx index 9ae866266..54e0bcd22 100644 --- a/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx +++ b/src/Utils/Utils_DESTRUCTEUR_GENERIQUE.hxx @@ -140,4 +140,4 @@ private : }; -# endif /* # if !defined( __SINGLETON__H__ ) */ +# endif /* # if !defined( __DESTRUCTEUR_GENERIQUE__H__ ) */ -- 2.39.2