Skip to content

Commit 51b65cb

Browse files
committed
Read websocket in background to look for ctrl-c
Otherwise busy Python code that isn't reading input characters won't be interruptible. Fixes #6707
1 parent df52d99 commit 51b65cb

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

supervisor/shared/web_workflow/web_workflow.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,8 @@ void supervisor_web_workflow_background(void) {
13501350
// Close the active socket if it is no longer connected.
13511351
common_hal_socketpool_socket_close(&active);
13521352
}
1353+
1354+
websocket_background();
13531355
}
13541356

13551357
void supervisor_stop_web_workflow(void) {

supervisor/shared/web_workflow/websocket.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
#include "supervisor/shared/web_workflow/websocket.h"
2828

29+
#include "py/ringbuf.h"
30+
#include "py/runtime.h"
31+
#include "shared/runtime/interrupt_char.h"
2932
#include "supervisor/shared/title_bar.h"
3033

3134
// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server.
@@ -43,13 +46,20 @@ typedef struct {
4346
size_t payload_remaining;
4447
} _websocket;
4548

49+
// Buffer the incoming serial data in the background so that we can look for the
50+
// interrupt character.
51+
STATIC ringbuf_t _incoming_ringbuf;
52+
STATIC uint8_t _buf[16];
53+
4654
static _websocket cp_serial;
4755

4856
static const char *TAG = "CP websocket";
4957

5058
void websocket_init(void) {
5159
cp_serial.socket.num = -1;
5260
cp_serial.socket.connected = false;
61+
62+
ringbuf_init(&_incoming_ringbuf, _buf, sizeof(_buf) - 1);
5363
}
5464

5565
void websocket_handoff(socketpool_socket_obj_t *socket) {
@@ -193,16 +203,16 @@ bool websocket_available(void) {
193203
if (!websocket_connected()) {
194204
return false;
195205
}
196-
_read_next_frame_header();
197-
return cp_serial.payload_remaining > 0 && cp_serial.frame_index >= cp_serial.frame_len;
206+
websocket_background();
207+
return ringbuf_num_filled(&_incoming_ringbuf) > 0;
198208
}
199209

200210
char websocket_read_char(void) {
201-
uint8_t c;
202-
if (!_read_next_payload_byte(&c)) {
203-
c = -1;
211+
websocket_background();
212+
if (ringbuf_num_filled(&_incoming_ringbuf) > 0) {
213+
return ringbuf_get(&_incoming_ringbuf);
204214
}
205-
return c;
215+
return -1;
206216
}
207217

208218
static void _websocket_send(_websocket *ws, const char *text, size_t len) {
@@ -246,3 +256,15 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) {
246256
void websocket_write(const char *text, size_t len) {
247257
_websocket_send(&cp_serial, text, len);
248258
}
259+
260+
void websocket_background(void) {
261+
uint8_t c;
262+
while (ringbuf_num_empty(&_incoming_ringbuf) > 0 &&
263+
_read_next_payload_byte(&c)) {
264+
if (c == mp_interrupt_char) {
265+
mp_sched_keyboard_interrupt();
266+
continue;
267+
}
268+
ringbuf_put(&_incoming_ringbuf, c);
269+
}
270+
}

supervisor/shared/web_workflow/websocket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ void websocket_handoff(socketpool_socket_obj_t *socket);
3535
bool websocket_connected(void);
3636
bool websocket_available(void);
3737
char websocket_read_char(void);
38+
void websocket_background(void);
3839
void websocket_write(const char *text, size_t len);

0 commit comments

Comments
 (0)