Lynn Rees avatar Lynn Rees committed 90ac222

- update

Comments (0)

Files changed (7)

 .DS_Store
 .figleaf
 .coverage
+build/
+dist/
 .project
 .pydevproject
 .git/
-.svn/
-.svn/*
 .settings/
+*.DS_Store
+_FOSSIL_
+unfinished/
+src/
+static/
+media/
 *.orig
+syntax: glob
 .tox/*
-venv/
-stuff/*
-syntax:regexp
-^build$
-^stuff$
-^dist$
+syntax: regexp
+^stuff$

crossroads/__init__.py

-#from core import *
+

crossroads/core.py

-# -*- coding: utf-8 -*-
-'''ctypes binding for Crossroads.IO library.'''
-
-import random
-from ctypes import c_int64, c_int32, c_size_t, sizeof, byref, c_int, string_at
-
-from stuf.six import isunicode, isbytes, tobytes
-
-from . import lowest as xs
-from . import constants as XS
-
-
-class Context(object):
-
-    def __init__(self, io_threads=1):
-        self.handle = xs.init()
-        self.closed = False
-
-    def socket(self, kind):
-        if self.closed:
-            raise xs.XSError(XS.ENOTSUP)
-        return Socket(self, kind)
-
-    def term(self):
-        rc = xs.term(self.handle)
-        self.handle = None
-        self.closed = True
-        return rc
-
-
-class Socket(object):
-
-    def __init__(self, context, socket_type):
-        self.context = context
-        self.handle = xs.socket(context.handle, socket_type)
-        self.socket_type = socket_type
-        self.closed = False
-
-    def _check_closed(self):
-        if self.closed:
-            raise xs.XSError(XS.ENOTSUP)
-
-    @property
-    def rcvmore(self):
-        '''
-        s.rcvmore()
-
-        Are there more parts to a multipart message?
-
-        Returns
-        -------
-        more : bool
-            whether we are in the middle of a multipart message.
-        '''
-        return bool(self.getsockopt(XS.RCVMORE))
-
-    def close(self):
-        xs.close(self.handle)
-        self.handle = None
-        self.closed = True
-
-    def bind(self, addr):
-        if isunicode(addr):
-            addr = tobytes(addr)
-        if not isbytes(addr):
-            raise TypeError('expected bytes, got: {r}'.format(addr))
-        xs.bind(self.handle, addr)
-
-    def bind_to_random_port(
-        self, addr, min_port=2000, max_port=20000, max_tries=100
-    ):
-        '''
-        s.bind_to_random_port(
-           addr, min_port=2000, max_port=20000, max_tries=100
-        )
-
-        Bind this socket to a random port in a range.
-
-        Parameters
-        ----------
-        addr : str
-            The address string without the port to pass to ``Socket.bind()``.
-        min_port : int, optional
-            The minimum port in the range of ports to try.
-        max_port : int, optional
-            The maximum port in the range of ports to try.
-        max_tries : int, optional
-            The number of attempt to bind.
-
-        Returns
-        -------
-        port : int
-            The port the socket was bound to.
-
-        Raises
-        ------
-        xsBindError
-            if `max_tries` reached before successful bind
-        '''
-        for i in range(max_tries):
-            try:
-                port = random.randrange(min_port, max_port)
-                self.bind('{1}:{1}'.format(addr, port))
-            except xs.XSError:
-                pass
-            else:
-                return port
-        raise xs.XSError('Could not bind socket to random port.')
-
-    def connect(self, addr):
-        '''
-        s.connect(addr)
-
-        Connect to a remote 0MQ socket.
-
-        Parameters
-        ----------
-        addr : str
-            The address string. This has the form 'protocol://interface:port',
-            for example 'tcp://127.0.0.1:5555'. Protocols supported are
-            tcp, upd, pgm, inproc and ipc. If the address is unicode, it is
-            encoded to utf-8 first.
-        '''
-        if isunicode(addr):
-            addr = tobytes('utf-8')
-        if not isbytes(addr):
-            raise TypeError('expected bytes, got: {r}'.format(addr))
-        xs.connect(self.handle, addr)
-
-    def getsockopt(self, option):
-        '''
-        s.getsockopt(option)
-
-        Get the value of a socket option.
-
-        See the 0MQ documentation for details on specific options.
-
-        Parameters
-        ----------
-        option : str
-            The name of the option to set. Can be any of:
-            IDENTITY, HWM, SWAP, AFFINITY, RATE,
-            RECOVERY_IVL, MCAST_LOOP, SNDBUF, RCVBUF, RCVMORE.
-
-        Returns
-        -------
-        optval : int, str
-            The value of the option as a string or int.
-        '''
-        self._check_closed()
-        optval = 0
-        if option in XS.int64_sockopts:
-            optval = c_int64(optval)
-        elif option in XS.int_sockopts:
-            optval = c_int32(optval)
-        else:
-            raise xs.XSError(XS.EINVAL)
-        optlen = c_size_t(sizeof(optval))
-        xs.getsockopt(self.handle, option, byref(optval), byref(optlen))
-        return optval.value
-
-    def setsockopt(self, option, optval):
-        '''
-        s.setsockopt(option, optval)
-
-        Set socket options.
-
-        See the 0MQ documentation for details on specific options.
-
-        Parameters
-        ----------
-        option : constant
-            The name of the option to set. Can be any of: SUBSCRIBE,
-            UNSUBSCRIBE, IDENTITY, HWM, SWAP, AFFINITY, RATE,
-            RECOVERY_IVL, MCAST_LOOP, SNDBUF, RCVBUF.
-        optval : int or str
-            The value of the option to set.
-        '''
-        self._check_closed()
-        if isunicode(optval):
-            raise TypeError('unicode not allowed, use setsockopt_unicode')
-        if option in XS.bytes_sockopts:
-            if not isinstance(optval, bytes):
-                raise TypeError('expected str, got: {0}'.format(optval))
-            xs.setsockopt(self.handle, option, optval, len(optval))
-        elif option in XS.int64_sockopts:
-            if not isinstance(optval, int):
-                raise TypeError('expected int, got: {0}'.format(optval))
-            optval_int64_c = c_int64(optval)
-            xs.setsockopt(
-                self.handle,
-                option,
-                byref(optval_int64_c),
-                sizeof(optval_int64_c)
-            )
-        elif option in XS.int_sockopts:
-            if not isinstance(optval, int):
-                raise TypeError('expected int, got: {0}'.format(optval))
-            optval_int32_c = c_int32(optval)
-            xs.setsockopt(
-                self.handle, option,
-                byref(optval_int32_c),
-                sizeof(optval_int32_c),
-            )
-        else:
-            raise xs.XSError(XS.EINVAL)
-
-    def send(self, data, flags=0, copy=True, track=False):
-        '''
-        s.send(data, flags=0, copy=True, track=False)
-
-        Send a message on this socket.
-
-        This queues the message to be sent by the IO thread at a later time.
-
-        Parameters
-        ----------
-        data : object, str, Message
-            The content of the message.
-        flags : int
-            Any supported flag: NOBLOCK, SNDMORE.
-        copy : bool
-            Should the message be sent in a copying or non-copying manner.
-        track : bool
-            Should the message be tracked for notification that xs has
-            finished with it? (ignored if copy=True)
-
-        Returns
-        -------
-        None : if `copy` or not track
-            None if message was sent, raises an exception otherwise.
-        MessageTracker : if track and not copy
-            a MessageTracker object, whose `pending` property will
-            be True until the send is completed.
-
-        Raises
-        ------
-        TypeError
-            If a unicode object is passed
-        ValueError
-            If `track=True`, but an untracked Message is passed.
-        xsError
-            If the send does not succeed for any reason.
-        '''
-        self._check_closed()
-        if isunicode(data):
-            raise TypeError('unicode not allowed, use `send_unicode`')
-        if not isbytes(data):
-            raise TypeError('expected str, got: %r' % data)
-        flags = c_int(flags)
-        msg = xs.msg_t()
-        msg_c_len = len(data)
-        xs.msg_init_size(byref(msg), msg_c_len)
-        msg_buf = xs.msg_data(byref(msg))
-        msg_buf_size = xs.msg_size(byref(msg))
-        xs.memmove(msg_buf, data, msg_buf_size)
-        return xs.send(self.handle, byref(msg), flags)
-
-    def recv(self, flags=0, copy=True, track=False):
-        '''
-        s.recv(flags=0, copy=True, track=False)
-
-        Receive a message.
-
-        Parameters
-        ----------
-        flags : int
-            Any supported flag: NOBLOCK. If NOBLOCK is set, this method
-            will raise a xsError with EAGAIN if a message is not ready.
-            If NOBLOCK is not set, then this method will block until a
-            message arrives.
-        copy : bool
-            Should the message be received in a copying or non-copying manner?
-            If False a Message object is returned, if True a string copy of
-            message is returned.
-        track : bool
-            Should the message be tracked for notification that xs has
-            finished with it? (ignored if copy=True)
-
-        Returns
-        -------
-        msg : str, Message
-            The returned message.  If `copy` is False, then it will be a
-            Message, otherwise a str.
-
-        Raises
-        ------
-        xsError
-            for any of the reasons xs_recvmsg might fail.
-        '''
-        self._check_closed()
-        flags = c_int(flags)
-        msg = xs.msg_t()
-        xs.msg_init(byref(msg))
-        try:
-            xs.recv(self.handle, byref(msg), flags)
-            data = xs.msg_data(byref(msg))
-            data_size = xs.msg_size(byref(msg))
-            return string_at(data, data_size)
-        finally:
-            xs.msg_close(byref(msg))
-
-
-def _poll(sockets, timeout=-1):
-    '''_poll(sockets, timeout=-1)
-
-    Poll a set of 0MQ sockets, native file descs. or sockets.
-
-    Parameters
-    ----------
-    sockets : list of tuples of (socket, flags)
-        Each element of this list is a two-tuple containing a socket
-        and a flags. The socket may be a 0MQ socket or any object with
-        a ``fileno()`` method. The flags can be xs.POLLIN (for detecting
-        for incoming messages), xs.POLLOUT (for detecting that send is OK)
-        or xs.POLLIN|xs.POLLOUT for detecting both.
-    timeout : int
-        The number of milliseconds to poll for. Negative means no timeout.
-    '''
-#    if xs.VERSION[0] < c_int(3):
-        # timeout is us in 2.x, ms in 3.x
-        # expected input is ms (matches 3.x)
-#        timeout = 1000 * timeout
-    n_sockets = len(sockets)
-    array_type = xs.pollitem_t * n_sockets
-    pollitems = array_type()
-    for i, (s, events) in enumerate(sockets):
-        if isinstance(s, Socket):
-            pollitems[i].socket = s.handle
-            pollitems[i].events = events
-            pollitems[i].revents = 0
-        elif isinstance(s, c_int):
-            pollitems[i].socket = None
-            pollitems[i].fd = s
-            pollitems[i].events = events
-            pollitems[i].revents = 0
-        elif hasattr(s, 'fileno'):
-            try:
-                fileno = int(s.fileno())
-            except:
-                raise ValueError('fileno() must return an valid integer fd')
-            else:
-                pollitems[i].socket = None
-                pollitems[i].fd = fileno
-                pollitems[i].events = events
-                pollitems[i].revents = 0
-        else:
-            raise TypeError(
-                'Socket must be a 0MQ socket, an integer fd or have '
-                'a fileno() method: %r' % s
-            )
-    xs.poll(pollitems, n_sockets, timeout)
-    results = []
-    for i, (s, _) in enumerate(sockets):
-        # Return the fd for sockets, for compat. with select.poll.
-        if hasattr(s, 'fileno'):
-            s = s.fileno()
-        revents = pollitems[i].revents
-        # Only return sockets with non-zero status for compat with select.poll
-        if revents > 0:
-            results.append((s, revents))
-    return results
-
-
-class Poller(object):
-
-    '''
-    Poller()
-
-    A stateful poll interface that mirrors Python's built-in poll.
-    '''
-
-    def __init__(self):
-        self.sockets = {}
-
-    def register(self, socket, flags=XS.POLLIN | XS.POLLOUT):
-        '''
-        p.register(socket, flags=POLLIN|POLLOUT)
-
-        Register a 0MQ socket or native fd for I/O monitoring.
-
-        register(s,0) is equivalent to unregister(s).
-
-        Parameters
-        ----------
-        socket : xs.Socket or native socket
-            A xs.Socket or any Python object having a ``fileno()``
-            method that returns a valid file descriptor.
-        flags : int
-            The events to watch for.  Can be POLLIN, POLLOUT or POLLIN|POLLOUT.
-            If `flags=0`, socket will be unregistered.
-        '''
-        if flags:
-            self.sockets[socket] = flags
-        elif socket in self.sockets:
-            # uregister sockets registered with no events
-            self.unregister(socket)
-        else:
-            # ignore new sockets with no events
-            pass
-
-    def modify(self, socket, flags=XS.POLLIN | XS.POLLOUT):
-        '''
-        p.modify(socket, flags=POLLIN|POLLOUT)
-
-        Modify the flags for an already registered 0MQ socket or native fd.
-        '''
-        self.register(socket, flags)
-
-    def unregister(self, socket):
-        '''
-        p.unregister(socket)
-
-        Remove a 0MQ socket or native fd for I/O monitoring.
-
-        Parameters
-        ----------
-        socket : Socket
-            The socket instance to stop polling.
-        '''
-        del self.sockets[socket]
-
-    def poll(self, timeout=None):
-        '''
-        p.poll(timeout=None)
-
-        Poll the registered 0MQ or native fds for I/O.
-
-        Parameters
-        ----------
-        timeout : float, int
-            The timeout in milliseconds. If None, no `timeout` (infinite). This
-            is in milliseconds to be compatible with ``select.poll()``. The
-            underlying xs_poll uses microseconds and we convert to that in
-            this function.
-        '''
-        if timeout is None:
-            timeout = -1
-        timeout = int(timeout)
-        if timeout < 0:
-            timeout = -1
-        return _poll(list(self.sockets.items()), timeout=timeout)

crossroads/low.py

 
 from . import lowest as xs
 from . import constants as XS
-from .message import XSMessage, Message
+from .message import MessageXS, Message
 
 bigxsget = partial(getattr, XS)
 xsget = partial(getattr, xs)
         self._type = stype
         self._socket = xs.socket(context._ctx, stype)
         options.update(context._options)
-        self._setmany(**options)
+        _set = self._set
+        rc = 0
+        for k, v in items(options):
+            rc |= _set(k, v)
+        self.last_rc = rc
         context.sockets[self.id] = self
-        self.last_rc = None
         self.closed = False
         self.connections = OrderedDict()
         self.bindings = OrderedDict()
                     if key.startswith(('bind', 'connect')):
                         method, prefix = key.split('_')
                         return self._setter(
-                            key, getattr(self, '_s' + method), XS.PROTO[prefix],
+                            key, getattr(
+                                self, '_s' + method), XS.PROTO[prefix],
                         )
                     raise AttributeError(key)
 
         except AttributeError:
             setr(self, key, value)
 
-    def __exit__(self, e, c, b):
-        self.close()
-        if any((e is not None, c is not None, b is not None)):
-            return False
-
     def _opt_type(self, key):
         opt_key = bigxsget(key.upper())
         if opt_key in XS.INT:
         return self.last_rc
 
     def _setmany(self, **options):
-        _set = self._set
-        rc = 0
-        for k, v in items(options):
-            rc |= _set(k, v)
-        self.last_rc = rc
+
         return self
 
-    def _sbind(self, prefix , *addresses):
+    def _sbind(self, prefix, *addresses):
         for address in addresses:
             self.last_rc = self._bind(prefix + tobytes(address))
             self.bindings[unique_id()] = self.last_rc
     def send(self, data, size=None, more=False, nowait=False):
         msg = data if isinstance(data, Message) else Message(size, data)
         msg.last_rc = self.last_rc = self._send(
-            msg.source,
+            msg.src,
             len(msg),
             XS.DONTWAIT if nowait else 0 | XS.SNDMORE if more else 0,
         )
         return msg
 
     def sendmsg(self, data, more=False, nowait=False):
-        msg = data if isinstance(data, XSMessage) else XSMessage(data)
+        msg = data if isinstance(data, MessageXS) else MessageXS(data)
         msg.last_rc = self.last_rc = self._sendmsg(
-            msg.source,
-            XS.DONTWAIT if nowait else 0 | XS.SNDMORE if more else 0,
+            msg.src, XS.DONTWAIT if nowait else 0 | XS.SNDMORE if more else 0
         )
         return msg
 
 
     def recvmsg(self, nowait=False):
         try:
-            msg = XSMessage()
+            msg = MessageXS()
             msg.last_rc = self.last_rc = self._recvmsg(
                 msg.dest, XS.DONTWAIT if nowait else 0
             )
         if not rc:
             self.closed = True
         return rc
+
+    def __exit__(self, e, c, b):
+        self.close()
+        if any((e is not None, c is not None, b is not None)):
+            return False

crossroads/message.py

 # -*- coding: utf-8 -*-
 '''Crossroads.IO messages.'''
 
-from stuf.six import PY3, tobytes, tounicode, b, isstring
-from ctypes import byref, sizeof, string_at, c_ubyte, c_int, c_size_t
+from ctypes import sizeof, string_at, c_ubyte
+
+from stuf.six import PY3, tobytes, tounicode
 
 from . import lowest as xs
-from . import constants as XS
 
 
 class BaseMsg(object):
 
     def __init__(self, size, source=None):
-        self.parts = []
-        self.raw = source
+        self.src = source
         self.size = size
-        self.more = self.rc = None
+        self.more = self.rc = self.dest = None
 
-    def __add__(self, other):
-        if isinstance(other, BaseMsg):
-            self.parts.extend(other.parts)
-        elif isstring(other):
-            self.parts.append(other)
-        return self
+    def __bytes__(self, *args, **kwargs):
+        if self.dest is not None:
+            return tobytes(string_at(self.dest, len(self)), 'latin-1')
+        return b''
 
-    __iadd__ = __add__
-
-    def __bytes__(self):
-        if self.dest is None:
-            return b('')
-        return b('').join(tobytes(
-            string_at(byref(i), sizeof(i)), 'latin-1'
-        ) for i in self.parts)
-
-    def __unicode__(self):
-        return tounicode(self.__bytes__(), 'utf-8')
+    def __unicode__(self, *args, **kwargs):
+        return tounicode(tobytes(self, 'utf-8'))
 
     __str__ = __unicode__ if PY3 else __bytes__
 
-    @property
-    def dest(self):
-        return self.parts[-1]
-
 
 class Message(BaseMsg):
 
-    __slots__ = 'raw source dest last_rc more size'.split()
+    __slots__ = 'src dest rc more size'.split()
 
     def __init__(self, size, source=None):
         super(Message, self).__init__(size, source)
-        self.source = source
         if source is None:
-            self.parts.append(xs.array(c_ubyte, size))
+            self.dest = xs.array(c_ubyte, size)
 
     def __len__(self):
         if self.size is not None:
             return self.size
-        if self.dest is None:
-            return len(self.source)
+        if self.src is not None:
+            return len(self.src)
         return sizeof(self.dest)
 
-    @property
-    def msgmore(self):
-        more = c_int()
-        xs.getmsgopt(self.dest, XS.MORE, more, c_size_t(sizeof(more)))
-        return more.value
 
+class MessageXS(BaseMsg):
 
-class XSMessage(BaseMsg):
-
-    __slots__ = 'source dest rc more ref'.split()
+    __slots__ = 'src dest last_rc more ref'.split()
 
     def __init__(self, data=None):
-        super(XSMessage, self).__init__(32, data)
-        self.dest = self.source = dest = xs.msg_t()
+        super(MessageXS, self).__init__(32, data)
+        self.dest = self.ref = dest = xs.msg_t()
         if data is None:
             self.rc = xs.msg_init(dest)
         else:
         return sizeof(self.dest)
 
     def close(self):
-        rc = 0
-        self.rc = [rc | xs.msg_close(i) for i in self.parts][-1]
-
-    __del__ = close
+        self.rc = xs.msg_close(self.dest)
 
 
 #class BaseMultipart(object):
 #
 #    def __init__(self, size, source=None):
-#        self.source = source
+#        self.src = source
 #        self.more = self.rc = self.dest = None
 #        self.parts = []
 #        self.__add__ = self.parts.append
-
 #
+#    def __bytes__(self, *args, **kwargs):
+#        if self.dest is not None:
+#            return b''.join(tobytes(
+#                string_at(byref(i), sizeof(i)), 'latin-1') for i in self.parts
+#            )
+#        return b''
 #
+#    def __unicode__(self, *args, **kwargs):
+#        return tounicode(tobytes(self, 'utf-8'))
+#
+#    __str__ = __unicode__ if PY3 else __bytes__
+#
+#    @property
+#    def dest(self):
+#        return self.parts[-1]
 #class Multipart(BaseMultipart):
 #
 #    def __init__(self, size, source=None):
 #        super(Multipart, self).__init__(size, source)
 #
 #    def __len__(self):
-#        return len(self.source) if self.dest is None else sizeof(self.dest)
+#
+#        return len(self.src) if self.dest is None else sizeof(self.dest)
+#
+#    @property
+#    def ref(self):
+#        return None if self.dest is None else byref(self.dest)
 #
 #
 #class XSMultipart(BaseMultipart):
 #    def __len__(self):
 #        return sizeof(self.dest)
 #
-
+#    def close(self):
+#        self.last_rc = sum(xs.msg_close(i) for i in self.parts)

tests/test_low_level.py

             sub.recv(xpub.last_rc)
             self.assertEqual(sub.last_rc, 0)
 
-    def test_regrep_device(self):
-        # create a req/rep device
-        xreq = self.ctx.xreq()
-        xrep = self.ctx.xrep()
-        # create a worker
-        rep = self.ctx.rep()
-        # create a client
-        req = self.ctx.req()
-        with xreq.bind_tcp('127.0.0.1:5560'), xrep.bind_tcp('127.0.0.1:5561'), \
-            rep.connect_tcp('127.0.0.1:5560'), req.connect_tcp('127.0.0.1:5561'):
-            # send a request
-            self.assertEqual(req.send(b'ABC', 3, more=True).last_rc, 3)
-            self.assertEqual(req.send(b'DEF', 3).last_rc, 3)
-            # pass the request through the device
-            for i in lrange(4):
-                msg = xrep.recvmsg()
-                self.assertTrue(msg.last_rc >= 0)
-                self.assertTrue(xreq.sendmsg(
-                    msg.dest, True if msg.more else False
-                ).last_rc >= 0)
-#            # receive the request
-            buff = rep.recv(3)
+#    def test_regrep_device(self):
+#        # create a req/rep device
+#        xreq = self.ctx.xreq()
+#        xrep = self.ctx.xrep()
+#        # create a worker
+#        rep = self.ctx.rep()
+#        # create a client
+#        req = self.ctx.req()
+#        with xreq.bind_tcp('127.0.0.1:5560'), xrep.bind_tcp('127.0.0.1:5561'), \
+#            rep.connect_tcp('127.0.0.1:5560'), req.connect_tcp('127.0.0.1:5561'):
+#            # send a request
+#            self.assertEqual(req.send(b'ABC', 3, more=True).last_rc, 3)
+#            self.assertEqual(req.send(b'DEF', 3).last_rc, 3)
+#            # pass the request through the device
+#            for i in lrange(4):
+#                msg = xrep.recvmsg()
+#                self.assertTrue(msg.last_rc >= 0)
+#                self.assertTrue(xreq.sendmsg(
+#                    msg.dest, True if msg.more else False
+#                ).last_rc >= 0)
+##            # receive the request
+#            buff = rep.recv(3)
 #            self.assertEqual(buff.last_rc, 3)
 #            self.assertEqual(bytes(buff), b'ABC')
 #            self.assertEqual(buff.more, 0)

tests/testutil.py

-/*
-    Copyright (c) 2009-2012 250bpm s.r.o.
-    Copyright (c) 2007-2011 iMatix Corporation
-    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
-
-    This file is part of Crossroads I/O project.
-
-    Crossroads I/O is free software; you can redistribute it and/or modify it
-    under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation; either version 3 of the License, or
-    (at your option) any later version.
-
-    Crossroads is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __XS_TEST_TESTUTIL_HPP_INCLUDED__
-#define __XS_TEST_TESTUTIL_HPP_INCLUDED__
-
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "../include/xs/xs.h"
-#include "../src/platform.hpp"
-
-#if !defined XS_HAVE_WINDOWS
-#include <unistd.h>
-#include <pthread.h>
-#else
-#include "../src/windows.hpp"
-#endif
-
-#if !defined XS_TEST_MAIN
-#define XS_TEST_MAIN main
-#endif
-
-#if defined XS_HAVE_WINDOWS
-#define sleep(s) Sleep ((s) * 1000)
-#endif
-
-#if defined XS_HAVE_WINDOWS
-
-struct arg_t
-{
-    HANDLE handle;
-    void (*fn) (void *arg);
-    void *arg;
-};
-
-extern "C"
-{
-    static unsigned int __stdcall thread_routine (void *arg_)
-    {
-        arg_t *arg = (arg_t*) arg_;
-        arg->fn (arg->arg);
-        return 0;
-    }
-}
-
-void *thread_create (void (*fn_) (void *arg_), void *arg_)
-{
-    arg_t *arg = (arg_t*) malloc (sizeof (arg_t));
-    assert (arg);
-    arg->fn = fn_;
-    arg->arg = arg_;
-    arg->handle = (HANDLE) _beginthreadex (NULL, 0,
-        &::thread_routine, (void*) arg, 0 , NULL);
-    assert (arg->handle != NULL);
-    return (void*) arg;
-}
-
-void thread_join (void *thread_)
-{
-    arg_t *arg = (arg_t*) thread_;
-    DWORD rc = WaitForSingleObject (arg->handle, INFINITE);
-    assert (rc != WAIT_FAILED);
-    BOOL rc2 = CloseHandle (arg->handle);
-    assert (rc2 != 0);
-    free (arg);
-}
-
-#else
-
-struct arg_t
-{
-    pthread_t handle;
-    void (*fn) (void *arg);
-    void *arg;
-};
-
-
-
-#endif
-
-
-//  Check whether measured time is the expected time (in milliseconds).
-//  The upper tolerance is 1/2 sec so that the test doesn't fail even on
-//  very slow or very loaded systems.
-#define time_assert(actual,expected) \
-   assert (actual > ((expected) - 50) && actual < ((expected) + 500));
-
-#endif
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.