reader thread reads and dispatches commands in an infinite loop
| 151 | |
| 152 | |
| 153 | class ReaderThread(PyDBDaemonThread): |
| 154 | """reader thread reads and dispatches commands in an infinite loop""" |
| 155 | |
| 156 | def __init__(self, sock, py_db, PyDevJsonCommandProcessor, process_net_command, terminate_on_socket_close=True): |
| 157 | assert sock is not None |
| 158 | PyDBDaemonThread.__init__(self, py_db) |
| 159 | self.__terminate_on_socket_close = terminate_on_socket_close |
| 160 | |
| 161 | self.sock = sock |
| 162 | self._buffer = b"" |
| 163 | self.name = "pydevd.Reader" |
| 164 | self.process_net_command = process_net_command |
| 165 | self.process_net_command_json = PyDevJsonCommandProcessor(self._from_json).process_net_command_json |
| 166 | |
| 167 | def _from_json(self, json_msg, update_ids_from_dap=False): |
| 168 | return pydevd_base_schema.from_json(json_msg, update_ids_from_dap, on_dict_loaded=self._on_dict_loaded) |
| 169 | |
| 170 | def _on_dict_loaded(self, dct): |
| 171 | for listener in self.py_db.dap_messages_listeners: |
| 172 | listener.after_receive(dct) |
| 173 | |
| 174 | @overrides(PyDBDaemonThread.do_kill_pydev_thread) |
| 175 | def do_kill_pydev_thread(self): |
| 176 | PyDBDaemonThread.do_kill_pydev_thread(self) |
| 177 | # Note that we no longer shutdown the reader, just the writer. The idea is that we shutdown |
| 178 | # the writer to send that the communication has finished, then, the client will shutdown its |
| 179 | # own writer when it receives an empty read, at which point this reader will also shutdown. |
| 180 | |
| 181 | # That way, we can *almost* guarantee that all messages have been properly sent -- it's not |
| 182 | # completely guaranteed because it's possible that the process exits before the whole |
| 183 | # message was sent as having this thread alive won't stop the process from exiting -- we |
| 184 | # have a timeout when exiting the process waiting for this thread to finish -- see: |
| 185 | # PyDB.dispose_and_kill_all_pydevd_threads()). |
| 186 | |
| 187 | # try: |
| 188 | # self.sock.shutdown(SHUT_RD) |
| 189 | # except: |
| 190 | # pass |
| 191 | # try: |
| 192 | # self.sock.close() |
| 193 | # except: |
| 194 | # pass |
| 195 | |
| 196 | def _read(self, size): |
| 197 | while True: |
| 198 | buffer_len = len(self._buffer) |
| 199 | if buffer_len == size: |
| 200 | ret = self._buffer |
| 201 | self._buffer = b"" |
| 202 | return ret |
| 203 | |
| 204 | if buffer_len > size: |
| 205 | ret = self._buffer[:size] |
| 206 | self._buffer = self._buffer[size:] |
| 207 | return ret |
| 208 | |
| 209 | try: |
| 210 | r = self.sock.recv(max(size - buffer_len, 1024)) |