diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 4d01d5295fe..e1d333fd78b 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -26,22 +26,42 @@ import cgitb import errno +import heapq import logging import logging.handlers import os +import platform +import release import socket import sys import threading import time -import release -from pprint import pformat import warnings -import heapq +from pprint import pformat # TODO modules that import netsvc only for things from loglevels must be changed to use loglevels. from loglevels import * import tools +def close_socket(sock): + """ Closes a socket instance cleanly + + :param sock: the network socket to close + :type sock: socket.socket + """ + try: + sock.shutdown(socket.SHUT_RDWR) + except socket.error, e: + ## On OSX, socket shutdowns both sides if any side closes it + ## causing an error 57 'Socket is not connected' on shutdown + ## of the other side (or something), see + ## http://bugs.python.org/issue4397 + ## note: stdlib fixed test, not behavior + if e.errno != errno.ENOTCONN or platform.system() != 'Darwin': + raise + sock.close() + + class Service(object): """ Base class for *Local* services @@ -381,19 +401,7 @@ class Server: return '\n'.join(res) def _close_socket(self): - if os.name != 'nt': - try: - self.socket.shutdown(getattr(socket, 'SHUT_RDWR', 2)) - except socket.error, e: - if e.errno != errno.ENOTCONN: raise - # OSX, socket shutdowns both sides if any side closes it - # causing an error 57 'Socket is not connected' on shutdown - # of the other side (or something), see - # http://bugs.python.org/issue4397 - self.__logger.debug( - '"%s" when shutting down server socket, ' - 'this is normal under OS X', e) - self.socket.close() + close_socket(self.socket) class OpenERPDispatcherException(Exception): def __init__(self, exception, traceback): diff --git a/openerp/service/netrpc_server.py b/openerp/service/netrpc_server.py index ac3cd724a45..b4d5a74dc48 100644 --- a/openerp/service/netrpc_server.py +++ b/openerp/service/netrpc_server.py @@ -45,16 +45,6 @@ class TinySocketClientThread(threading.Thread, netsvc.OpenERPDispatcher): self.sock.settimeout(1200) self.threads = threads - def __del__(self): - if self.sock: - try: - self.socket.shutdown( - getattr(socket, 'SHUT_RDWR', 2)) - except Exception: - pass - # That should garbage-collect and close it, too - self.sock = None - def run(self): self.running = True try: @@ -93,8 +83,7 @@ class TinySocketClientThread(threading.Thread, netsvc.OpenERPDispatcher): logging.getLogger('web-services').exception("netrpc: cannot deliver exception message to client") break - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() + netsvc.close_socket(self.sock) self.sock = None self.threads.remove(self) self.running = False diff --git a/openerp/tiny_socket.py b/openerp/tiny_socket.py index 44f7db04f01..cc0f09ec976 100644 --- a/openerp/tiny_socket.py +++ b/openerp/tiny_socket.py @@ -24,6 +24,8 @@ import cPickle import cStringIO import marshal +import netsvc + class Myexception(Exception): """ custome exception object store @@ -56,8 +58,7 @@ class mysocket: self.sock.connect((host, int(port))) def disconnect(self): - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() + netsvc.close_socket(self.sock) def mysend(self, msg, exception=False, traceback=None): msg = cPickle.dumps([msg,traceback])