Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r72262:ce8c750062dc
Date: 2014-06-28 10:57 +0200
http://bitbucket.org/pypy/pypy/changeset/ce8c750062dc/

Log:    merge heads

diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -465,9 +465,13 @@
 
 This is documented (here__ and here__).  It needs 4 GB of RAM to run
 "rpython targetpypystandalone" on top of PyPy, a bit more when running
-on CPython.  If you have less than 4 GB it will just swap forever (or
-fail if you don't have enough swap).  On 32-bit, divide the numbers by
-two.
+on top of CPython.  If you have less than 4 GB free, it will just swap
+forever (or fail if you don't have enough swap).  And we mean *free:*
+if the machine has 4 GB *in total,* then it will swap.
+
+On 32-bit, divide the numbers by two.  (We didn't try recently, but in
+the past it was possible to compile a 32-bit version on a 2 GB Linux
+machine with nothing else running: no Gnome/KDE, for example.)
 
 .. __: http://pypy.org/download.html#building-from-source
 .. __: 
https://pypy.readthedocs.org/en/latest/getting-started-python.html#translating-the-pypy-python-interpreter
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
@@ -6,8 +6,8 @@
     }
 
     interpleveldefs = {
-        'SocketType':  'interp_socket.W_RSocket',
-        'socket'    :  'interp_socket.W_RSocket',
+        'SocketType':  'interp_socket.W_Socket',
+        'socket'    :  'interp_socket.W_Socket',
         'error'     :  'interp_socket.get_error(space, "error")',
         'herror'    :  'interp_socket.get_error(space, "herror")',
         'gaierror'  :  'interp_socket.get_error(space, "gaierror")',
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
@@ -1,8 +1,12 @@
-from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
-from pypy.module._socket.interp_socket import converted_error, W_RSocket, 
addr_as_object, ipaddr_from_object
 from rpython.rlib import rsocket
 from rpython.rlib.rsocket import SocketError, INVALID_SOCKET
+
 from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
+from pypy.module._socket.interp_socket import (
+    converted_error, W_Socket, addr_as_object, ipaddr_from_object
+)
+
 
 def gethostname(space):
     """gethostname() -> string
@@ -136,10 +140,10 @@
     The remaining arguments are the same as for socket().
     """
     try:
-        sock = rsocket.fromfd(fd, family, type, proto, W_RSocket)
+        sock = rsocket.fromfd(fd, family, type, proto)
     except SocketError, e:
         raise converted_error(space, e)
-    return space.wrap(sock)
+    return space.wrap(W_Socket(sock))
 
 @unwrap_spec(family=int, type=int, proto=int)
 def socketpair(space, family=rsocket.socketpair_default_family,
@@ -153,10 +157,13 @@
     AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
     """
     try:
-        sock1, sock2 = rsocket.socketpair(family, type, proto, W_RSocket)
+        sock1, sock2 = rsocket.socketpair(family, type, proto)
     except SocketError, e:
         raise converted_error(space, e)
-    return space.newtuple([space.wrap(sock1), space.wrap(sock2)])
+    return space.newtuple([
+        space.wrap(W_Socket(sock1)),
+        space.wrap(W_Socket(sock2))
+    ])
 
 # The following 4 functions refuse all negative numbers, like CPython 2.6.
 # They could also check that the argument is not too large, but CPython 2.6
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -1,14 +1,18 @@
+from rpython.rlib import rsocket
+from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rsocket import (
+    RSocket, AF_INET, SOCK_STREAM, SocketError, SocketErrorWithErrno,
+    RSocketError
+)
+from rpython.rtyper.lltypesystem import lltype, rffi
+
+from pypy.interpreter import gateway
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\
-     interp_attrproperty
+from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from rpython.rlib.rarithmetic import intmask
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib import rsocket
-from rpython.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM
-from rpython.rlib.rsocket import SocketError, SocketErrorWithErrno, 
RSocketError
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter import gateway
+from pypy.interpreter.typedef import (
+    GetSetProperty, TypeDef, make_weakref_descr
+)
 
 
 # XXX Hack to seperate rpython and pypy
@@ -124,10 +128,18 @@
     return addr
 
 
-class W_RSocket(W_Root, RSocket):
-    def __del__(self):
-        self.clear_all_weakrefs()
-        RSocket.__del__(self)
+class W_Socket(W_Root):
+    def __init__(self, sock):
+        self.sock = sock
+
+    def get_type_w(self, space):
+        return space.wrap(self.sock.type)
+
+    def get_proto_w(self, space):
+        return space.wrap(self.sock.proto)
+
+    def get_family_w(self, space):
+        return space.wrap(self.sock.family)
 
     def accept_w(self, space):
         """accept() -> (socket object, address info)
@@ -137,22 +149,22 @@
         info is a pair (hostaddr, port).
         """
         try:
-            fd, addr = self.accept()
+            fd, addr = self.sock.accept()
             sock = rsocket.make_socket(
-                fd, self.family, self.type, self.proto, W_RSocket)
-            return space.newtuple([space.wrap(sock),
+                fd, self.sock.family, self.sock.type, self.sock.proto)
+            return space.newtuple([space.wrap(W_Socket(sock)),
                                    addr_as_object(addr, sock.fd, space)])
-        except SocketError, e:
+        except SocketError as e:
             raise converted_error(space, e)
 
     # convert an Address into an app-level object
     def addr_as_object(self, space, address):
-        return addr_as_object(address, self.fd, space)
+        return addr_as_object(address, self.sock.fd, space)
 
     # convert an app-level object into an Address
     # based on the current socket's family
     def addr_from_object(self, space, w_address):
-        return addr_from_object(self.family, space, w_address)
+        return addr_from_object(self.sock.family, space, w_address)
 
     def bind_w(self, space, w_addr):
         """bind(address)
@@ -162,8 +174,8 @@
         sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
         """
         try:
-            self.bind(self.addr_from_object(space, w_addr))
-        except SocketError, e:
+            self.sock.bind(self.addr_from_object(space, w_addr))
+        except SocketError as e:
             raise converted_error(space, e)
 
     def close_w(self, space):
@@ -172,7 +184,7 @@
         Close the socket.  It cannot be used after this call.
         """
         try:
-            self.close()
+            self.sock.close()
         except SocketError:
             # cpython doesn't return any errors on close
             pass
@@ -184,8 +196,8 @@
         is a pair (host, port).
         """
         try:
-            self.connect(self.addr_from_object(space, w_addr))
-        except SocketError, e:
+            self.sock.connect(self.addr_from_object(space, w_addr))
+        except SocketError as e:
             raise converted_error(space, e)
 
     def connect_ex_w(self, space, w_addr):
@@ -196,15 +208,16 @@
         """
         try:
             addr = self.addr_from_object(space, w_addr)
-        except SocketError, e:
+        except SocketError as e:
             raise converted_error(space, e)
-        error = self.connect_ex(addr)
+        error = self.sock.connect_ex(addr)
         return space.wrap(error)
 
     def dup_w(self, space):
         try:
-            return self.dup(W_RSocket)
-        except SocketError, e:
+            sock = self.sock.dup()
+            return W_Socket(sock)
+        except SocketError as e:
             raise converted_error(space, e)
 
     def fileno_w(self, space):
@@ -212,7 +225,7 @@
 
         Return the integer file descriptor of the socket.
         """
-        return space.wrap(intmask(self.fd))
+        return space.wrap(intmask(self.sock.fd))
 
     def getpeername_w(self, space):
         """getpeername() -> address info
@@ -221,9 +234,9 @@
         info is a pair (hostaddr, port).
         """
         try:
-            addr = self.getpeername()
-            return addr_as_object(addr, self.fd, space)
-        except SocketError, e:
+            addr = self.sock.getpeername()
+            return addr_as_object(addr, self.sock.fd, space)
+        except SocketError as e:
             raise converted_error(space, e)
 
     def getsockname_w(self, space):
@@ -233,9 +246,9 @@
         info is a pair (hostaddr, port).
         """
         try:
-            addr = self.getsockname()
-            return addr_as_object(addr, self.fd, space)
-        except SocketError, e:
+            addr = self.sock.getsockname()
+            return addr_as_object(addr, self.sock.fd, space)
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(level=int, optname=int)
@@ -248,11 +261,11 @@
         """
         if w_buflen is None:
             try:
-                return space.wrap(self.getsockopt_int(level, optname))
-            except SocketError, e:
+                return space.wrap(self.sock.getsockopt_int(level, optname))
+            except SocketError as e:
                 raise converted_error(space, e)
         buflen = space.int_w(w_buflen)
-        return space.wrap(self.getsockopt(level, optname, buflen))
+        return space.wrap(self.sock.getsockopt(level, optname, buflen))
 
     def gettimeout_w(self, space):
         """gettimeout() -> timeout
@@ -260,7 +273,7 @@
         Returns the timeout in floating seconds associated with socket
         operations. A timeout of None indicates that timeouts on socket
         """
-        timeout = self.gettimeout()
+        timeout = self.sock.gettimeout()
         if timeout < 0.0:
             return space.w_None
         return space.wrap(timeout)
@@ -274,8 +287,8 @@
         will allow before refusing new connections.
         """
         try:
-            self.listen(backlog)
-        except SocketError, e:
+            self.sock.listen(backlog)
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(w_mode = WrappedDefault("r"),
@@ -298,8 +311,8 @@
         the remote end is closed and all data is read, return the empty string.
         """
         try:
-            data = self.recv(buffersize, flags)
-        except SocketError, e:
+            data = self.sock.recv(buffersize, flags)
+        except SocketError as e:
             raise converted_error(space, e)
         return space.wrap(data)
 
@@ -310,13 +323,13 @@
         Like recv(buffersize, flags) but also return the sender's address info.
         """
         try:
-            data, addr = self.recvfrom(buffersize, flags)
+            data, addr = self.sock.recvfrom(buffersize, flags)
             if addr:
-                w_addr = addr_as_object(addr, self.fd, space)
+                w_addr = addr_as_object(addr, self.sock.fd, space)
             else:
                 w_addr = space.w_None
             return space.newtuple([space.wrap(data), w_addr])
-        except SocketError, e:
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(data='bufferstr', flags=int)
@@ -328,8 +341,8 @@
         sent; this may be less than len(data) if the network is busy.
         """
         try:
-            count = self.send(data, flags)
-        except SocketError, e:
+            count = self.sock.send(data, flags)
+        except SocketError as e:
             raise converted_error(space, e)
         return space.wrap(count)
 
@@ -343,8 +356,9 @@
         to tell how much data has been sent.
         """
         try:
-            self.sendall(data, flags, space.getexecutioncontext().checksignals)
-        except SocketError, e:
+            self.sock.sendall(
+                data, flags, space.getexecutioncontext().checksignals)
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(data='bufferstr')
@@ -364,8 +378,8 @@
             w_addr = w_param3
         try:
             addr = self.addr_from_object(space, w_addr)
-            count = self.sendto(data, flags, addr)
-        except SocketError, e:
+            count = self.sock.sendto(data, flags, addr)
+        except SocketError as e:
             raise converted_error(space, e)
         return space.wrap(count)
 
@@ -377,7 +391,7 @@
         setblocking(True) is equivalent to settimeout(None);
         setblocking(False) is equivalent to settimeout(0.0).
         """
-        self.setblocking(flag)
+        self.sock.setblocking(flag)
 
     @unwrap_spec(level=int, optname=int)
     def setsockopt_w(self, space, level, optname, w_optval):
@@ -391,13 +405,13 @@
         except:
             optval = space.str_w(w_optval)
             try:
-                self.setsockopt(level, optname, optval)
-            except SocketError, e:
+                self.sock.setsockopt(level, optname, optval)
+            except SocketError as e:
                 raise converted_error(space, e)
             return
         try:
-            self.setsockopt_int(level, optname, optval)
-        except SocketError, e:
+            self.sock.setsockopt_int(level, optname, optval)
+        except SocketError as e:
             raise converted_error(space, e)
 
     def settimeout_w(self, space, w_timeout):
@@ -415,7 +429,7 @@
             if timeout < 0.0:
                 raise OperationError(space.w_ValueError,
                                      space.wrap('Timeout value out of range'))
-        self.settimeout(timeout)
+        self.sock.settimeout(timeout)
 
     @unwrap_spec(nbytes=int, flags=int)
     def recv_into_w(self, space, w_buffer, nbytes=0, flags=0):
@@ -424,8 +438,8 @@
         if nbytes == 0 or nbytes > lgt:
             nbytes = lgt
         try:
-            return space.wrap(self.recvinto(rwbuffer, nbytes, flags))
-        except SocketError, e:
+            return space.wrap(self.sock.recvinto(rwbuffer, nbytes, flags))
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(nbytes=int, flags=int)
@@ -435,13 +449,13 @@
         if nbytes == 0 or nbytes > lgt:
             nbytes = lgt
         try:
-            readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags)
+            readlgt, addr = self.sock.recvfrom_into(rwbuffer, nbytes, flags)
             if addr:
-                w_addr = addr_as_object(addr, self.fd, space)
+                w_addr = addr_as_object(addr, self.sock.fd, space)
             else:
                 w_addr = space.w_None
             return space.newtuple([space.wrap(readlgt), w_addr])
-        except SocketError, e:
+        except SocketError as e:
             raise converted_error(space, e)
 
     @unwrap_spec(cmd=int)
@@ -473,7 +487,7 @@
                     option_ptr.c_keepaliveinterval = space.uint_w(w_interval)
 
                 res = _c.WSAIoctl(
-                    self.fd, cmd, value_ptr, value_size,
+                    self.sock.fd, cmd, value_ptr, value_size,
                     rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL)
                 if res < 0:
                     raise converted_error(space, rsocket.last_error())
@@ -494,8 +508,8 @@
         (flag == SHUT_RDWR).
         """
         try:
-            self.shutdown(how)
-        except SocketError, e:
+            self.sock.shutdown(how)
+        except SocketError as e:
             raise converted_error(space, e)
 
     #------------------------------------------------------------
@@ -536,12 +550,13 @@
 @unwrap_spec(family=int, type=int, proto=int)
 def newsocket(space, w_subtype, family=AF_INET,
               type=SOCK_STREAM, proto=0):
-    sock = space.allocate_instance(W_RSocket, w_subtype)
+    self = space.allocate_instance(W_Socket, w_subtype)
     try:
-        W_RSocket.__init__(sock, family, type, proto)
-    except SocketError, e:
+        sock = RSocket(family, type, proto)
+    except SocketError as e:
         raise converted_error(space, e)
-    return space.wrap(sock)
+    W_Socket.__init__(self, sock)
+    return space.wrap(self)
 descr_socket_new = interp2app(newsocket)
 
 # ____________________________________________________________
@@ -597,10 +612,10 @@
 
 socketmethods = {}
 for methodname in socketmethodnames:
-    method = getattr(W_RSocket, methodname + '_w')
+    method = getattr(W_Socket, methodname + '_w')
     socketmethods[methodname] = interp2app(method)
 
-W_RSocket.typedef = TypeDef("_socket.socket",
+W_Socket.typedef = TypeDef("_socket.socket",
     __doc__ = """\
 socket([family[, type[, proto]]]) -> socket object
 
@@ -639,9 +654,9 @@
 
  [*] not available on all platforms!""",
     __new__ = descr_socket_new,
-    __weakref__ = make_weakref_descr(W_RSocket),
-    type = interp_attrproperty('type', W_RSocket),
-    proto = interp_attrproperty('proto', W_RSocket),
-    family = interp_attrproperty('family', W_RSocket),
+    __weakref__ = make_weakref_descr(W_Socket),
+    type = GetSetProperty(W_Socket.get_type_w),
+    proto = GetSetProperty(W_Socket.get_proto_w),
+    family = GetSetProperty(W_Socket.get_family_w),
     ** socketmethods
     )
diff --git a/pypy/tool/gcdump.py b/pypy/tool/gcdump.py
--- a/pypy/tool/gcdump.py
+++ b/pypy/tool/gcdump.py
@@ -43,7 +43,7 @@
 
     def print_summary(self):
         items = self.summary.items()
-        items.sort(key=lambda(typenum, stat): stat[1])    # sort by totalsize
+        items.sort(key=lambda (typenum, stat): stat[1])    # sort by totalsize
         totalsize = 0
         for typenum, stat in items:
             totalsize += stat[1]
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
@@ -493,10 +493,16 @@
 getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP,
                        size_t, CCHARP, size_t, rffi.INT], rffi.INT)
 
-htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False)
-htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False)
-ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False)
-ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False)
+if sys.platform.startswith("openbsd"):
+    htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False, 
macro=True)
+    htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False, 
macro=True)
+    ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False, 
macro=True)
+    ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False, 
macro=True)
+else:
+    htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False)
+    htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False)
+    ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False)
+    ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False)
 
 if _POSIX:
     inet_aton = external('inet_aton', [CCHARP, lltype.Ptr(in_addr)],
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -15,17 +15,18 @@
 # It's unclear if makefile() and SSL support belong here or only as
 # app-level code for PyPy.
 
+from rpython.rlib import _rsocket_rffi as _c, jit, rgc
 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
-from rpython.rlib import jit
+
+
 # Usage of @jit.dont_look_inside in this file is possibly temporary
 # and only because some lltypes declared in _rsocket_rffi choke the
 # JIT's codewriter right now (notably, FixedSizeArray).
+INVALID_SOCKET = _c.INVALID_SOCKET
 
 
 def mallocbuf(buffersize):
@@ -86,6 +87,7 @@
         self.addr_p = addr
         self.addrlen = addrlen
 
+    @rgc.must_be_light_finalizer
     def __del__(self):
         if self.addr_p:
             lltype.free(self.addr_p, flavor='raw', track_allocation=False)
@@ -493,8 +495,8 @@
 class RSocket(object):
     """RPython-level socket object.
     """
-    _mixin_ = True        # for interp_socket.py
     fd = _c.INVALID_SOCKET
+
     def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0,
                  fd=_c.INVALID_SOCKET):
         """Create a new socket."""
