X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=bin%2FPortManager.py;h=53ebacea9a7c9e86b59bd0958ee0b1234407c87c;hb=d1cae124bfb0155567da286f2cfd738e3411cb3b;hp=71143075f1f895e6557d6fa78e855445ca7a1b7a;hpb=57a707f6de766d833df53815664023a3903c5691;p=modules%2Fkernel.git diff --git a/bin/PortManager.py b/bin/PortManager.py index 71143075f..53ebacea9 100644 --- a/bin/PortManager.py +++ b/bin/PortManager.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -8,7 +8,7 @@ # 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. +# version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -21,27 +21,19 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import multiprocessing -import time -import socket - import os import sys -import threading -import SocketServer try: - import cPickle as pickle + import cPickle as pickle #@UnusedImport except: - import pickle - -import struct -import ctypes + import pickle #@Reimport import logging def createLogger(): logger = logging.getLogger(__name__) # logger.setLevel(logging.DEBUG) + logger.setLevel(logging.INFO) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter("%(levelname)s:%(threadName)s:%(message)s") @@ -51,43 +43,26 @@ def createLogger(): # logger = createLogger() - -if sys.platform == 'win32': - import multiprocessing.reduction # make sockets pickable/inheritable - -multiprocessing.freeze_support() # Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. - #------------------------------------ -# A file locker (Linux only) -import fcntl -class PortManagerLock: - def __init__(self, filename, readonly=False, blocking=True): - # This will create it if it does not exist already - logger.debug("Create lock on %s"%filename) - self.__readonly = readonly - self.__blocking = blocking - self.__filename = filename - flag = 'w' - if self.__readonly: - flag = 'r' - self.handle = open(self.__filename, 'a+') - - def acquire(self): - mode = fcntl.LOCK_EX - if not self.__blocking: # Raise an IOError exception if file has already been locked - mode = mode | fcntl.LOCK_NB - fcntl.flock(self.handle, mode) - logger.debug("lock acquired %s"%self.__blocking) - - def release(self): - fcntl.flock(self.handle, fcntl.LOCK_UN) - logger.debug("lock released") - - def __del__(self): - logger.debug("Close lock file") - self.handle.close() - os.remove(self.__filename) +# A file locker +def __acquire_lock(lock): + if sys.platform == "win32": + import msvcrt + # lock 1 byte: file is supposed to be zero-byte long + msvcrt.locking(lock.fileno(), msvcrt.LK_LOCK, 1) + else: + import fcntl + fcntl.flock(lock, fcntl.LOCK_EX) # +def __release_lock(lock): + if sys.platform == "win32": + import msvcrt + msvcrt.locking(lock.fileno(), msvcrt.LK_UNLCK, 1) + else: + import fcntl + fcntl.flock(lock, fcntl.LOCK_UN) +# +#------------------------------------ def _getConfigurationFilename(): omniorbUserPath = os.getenv("OMNIORB_USER_PATH") @@ -98,7 +73,11 @@ def _getConfigurationFilename(): suffix="PortManager", extension="cfg", hidden=True) - lock_file = portmanager_config + "-lock" + import tempfile + temp = tempfile.NamedTemporaryFile() + lock_file = os.path.join(os.path.dirname(temp.name), ".omniORB_PortManager.lock") + temp.close() + return (portmanager_config, lock_file) # @@ -110,10 +89,26 @@ def __isNetworkConnectionActiveOnPort(port): # :NOTE: Under windows: # netstat options -l and -t are unavailable # grep command is unavailable - from subprocess import Popen, PIPE - (stdout, stderr) = Popen(['netstat','-an'], stdout=PIPE).communicate() + if sys.platform == "win32": + cmd = ['netstat','-a','-n','-p tcp'] + else: + cmd = ['netstat','-ant'] + pass + + err = None + try: + from subprocess import Popen, PIPE, STDOUT + p = Popen(cmd, stdout=PIPE, stderr=STDOUT) + out, err = p.communicate() + except: + print "Error when trying to access active network connections." + if err: print err + import traceback + traceback.print_exc() + return False + import StringIO - buf = StringIO.StringIO(stdout) + buf = StringIO.StringIO(out) ports = buf.readlines() # search for TCP - LISTEN connections import re @@ -124,15 +119,17 @@ def __isNetworkConnectionActiveOnPort(port): if p == port: return True except: pass + return False # def getPort(preferedPort=None): logger.debug("GET PORT") config_file, lock_file = _getConfigurationFilename() + oldmask = os.umask(0) with open(lock_file, 'w') as lock: # acquire lock - fcntl.flock(lock, fcntl.LOCK_EX) + __acquire_lock(lock) # read config config = {'busy_ports':[]} @@ -140,8 +137,9 @@ def getPort(preferedPort=None): try: with open(config_file, 'r') as f: config = pickle.load(f) - except IOError: # empty file - pass + except: + logger.info("Problem loading PortManager file: %s"%config_file) + # In this case config dictionary is reset logger.debug("load busy_ports: %s"%str(config["busy_ports"])) @@ -156,6 +154,9 @@ def getPort(preferedPort=None): msg += "Can't find a free port to launch omniNames\n" msg += "Try to kill the running servers and then launch SALOME again.\n" raise RuntimeError, msg + logger.debug("Port %s seems to be busy"%str(port)) + if not port in config["busy_ports"]: + config["busy_ports"].append(port) port = port + 1 logger.debug("found free port: %s"%str(port)) config["busy_ports"].append(port) @@ -169,10 +170,12 @@ def getPort(preferedPort=None): pass # release lock - fcntl.flock(lock, fcntl.LOCK_UN) + __release_lock(lock) + # - logger.debug("get port: %s"%str(port)) - return port + os.umask(oldmask) + logger.debug("get port: %s"%str(port)) + return port # def releasePort(port): @@ -180,9 +183,10 @@ def releasePort(port): logger.debug("RELEASE PORT (%s)"%port) config_file, lock_file = _getConfigurationFilename() + oldmask = os.umask(0) with open(lock_file, 'w') as lock: # acquire lock - fcntl.flock(lock, fcntl.LOCK_EX) + __acquire_lock(lock) # read config config = {'busy_ports':[]} @@ -211,16 +215,20 @@ def releasePort(port): pass # release lock - fcntl.flock(lock, fcntl.LOCK_UN) + __release_lock(lock) logger.debug("released port port: %s"%str(port)) + + os.umask(oldmask) # def getBusyPorts(): + busy_ports = [] config_file, lock_file = _getConfigurationFilename() + oldmask = os.umask(0) with open(lock_file, 'w') as lock: # acquire lock - fcntl.flock(lock, fcntl.LOCK_EX) + __acquire_lock(lock) # read config config = {'busy_ports':[]} @@ -235,7 +243,8 @@ def getBusyPorts(): busy_ports = config["busy_ports"] # release lock - fcntl.flock(lock, fcntl.LOCK_UN) + __release_lock(lock) - return busy_ports + os.umask(oldmask) + return busy_ports #