[pypy-commit] pypy issue1430: add locks and copy hostent. now it segfaults, add print to see where

mattip noreply at buildbot.pypy.org
Thu May 1 00:31:16 CEST 2014


Author: mattip <matti.picus at gmail.com>
Branch: issue1430
Changeset: r71109:df59574c2222
Date: 2014-05-01 01:29 +0300
http://bitbucket.org/pypy/pypy/changeset/df59574c2222/

Log:	add locks and copy hostent. now it segfaults, add print to see where

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),
@@ -447,6 +447,7 @@
 #in_addr_size = sizeof(in_addr)
 in6_addr = cConfig.in6_addr
 addrinfo = cConfig.addrinfo
+hostent = cConfig.hostent
 if _POSIX:
     nfds_t = cConfig.nfds_t
     pollfd = cConfig.pollfd
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -20,6 +20,7 @@
 from rpython.rlib.rarithmetic import intmask, r_uint
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.lltypesystem.rffi import sizeof, offsetof
+from rpython.rlib import rthread
 INVALID_SOCKET = _c.INVALID_SOCKET
 
 def mallocbuf(buffersize):
@@ -29,6 +30,8 @@
 constants = _c.constants
 locals().update(constants) # Define constants from _c
 
+ll_locks = {}
+
 if _c.WIN32:
     from rpython.rlib import rwin32
     def rsocket_startup():
@@ -38,9 +41,12 @@
             assert res == 0
         finally:
             lltype.free(wsadata, flavor='raw')
+        ll_locks['gethostbyname'] = rthread.allocate_lock()
+        ll_locks['gethostbyaddr'] = rthread.allocate_lock()
 else:
     def rsocket_startup():
-        pass
+        ll_locks['gethostbyname'] = rthread.allocate_lock()
+        ll_locks['gethostbyaddr'] = rthread.allocate_lock()
 
 
 def ntohs(x):
@@ -1125,21 +1131,31 @@
     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
-    addr = gethostbyname(name)
-    hostent = _c.gethostbyname(name)
-    return gethost_common(name, hostent, addr)
+    # XXX use gethostbyname_r() if available instead of locks
+    with lltype.scoped_alloc(rffi.CArray(_c.hostent), 1) as hostent:
+        addr = gethostbyname(name)
+        ll_locks['gethostbyname'].acquire(True)
+        _hostent = _c.gethostbyname(name)
+        if not _hostent:
+            raise HSocketError(name)
+        rffi.structcopy(hostent[0], _hostent)
+        ll_locks['gethostbyname'].release()
+        return gethost_common(name, hostent[0], addr)
 
 def gethostbyaddr(ip):
-    # XXX use gethostbyaddr_r() if available, and/or use locks if not
+    # 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)
+        with lltype.scoped_alloc(rffi.CArray(_c.hostent), 1) as hostent:
+            ll_locks['gethostbyaddr'].acquire(True)
+            _hostent = _c.gethostbyaddr(p, size, addr.family)
+            rffi.structcopy(hostent[0], _hostent)
+            ll_locks['gethostbyaddr'].release()
+            return gethost_common(ip, hostent[0], addr)
     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
@@ -67,21 +67,27 @@
     domain = 'google.com'
     result = [0] * nthreads
     threads = [None] * nthreads
+    print 'starting', 70
     def lookup_name(i):
         name, aliases, address_list = gethostbyname_ex(domain)
         if name == domain:
             result[i] += 1
+        print 'done',i,75
     for i in range(nthreads):
         threads[i] = threading.Thread(target = lookup_name, args=[i])
         threads[i].start()
+        print 'threads', 78
+    print 'done', 79
     for i in range(nthreads):
         threads[i].join()
     assert sum(result) == nthreads
+    print 'done', 82
 
 def test_thread_safe_gethostbyaddr():
     import threading
     nthreads = 10
     ip = '8.8.8.8'
+    print 'starting', 87
     domain = gethostbyaddr(ip)[0]
     result = [0] * nthreads
     threads = [None] * nthreads
@@ -92,6 +98,7 @@
     for i in range(nthreads):
         threads[i] = threading.Thread(target = lookup_addr, args=[ip, i])
         threads[i].start()
+        print 'threads', 98
     for i in range(nthreads):
         threads[i].join()
     assert sum(result) == nthreads


More information about the pypy-commit mailing list