[IMP] OSX handling of socket shutdown in TinySocketClientThread

When the client closes its socket, on OSX it closes the server one as well, leading to an errno.ENOTCONN when trying to shut it down.

Also use the unified socket-closing function to handle tinysocket

bzr revid: xmo@openerp.com-20110616102624-vixxow6twsx7j84s
This commit is contained in:
Xavier Morel 2011-06-16 12:26:24 +02:00
parent abb606aa7c
commit 012c93ae40
3 changed files with 28 additions and 30 deletions

View File

@ -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):

View File

@ -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

View File

@ -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])