@@ -509,6 +511,7 @@
         self.proto = proto
         self.timeout = defaults.timeout
 
+    @rgc.must_be_light_finalizer
     def __del__(self):
         fd = self.fd
         if fd != _c.INVALID_SOCKET:
diff --git a/rpython/translator/c/src/thread_gil.c 
b/rpython/translator/c/src/thread_gil.c
--- a/rpython/translator/c/src/thread_gil.c
+++ b/rpython/translator/c/src/thread_gil.c
@@ -38,15 +38,14 @@
 
 long rpy_fastgil = 1;
 long rpy_waiting_threads = -42;    /* GIL not initialized */
-static mutex_t mutex_gil_stealer;
-static mutex_t mutex_gil;
+static mutex1_t mutex_gil_stealer;
+static mutex2_t mutex_gil;
 
 void RPyGilAllocate(void)
 {
     assert(RPY_FASTGIL_LOCKED(rpy_fastgil));
-    mutex_init(&mutex_gil_stealer);
-    mutex_init(&mutex_gil);
-    mutex_lock(&mutex_gil);
+    mutex1_init(&mutex_gil_stealer);
+    mutex2_init_locked(&mutex_gil);
     rpy_waiting_threads = 0;
 }
 
@@ -80,14 +79,15 @@
            first-in-first-out order, this will nicely give the threads
            a round-robin chance.
         */
