[pypy-commit] pypy default: merge branch issue1430
bdkearns
noreply at buildbot.pypy.org
Fri May 2 02:00:20 CEST 2014
Author: Brian Kearns <bdkearns at gmail.com>
Branch:
Changeset: r71165:9fe91ecfce83
Date: 2014-05-01 19:50 -0400
http://bitbucket.org/pypy/pypy/changeset/9fe91ecfce83/
Log: merge branch issue1430
diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py
--- a/pypy/module/_socket/__init__.py
+++ b/pypy/module/_socket/__init__.py
@@ -17,6 +17,8 @@
def startup(self, space):
from rpython.rlib.rsocket import rsocket_startup
rsocket_startup()
+ from pypy.module._socket.interp_func import State
+ space.fromcache(State).startup(space)
def buildloaders(cls):
from rpython.rlib import rsocket
diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py
--- a/pypy/module/_socket/interp_func.py
+++ b/pypy/module/_socket/interp_func.py
@@ -42,8 +42,9 @@
Return the true host name, a list of aliases, and a list of IP addresses,
for a host. The host argument is a string giving a host name or IP number.
"""
+ lock = space.fromcache(State).netdb_lock
try:
- res = rsocket.gethostbyname_ex(host)
+ res = rsocket.gethostbyname_ex(host, lock)
except SocketError, e:
raise converted_error(space, e)
return common_wrapgethost(space, res)
@@ -55,8 +56,9 @@
Return the true host name, a list of aliases, and a list of IP addresses,
for a host. The host argument is a string giving a host name or IP number.
"""
+ lock = space.fromcache(State).netdb_lock
try:
- res = rsocket.gethostbyaddr(host)
+ res = rsocket.gethostbyaddr(host, lock)
except SocketError, e:
raise converted_error(space, e)
return common_wrapgethost(space, res)
@@ -310,3 +312,10 @@
raise OperationError(space.w_ValueError,
space.wrap('Timeout value out of range'))
rsocket.setdefaulttimeout(timeout)
+
+class State(object):
+ def __init__(self, space):
+ self.netdb_lock = None
+
+ def startup(self, space):
+ self.netdb_lock = space.allocate_lock()
diff --git a/pypy/objspace/fake/checkmodule.py b/pypy/objspace/fake/checkmodule.py
--- a/pypy/objspace/fake/checkmodule.py
+++ b/pypy/objspace/fake/checkmodule.py
@@ -10,6 +10,7 @@
mod = __import__('pypy.module.%s' % modname, None, None, ['__doc__'])
# force computation and record what we wrap
module = mod.Module(space, W_Root())
+ module.startup(space)
for name in module.loaders:
seeobj_w.append(module._load_lazily(space, name))
if hasattr(module, 'submodules'):
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -30,7 +30,7 @@
'stdio.h',
'netdb.h',
'arpa/inet.h',
- 'stdint.h',
+ 'stdint.h',
'errno.h',
)
if _HAS_AF_PACKET:
@@ -139,7 +139,7 @@
EAI_SOCKTYPE EAI_SYSTEM
IPPROTO_AH IPPROTO_BIP IPPROTO_DSTOPTS IPPROTO_EGP IPPROTO_EON IPPROTO_ESP
-IPPROTO_FRAGMENT IPPROTO_GGP IPPROTO_GRE IPPROTO_HELLO IPPROTO_HOPOPTS
+IPPROTO_FRAGMENT IPPROTO_GGP IPPROTO_GRE IPPROTO_HELLO IPPROTO_HOPOPTS
IPPROTO_ICMPV6 IPPROTO_IDP IPPROTO_IGMP IPPROTO_IPCOMP IPPROTO_IPIP
IPPROTO_IPV4 IPPROTO_IPV6 IPPROTO_MAX IPPROTO_MOBILE IPPROTO_ND IPPROTO_NONE
IPPROTO_PIM IPPROTO_PUP IPPROTO_ROUTING IPPROTO_RSVP IPPROTO_TCP IPPROTO_TP
@@ -174,7 +174,7 @@
SOCK_DGRAM SOCK_RAW SOCK_RDM SOCK_SEQPACKET SOCK_STREAM
-SOL_SOCKET SOL_IPX SOL_AX25 SOL_ATALK SOL_NETROM SOL_ROSE
+SOL_SOCKET SOL_IPX SOL_AX25 SOL_ATALK SOL_NETROM SOL_ROSE
SO_ACCEPTCONN SO_BROADCAST SO_DEBUG SO_DONTROUTE SO_ERROR SO_EXCLUSIVEADDRUSE
SO_KEEPALIVE SO_LINGER SO_OOBINLINE SO_RCVBUF SO_RCVLOWAT SO_RCVTIMEO
@@ -286,7 +286,7 @@
('nl_pid', rffi.INT),
('nl_groups', rffi.INT)],
ifdef='AF_NETLINK')
-
+
CConfig.addrinfo = platform.Struct('struct addrinfo',
[('ai_flags', rffi.INT),
('ai_family', rffi.INT),
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -18,6 +18,7 @@
from rpython.rlib.objectmodel import instantiate, keepalive_until_here
from rpython.rlib import _rsocket_rffi as _c
from rpython.rlib.rarithmetic import intmask, r_uint
+from rpython.rlib.rthread import dummy_lock
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.lltypesystem.rffi import sizeof, offsetof
INVALID_SOCKET = _c.INVALID_SOCKET
@@ -1124,22 +1125,24 @@
paddr = h_addr_list[i]
return (rffi.charp2str(hostent.c_h_name), aliases, address_list)
-def gethostbyname_ex(name):
- # XXX use gethostbyname_r() if available, and/or use locks if not
+def gethostbyname_ex(name, lock=dummy_lock):
+ # XXX use gethostbyname_r() if available instead of locks
addr = gethostbyname(name)
- hostent = _c.gethostbyname(name)
- return gethost_common(name, hostent, addr)
+ with lock:
+ hostent = _c.gethostbyname(name)
+ return gethost_common(name, hostent, addr)
-def gethostbyaddr(ip):
- # XXX use gethostbyaddr_r() if available, and/or use locks if not
+def gethostbyaddr(ip, lock=dummy_lock):
+ # XXX use gethostbyaddr_r() if available, instead of locks
addr = makeipaddr(ip)
assert isinstance(addr, IPAddress)
- p, size = addr.lock_in_addr()
- try:
- hostent = _c.gethostbyaddr(p, size, addr.family)
- finally:
- addr.unlock()
- return gethost_common(ip, hostent, addr)
+ with lock:
+ p, size = addr.lock_in_addr()
+ try:
+ hostent = _c.gethostbyaddr(p, size, addr.family)
+ finally:
+ addr.unlock()
+ return gethost_common(ip, hostent, addr)
def getaddrinfo(host, port_or_service,
family=AF_UNSPEC, socktype=0, proto=0, flags=0,
diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py
--- a/rpython/rlib/test/test_rsocket.py
+++ b/rpython/rlib/test/test_rsocket.py
@@ -3,6 +3,7 @@
from rpython.rlib.rsocket import *
import socket as cpy_socket
+
def setup_module(mod):
rsocket_startup()
@@ -61,6 +62,43 @@
py.test.fail("could not find the localhost address in %r"
% (address_list,))
+def test_thread_safe_gethostbyname_ex():
+ import threading
+ nthreads = 10
+ domain = 'google.com'
+ result = [0] * nthreads
+ threads = [None] * nthreads
+ lock = threading.Lock()
+ def lookup_name(i):
+ name, aliases, address_list = gethostbyname_ex(domain, lock)
+ if name == domain:
+ result[i] += 1
+ for i in range(nthreads):
+ threads[i] = threading.Thread(target = lookup_name, args=[i])
+ threads[i].start()
+ for i in range(nthreads):
+ threads[i].join()
+ assert sum(result) == nthreads
+
+def test_thread_safe_gethostbyaddr():
+ import threading
+ nthreads = 10
+ ip = '8.8.8.8'
+ domain = gethostbyaddr(ip)[0]
+ result = [0] * nthreads
+ threads = [None] * nthreads
+ lock = threading.Lock()
+ def lookup_addr(ip, i):
+ name, aliases, address_list = gethostbyaddr(ip, lock)
+ if name == domain:
+ result[i] += 1
+ for i in range(nthreads):
+ threads[i] = threading.Thread(target = lookup_addr, args=[ip, i])
+ threads[i].start()
+ for i in range(nthreads):
+ threads[i].join()
+ assert sum(result) == nthreads
+
def test_gethostbyaddr():
try:
cpy_socket.gethostbyaddr("::1")
More information about the pypy-commit
mailing list