xpra icon
Bug tracker and wiki

Ticket #1211: html5-win32.patch

File html5-win32.patch, 8.7 KB (added by Antoine Martin, 4 years ago)

try to use blocking socket everywhere and wrap win32 non-blocking socket calls

  • setup.py

     
    134134gtk2_ENABLED = DEFAULT and client_ENABLED and not PYTHON3
    135135gtk3_ENABLED = DEFAULT and client_ENABLED and PYTHON3
    136136opengl_ENABLED = DEFAULT and client_ENABLED
    137 html5_ENABLED = not WIN32           #websockify is broken on win32, see https://github.com/kanaka/websockify/issues/28
     137html5_ENABLED = DEFAULT
    138138
    139139vsock_ENABLED           = sys.platform.startswith("linux") and os.path.exists("/usr/include/linux/vm_sockets.h")
    140140bencode_ENABLED         = DEFAULT
  • xpra/net/bytestreams.py

     
    254254            self.filename = remote
    255255
    256256    def peek(self, n):
    257         self._socket.settimeout(None)
    258         return self._socket.recv(n, socket.MSG_PEEK)
     257        try:
     258            return self._socket.recv(n, socket.MSG_PEEK)
     259        except Exception as e:
     260            log("peek failed: %s", e)
     261            return None
    259262
    260263    def read(self, n):
    261264        return self._read(self._socket.recv, n)
     
    290293        except:
    291294            log.warn("failed to get socket information", exc_info=True)
    292295        return d
    293 
    294 def set_socket_timeout(conn, timeout=None):
    295     #FIXME: this is ugly, but less intrusive than the alternative?
    296     log("set_socket_timeout(%s, %s)", conn, timeout)
    297     if isinstance(conn, SocketConnection):
    298         conn._socket.settimeout(timeout)
  • xpra/server/proxy/proxy_server.py

     
    5656        self.idle_add = glib.idle_add
    5757        self.timeout_add = glib.timeout_add
    5858        self.source_remove = glib.source_remove
    59         self._socket_timeout = PROXY_SOCKET_TIMEOUT
    6059        self.control_commands["stop"] = ArgsControlCommand("stop", "stops the proxy instance on the given display", self.handle_stop_command, min_args=1, max_args=1)
    6160
    6261        #ensure we cache the platform info before intercepting SIGCHLD
     
    211210        #this may block, so run it in a thread:
    212211        def do_start_proxy():
    213212            log("do_start_proxy()")
     213            #FIXME: this is ugly, but less intrusive than the alternative?
     214            sock = getattr(client_conn, "_socket", None)
     215            if sock:
     216                sock.settimeout(PROXY_SOCKET_TIMEOUT)
    214217            message_queue = MQueue()
    215218            try:
    216                 ioe = client_proto.wait_for_io_threads_exit(0.5+self._socket_timeout)
     219                ioe = client_proto.wait_for_io_threads_exit(0.5+PROXY_SOCKET_TIMEOUT)
    217220                if not ioe:
    218221                    log.error("some network IO threads have failed to terminate!")
    219222                    return
  • xpra/server/server_base.py

     
    3737from xpra.os_util import BytesIOClass, thread, get_hex_uuid, livefds, load_binary_file
    3838from xpra.util import typedict, flatten_dict, updict, log_screen_sizes, engs, repr_ellipsized, csv, iround, \
    3939    SERVER_EXIT, SERVER_ERROR, SERVER_SHUTDOWN, DETACH_REQUEST, NEW_CLIENT, DONE, IDLE_TIMEOUT
    40 from xpra.net.bytestreams import set_socket_timeout
    4140from xpra.platform import get_username
    4241from xpra.platform.paths import get_icon_filename
    4342from xpra.child_reaper import reaper_cleanup
     
    10271026            self.update_all_server_settings(reset)
    10281027
    10291028        self.accept_client(proto, c)
    1030         #use blocking sockets from now on:
    1031         set_socket_timeout(proto._conn, None)
    10321029
    10331030        def drop_client(reason="unknown", *args):
    10341031            self.disconnect_client(proto, reason, *args)
  • xpra/server/server_core.py

     
    153153        self._reverse_aliases = {}
    154154        self.socket_types = {}
    155155        self._max_connections = MAX_CONCURRENT_CONNECTIONS
    156         self._socket_timeout = 0.1
    157156        self._socket_dir = None
    158157        self.unix_socket_paths = []
    159158
     
    501500        assert socktype, "cannot find socket type for %s" % listener
    502501        try:
    503502            sock, address = listener.accept()
     503            sock.setblocking(True)
    504504        except socket.error as e:
    505505            netlog.error("Error: cannot accept new connection:")
    506506            netlog.error(" %s", e)
     
    515515            peername = str(address)
    516516        sockname = sock.getsockname()
    517517        target = peername or sockname
    518         sock.settimeout(self._socket_timeout)
    519         netlog("new_connection(%s) sock=%s, timeout=%s, sockname=%s, address=%s, peername=%s", args, sock, self._socket_timeout, sockname, address, peername)
     518        netlog("new_connection(%s) sock=%s, sockname=%s, address=%s, peername=%s", args, sock, sockname, address, peername)
    520519        conn = SocketConnection(sock, sockname, address, target, socktype)
    521520        netlog("socket connection: %s", conn)
    522521        if peername:
     
    532531        if socktype=="tcp" and self._html or self._tcp_proxy:
    533532            #see if the packet data is actually xpra or something else
    534533            #that we need to handle via a tcp proxy or the websockify adapter:
    535             conn._socket.settimeout(25)
     534            netlog("will peek")
    536535            v = conn.peek(128)
     536            #ugly win32 workaround (should be done in a thread?):
     537            if not v and sys.platform.startswith("win"):
     538                for _ in range(10):
     539                    time.sleep(0.010)
     540                    v = conn.peek(128)
     541                    if v:
     542                        break
     543            sock.setblocking(True)
    537544            netlog("peek()=%s", nonl(v))
    538545            if v and v[0] not in ("P", ord("P")):
    539546                if self._html:
     
    564571            netlog("new %s connection is not an xpra client, disconnecting it", socktype)
    565572            msg = "disconnect: invalid packet format, not an xpra client?\n"
    566573            try:
    567                 from xpra.net.bytestreams import set_socket_timeout
    568                 set_socket_timeout(conn, 1)
     574                sock.settimeout(1)
    569575                conn.write(msg)
    570576                conn.close()
    571577            except Exception as e:
     
    612618    def start_websockify(self, conn, frominfo):
    613619        netlog("start_websockify(%s, %s) www dir=%s", conn, frominfo, self._www_dir)
    614620        from xpra.net.websocket import WebSocketConnection, WSRequestHandler
     621        from xpra.net.bytestreams import untilConcludes
    615622        try:
     623            sock = conn._socket
     624            netlog("sock=%s (%s)", sock, type(sock))
     625            #workaround for win32 servers (this should not be needed on any other platform)
     626            #which don't seem to honour our request to use blocking sockets
     627            saved_recv = sock.recv
     628            saved_send = sock.send
     629            #saved_sendall = sock.sendall
     630            def recv(*args):
     631                return untilConcludes(conn.is_active, saved_recv, *args)
     632            def send(*args):
     633                return untilConcludes(conn.is_active, saved_send, *args)
     634            def sendall(*args):
     635                return untilConcludes(conn.is_active, saved_sendall, *args)
     636            sock.recv = recv
     637            sock.send = send
     638            #sock.sendall = sendall
    616639            def new_websocket_client(wsh):
    617640                netlog("new_websocket_client(%s)", wsh)
    618                 wsc = WebSocketConnection(conn._socket, conn.local, conn.remote, conn.target, conn.info, wsh)
     641                wsc = WebSocketConnection(sock, conn.local, conn.remote, conn.target, conn.info, wsh)
    619642                self.make_protocol("tcp", wsc, frominfo)
    620             WSRequestHandler(conn._socket, frominfo, new_websocket_client, self._www_dir)
     643            WSRequestHandler(sock, frominfo, new_websocket_client, self._www_dir)
    621644            return
    622645        except IOError as e:
    623646            netlog.error("Error: http failure responding to %s:", frominfo)
     
    645668            return
    646669        proxylog("proxy connected to tcp server at %s:%s : %s", host, port, tcp_server_connection)
    647670        sock = tcp_server_connection._socket
    648         sock.settimeout(self._socket_timeout)
    649671
    650672        #we can use blocking sockets for the client:
    651         conn.settimeout(None)
     673        conn.setblocking(True)
    652674        #but not for the server, which could deadlock on exit:
    653675        sock.settimeout(1)
    654676