xpra icon
Bug tracker and wiki

Changeset 166 in xpra


Ignore:
Timestamp:
09/19/11 09:41:22 (20 months ago)
Author:
antoine
Message:

try harder to close cleanly: ensure we close the socket when reaching the end of the write loop so that the last messages do go out, move disconnect code to a server.py function so that a client can request his own disconnection

Location:
trunk/src/xpra
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/xpra/protocol.py

    r160 r166  
    8383        self._source_has_more = False 
    8484        self._recv_counter = 0 
    85         self.closing = False 
    8685        self._closed = False 
    8786        self._read_decoder = IncrBDecode() 
     
    120119 
    121120    def _write_thread_loop(self): 
    122         while not self._closed: 
    123             log("write thread: waiting for data to write") 
    124             buf = self._write_queue.get() 
    125             # Used to signal that we should exit: 
    126             if buf is None: 
    127                 return 
    128             try: 
    129                 while buf: 
    130                     log("write thread: writing %s", repr_ellipsized(buf)) 
    131                     buf = buf[self._conn.write(buf):] 
    132             except (OSError, IOError, socket.error), e: 
    133                 log.info("Error writing to connection: %s", e) 
    134                 main_thread_call(self._connection_lost) 
    135                 return 
    136             except TypeError: 
    137                 assert self._closed 
    138                 return 
    139             if self._write_queue.empty(): 
    140                 main_thread_call(self._maybe_queue_more_writes) 
    141         return False 
     121        try: 
     122            while True: 
     123                log("write thread: waiting for data to write") 
     124                buf = self._write_queue.get() 
     125                # Used to signal that we should exit: 
     126                if buf is None: 
     127                    log("write thread: empty marker, exiting") 
     128                    break 
     129                try: 
     130                    while buf: 
     131                        log("write thread: writing %s", repr_ellipsized(buf)) 
     132                        buf = buf[self._conn.write(buf):] 
     133                except (OSError, IOError, socket.error), e: 
     134                    log.info("Error writing to connection: %s", e) 
     135                    main_thread_call(self._connection_lost) 
     136                    break 
     137                except TypeError: 
     138                    assert self._closed 
     139                    break 
     140                if self._write_queue.empty(): 
     141                    main_thread_call(self._maybe_queue_more_writes) 
     142        finally: 
     143            log("write thread: ended, closing socket") 
     144            self._conn.close() 
    142145 
    143146    def _read_thread_loop(self): 
     
    157160            self._read_queue.put(buf) 
    158161            main_thread_call(self._handle_read) 
     162            if not buf: 
     163                log("read thread: eof") 
     164                break 
     165        log("read thread: ended") 
    159166 
    160167    def _connection_lost(self): 
     
    204211                    unprocessed = self._decompressor.decompress(unprocessed) 
    205212                self._read_decoder = IncrBDecode(unprocessed) 
    206         return False 
     213        log("main thread: read handled") 
    207214 
    208215    def _process_packet(self, decoded): 
     
    234241            self._write_queue.put(None) 
    235242            self._closed = True 
    236             self._conn.close() 
  • trunk/src/xpra/server.py

    r159 r166  
    793793        # set this as our new one: 
    794794        if self._protocol is not None: 
    795             log.info("Disconnecting existing client") 
    796             #ensure that from now on we ignore any incoming packets coming 
    797             #from this connection as these could potentially set some keys pressed, etc 
    798             self._protocol.closing = True 
    799             self._clear_keys_pressed() 
    800             # send message asking for disconnection politely: 
    801             self._protocol.source.send_packet_now(["disconnect", "new valid connection received"]) 
    802             def force_disconnect(protocol): 
    803                 protocol.close() 
    804             #give 5 seconds for the write buffer to flush then we force disconnect it: 
    805             gobject.timeout_add(5000, force_disconnect, self._protocol) 
     795            self.disconnect("new valid connection received") 
    806796        self._protocol = proto 
    807797        ServerSource(self._protocol) 
     
    839829                self._send_new_window_packet(window) 
    840830 
     831    def disconnect(self, reason): 
     832        log.info("Disconnecting existing client, reason is: %s" % reason) 
     833        # send message asking for disconnection politely: 
     834        self._protocol.source.send_packet_now(["disconnect", reason]) 
     835        self._protocol.close() 
     836        #this ensures that from now on we ignore any incoming packets coming 
     837        #from this connection as these could potentially set some keys pressed, etc 
     838        #so it is now safe to clear them: 
     839        self._clear_keys_pressed() 
     840        log.info("Connection lost") 
     841 
     842    def _process_disconnect(self, proto, packet): 
     843        self.disconnect("on client request") 
     844 
    841845    def _process_server_settings(self, proto, packet): 
    842846        (_, settings) = packet 
     
    10161020        "jpeg-quality": _process_jpeg_quality, 
    10171021        "buffer-refresh": _process_buffer_refresh, 
     1022        "disconnect": _process_disconnect, 
    10181023        # "clipboard-*" packets are handled below: 
    10191024        Protocol.CONNECTION_LOST: _process_connection_lost, 
     
    10231028    def process_packet(self, proto, packet): 
    10241029        packet_type = packet[0] 
    1025         if self._protocol and self._protocol.closing: 
    1026             log.debug("ignoring %s packet on socket which is closing" % packet_type) 
    1027             return 
    10281030        if (isinstance(packet_type, str) 
    10291031            and packet_type.startswith("clipboard-")): 
Note: See TracChangeset for help on using the changeset viewer.