-        mutex_lock(&mutex_gil_stealer);
+        mutex1_lock(&mutex_gil_stealer);
+        mutex2_loop_start(&mutex_gil);
 
         /* We are now the stealer thread.  Steals! */
         while (1) {
             /* Sleep for one interval of time.  We may be woken up earlier
                if 'mutex_gil' is released.
             */
-            if (mutex_lock_timeout(&mutex_gil, 0.0001)) {   /* 0.1 ms... */
+            if (mutex2_lock_timeout(&mutex_gil, 0.0001)) {   /* 0.1 ms... */
                 /* We arrive here if 'mutex_gil' was recently released
                    and we just relocked it.
                  */
@@ -107,7 +107,8 @@
             /* Otherwise, loop back. */
         }
         atomic_decrement(&rpy_waiting_threads);
-        mutex_unlock(&mutex_gil_stealer);
+        mutex2_loop_stop(&mutex_gil);
+        mutex1_unlock(&mutex_gil_stealer);
 
         RESTORE_ERRNO();
     }
@@ -140,7 +141,7 @@
 
     /* Explicitly release the 'mutex_gil'.
      */
-    mutex_unlock(&mutex_gil);
+    mutex2_unlock(&mutex_gil);
 
     /* Now nobody has got the GIL, because 'mutex_gil' is released (but
        rpy_fastgil is still locked).  Call RPyGilAcquire().  It will
diff --git a/rpython/translator/c/src/thread_nt.c 
b/rpython/translator/c/src/thread_nt.c
--- a/rpython/translator/c/src/thread_nt.c
+++ b/rpython/translator/c/src/thread_nt.c
@@ -196,33 +196,46 @@
 /* GIL code                                                 */
 /************************************************************/
 
-typedef HANDLE mutex_t;   /* a semaphore, on Windows */
+typedef HANDLE mutex2_t;   /* a semaphore, on Windows */
 
 static void gil_fatal(const char *msg) {
     fprintf(stderr, "Fatal error in the GIL: %s\n", msg);
     abort();
 }
 
-static inline void mutex_init(mutex_t *mutex) {
+static inline void mutex2_init(mutex2_t *mutex) {
     *mutex = CreateSemaphore(NULL, 1, 1, NULL);
     if (*mutex == NULL)
         gil_fatal("CreateSemaphore failed");
 }
 
-static inline void mutex_lock(mutex_t *mutex) {
+static inline void mutex2_lock(mutex2_t *mutex) {
     WaitForSingleObject(*mutex, INFINITE);
 }
 
-static inline void mutex_unlock(mutex_t *mutex) {
+static inline void mutex2_unlock(mutex2_t *mutex) {
     ReleaseSemaphore(*mutex, 1, NULL);
 }
 
-static inline int mutex_lock_timeout(mutex_t *mutex, double delay)
+static inline void mutex2_init_locked(mutex2_t *mutex) {
+    mutex2_init(mutex);
+    mutex2_lock(mutex);
+}
+
+static inline void mutex2_loop_start(mutex2_t *mutex) { }
+static inline void mutex2_loop_stop(mutex2_t *mutex) { }
+
+static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay)
 {
     DWORD result = WaitForSingleObject(*mutex, (DWORD)(delay * 1000.0 + 
0.999));
     return (result != WAIT_TIMEOUT);
 }
 
+#define mutex1_t      mutex2_t
+#define mutex1_init   mutex2_init
+#define mutex1_lock   mutex2_lock
+#define mutex1_unlock mutex2_unlock
+
 #ifdef _M_IA64
 /* On Itanium, use 'acquire' memory ordering semantics */
 #define lock_test_and_set(ptr, value)  InterlockedExchangeAcquire(ptr, value)
diff --git a/rpython/translator/c/src/thread_pthread.c 
b/rpython/translator/c/src/thread_pthread.c
--- a/rpython/translator/c/src/thread_pthread.c
+++ b/rpython/translator/c/src/thread_pthread.c
@@ -479,12 +479,20 @@
 
 #define ASSERT_STATUS(call)                             \
     if (call != 0) {                                    \
-        fprintf(stderr, "Fatal error: " #call "\n");    \
+        perror("Fatal error: " #call);                  \
         abort();                                        \
     }
 
-static inline void timespec_add(struct timespec *t, double incr)
+static inline void timespec_delay(struct timespec *t, double incr)
 {
+#ifdef CLOCK_REALTIME
+    clock_gettime(CLOCK_REALTIME, &t);
+#else
+    struct timeval tv;
+    RPY_GETTIMEOFDAY(&tv);
+    t->tv_sec = tv.tv_sec;
+    t->tv_nsec = tv.tv_usec * 1000 + 999;
+#endif
     /* assumes that "incr" is not too large, less than 1 second */
     long nsec = t->tv_nsec + (long)(incr * 1000000000.0);
     if (nsec >= 1000000000) {
@@ -495,27 +503,56 @@
     t->tv_nsec = nsec;
 }
 
-typedef pthread_mutex_t mutex_t;
+typedef pthread_mutex_t mutex1_t;
 
-static inline void mutex_init(mutex_t *mutex) {
+static inline void mutex1_init(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_init(mutex, pthread_mutexattr_default));
 }
-static inline void mutex_lock(mutex_t *mutex) {
+static inline void mutex1_lock(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_lock(mutex));
 }
-static inline void mutex_unlock(mutex_t *mutex) {
+static inline void mutex1_unlock(mutex1_t *mutex) {
     ASSERT_STATUS(pthread_mutex_unlock(mutex));
 }
-static inline int mutex_lock_timeout(mutex_t *mutex, double delay) {
-    struct timespec t;
-    clock_gettime(CLOCK_REALTIME, &t);
-    timespec_add(&t, delay);
-    int error_from_timedlock = pthread_mutex_timedlock(mutex, &t);
-    if (error_from_timedlock == ETIMEDOUT)
-        return 0;
-    ASSERT_STATUS(error_from_timedlock);
-    return 1;
+
+typedef struct {
+    char locked;
+    pthread_mutex_t mut;
+    pthread_cond_t cond;
+} mutex2_t;
+
+static inline void mutex2_init_locked(mutex2_t *mutex) {
+    mutex->locked = 1;
+    ASSERT_STATUS(pthread_mutex_init(&mutex->mut, pthread_mutexattr_default));
+    ASSERT_STATUS(pthread_cond_init(&mutex->cond, pthread_condattr_default));
 }
+static inline void mutex2_unlock(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_lock(&mutex->mut));
+    mutex->locked = 0;
+    ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut));
+    ASSERT_STATUS(pthread_cond_signal(&mutex->cond));
+}
+static inline void mutex2_loop_start(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_lock(&mutex->mut));
+}
+static inline void mutex2_loop_stop(mutex2_t *mutex) {
+    ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut));
+}
+static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay) {
+    if (mutex->locked) {
+        struct timespec t;
+        timespec_delay(&t, delay);
+        int error_from_timedwait = pthread_cond_timedwait(
+                                       &mutex->cond, &mutex->mut, &t);
+        if (error_from_timedwait != ETIMEDOUT) {
+            ASSERT_STATUS(error_from_timedwait);
+        }
+    }
+    int result = !mutex->locked;
+    mutex->locked = 1;
+    return result;
+}
+
 #define lock_test_and_set(ptr, value)  __sync_lock_test_and_set(ptr, value)
 #define atomic_increment(ptr)          __sync_fetch_and_add(ptr, 1)
 #define atomic_decrement(ptr)          __sync_fetch_and_sub(ptr, 1)
diff --git a/rpython/translator/platform/posix.py 
b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -22,9 +22,11 @@
         return ['-l%s' % lib for lib in libraries]
 
     def _libdirs(self, library_dirs):
+        assert '' not in library_dirs
         return ['-L%s' % ldir for ldir in library_dirs]
 
     def _includedirs(self, include_dirs):
+        assert '' not in include_dirs
         return ['-I%s' % idir for idir in include_dirs]
 
     def _linkfiles(self, link_files):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to