2 # -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE
5 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
28 import cPickle as pickle #@UnusedImport
30 import pickle #@Reimport
32 __PORT_MIN_NUMBER = 2810
33 __PORT_MAX_NUMBER = 2910
37 logger = logging.getLogger(__name__)
38 # logger.setLevel(logging.DEBUG)
39 logger.setLevel(logging.INFO)
40 ch = logging.StreamHandler()
41 ch.setLevel(logging.DEBUG)
42 formatter = logging.Formatter("%(levelname)s:%(threadName)s:%(message)s")
43 ch.setFormatter(formatter)
47 logger = createLogger()
49 #------------------------------------
51 def __acquire_lock(lock):
52 if sys.platform == "win32":
54 # lock 1 byte: file is supposed to be zero-byte long
55 msvcrt.locking(lock.fileno(), msvcrt.LK_LOCK, 1)
58 fcntl.flock(lock, fcntl.LOCK_EX)
60 def __release_lock(lock):
61 if sys.platform == "win32":
63 msvcrt.locking(lock.fileno(), msvcrt.LK_UNLCK, 1)
66 fcntl.flock(lock, fcntl.LOCK_UN)
68 #------------------------------------
70 def _getConfigurationFilename():
71 omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
73 from salome_utils import generateFileName
74 portmanager_config = generateFileName(omniorbUserPath,
80 temp = tempfile.NamedTemporaryFile()
81 lock_file = os.path.join(os.path.dirname(temp.name), ".omniORB_PortManager.lock")
84 return (portmanager_config, lock_file)
87 def __isPortUsed(port, busy_ports):
88 return (port in busy_ports) or __isNetworkConnectionActiveOnPort(port)
91 def __isNetworkConnectionActiveOnPort(port):
92 # :NOTE: Under windows:
93 # netstat options -l and -t are unavailable
94 # grep command is unavailable
95 if sys.platform == "win32":
96 cmd = ['netstat','-a','-n','-p tcp']
98 cmd = ['netstat','-ant']
103 from subprocess import Popen, PIPE, STDOUT
104 p = Popen(cmd, stdout=PIPE, stderr=STDOUT)
105 out, err = p.communicate()
107 print "Error when trying to access active network connections."
110 traceback.print_exc()
114 buf = StringIO.StringIO(out)
115 ports = buf.readlines()
116 # search for TCP - LISTEN connections
118 regObj = re.compile( ".*tcp.*:([0-9]+).*:.*listen", re.IGNORECASE );
121 p = int(regObj.match(item).group(1))
122 if p == port: return True
128 def getPort(preferedPort=None):
129 logger.debug("GET PORT")
131 config_file, lock_file = _getConfigurationFilename()
132 oldmask = os.umask(0)
133 with open(lock_file, 'w') as lock:
138 config = {'busy_ports':[]}
139 logger.debug("read configuration file")
141 with open(config_file, 'r') as f:
142 config = pickle.load(f)
144 logger.info("Problem loading PortManager file: %s"%config_file)
145 # In this case config dictionary is reset
147 logger.debug("load busy_ports: %s"%str(config["busy_ports"]))
150 ports_info = config["busy_ports"]
151 busy_ports = [x[0] for x in ports_info]
153 if not port or __isPortUsed(port, busy_ports):
154 port = __PORT_MIN_NUMBER
155 while __isPortUsed(port, busy_ports):
156 if port == __PORT_MAX_NUMBER:
158 msg += "Can't find a free port to launch omniNames\n"
159 msg += "Try to kill the running servers and then launch SALOME again.\n"
160 raise RuntimeError, msg
161 logger.debug("Port %s seems to be busy"%str(port))
162 if not port in busy_ports:
163 config["busy_ports"].append((port,"other"))
165 logger.debug("found free port: %s"%str(port))
166 config["busy_ports"].append((port,"this"))
168 # write config, for this application only (i.e. no 'other' ports)
169 logger.debug("all busy_ports: %s"%str(config["busy_ports"]))
170 ports_info = config["busy_ports"]
171 config["busy_ports"] = [x for x in ports_info if x[1] == "this"]
172 logger.debug("write busy_ports: %s"%str(config["busy_ports"]))
174 with open(config_file, 'w') as f:
175 pickle.dump(config, f)
184 logger.debug("get port: %s"%str(port))
188 def releasePort(port):
190 logger.debug("RELEASE PORT (%s)"%port)
192 config_file, lock_file = _getConfigurationFilename()
193 oldmask = os.umask(0)
194 with open(lock_file, 'w') as lock:
199 config = {'busy_ports':[]}
200 logger.debug("read configuration file")
202 with open(config_file, 'r') as f:
203 config = pickle.load(f)
204 except IOError: # empty file
207 logger.debug("load busy_ports: %s"%str(config["busy_ports"]))
209 # remove port from list
210 ports_info = config["busy_ports"]
211 config["busy_ports"] = [x for x in ports_info if x[0] != port]
213 # write config, for this application only (i.e. no 'other' ports)
214 logger.debug("all busy_ports: %s"%str(config["busy_ports"]))
215 ports_info = config["busy_ports"]
216 config["busy_ports"] = [x for x in ports_info if x[1] == "this"]
217 logger.debug("write busy_ports: %s"%str(config["busy_ports"]))
219 with open(config_file, 'w') as f:
220 pickle.dump(config, f)
227 logger.debug("released port port: %s"%str(port))
233 config_file, lock_file = _getConfigurationFilename()
234 oldmask = os.umask(0)
235 with open(lock_file, 'w') as lock:
240 config = {'busy_ports':[]}
241 logger.debug("read configuration file")
243 with open(config_file, 'r') as f:
244 config = pickle.load(f)
245 except IOError: # empty file
248 logger.debug("load busy_ports: %s"%str(config["busy_ports"]))
250 # Scan all possible ports to determine which ones are owned by other applications
251 ports_info = config["busy_ports"]
252 busy_ports = [x[0] for x in ports_info]
253 for port in range(__PORT_MIN_NUMBER, __PORT_MAX_NUMBER):
254 if __isPortUsed(port, busy_ports):
255 logger.debug("Port %s seems to be busy"%str(port))
256 if not port in busy_ports:
257 config["busy_ports"].append((port,"other"))
259 logger.debug("all busy_ports: %s"%str(config["busy_ports"]))
261 ports_info = config["busy_ports"]
262 ports_info.sort(key=lambda x: x[0])