10000 extmod/modwebsocket: Add option for blocking writes to non-blk sockets. · mimoccc/circuitpython@5b1c221 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5b1c221

Browse files
committed
extmod/modwebsocket: Add option for blocking writes to non-blk sockets.
This is strange asymmetry which is sometimes needed, e.g. for WebREPL: we want to process only available input and no more; but for output, we want to get rid of all of it, because there's no other place to buffer/store it. This asymmetry is akin to CPython's asyncio asymmetry, where reads are asynchronous, but writes are synchronous (asyncio doesn't expect them to block, instead expects there to be (unlimited) buffering for any sync write to completely immediately).
1 parent 397b705 commit 5b1c221

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

extmod/modwebsocket.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#if MICROPY_PY_WEBSOCKET
3838

3939
enum { FRAME_HEADER, FRAME_OPT, PAYLOAD };
40+
enum { BLOCKING_WRITE = 1 };
4041

4142
typedef struct _mp_obj_websocket_t {
4243
mp_obj_base_t base;
@@ -48,17 +49,22 @@ typedef struct _mp_obj_websocket_t {
4849
byte mask_pos;
4950
byte buf_pos;
5051
byte buf[6];
52+
byte opts;
5153
} mp_obj_websocket_t;
5254

5355
STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
54-
mp_arg_check_num(n_args, n_kw, 1, 1, false);
56+
mp_arg_check_num(n_args, n_kw, 1, 2, false);
5557
mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t);
5658
o->base.type = type;
5759
o->sock = args[0];
5860
o->state = FRAME_HEADER;
5961
o->to_recv = 2;
6062
o->mask_pos = 0;
6163
o->buf_pos = 0;
64+
o->opts = 0;
65+
if (n_args > 1 && args[1] == mp_const_true) {
66+
o->opts |= BLOCKING_WRITE;
67+
}
6268
return o;
6369
}
6470

@@ -157,11 +163,24 @@ STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t si
157163
assert(size < 126);
158164
byte header[] = {0x81, size};
159165

166+
mp_obj_t dest[3];
167+
if (self->opts & BLOCKING_WRITE) {
168+
mp_load_method(self->sock, MP_QSTR_setblocking, dest);
169+
dest[2] = mp_const_true;
170+
mp_call_method_n_kw(1, 0, dest);
171+
}
172+
160173
mp_uint_t out_sz = mp_stream_writeall(self->sock, header, sizeof(header), errcode);
161-
if (out_sz == MP_STREAM_ERROR) {
162-
return MP_STREAM_ERROR;
174+
if (out_sz != MP_STREAM_ERROR) {
175+
out_sz = mp_stream_writeall(self->sock, buf, size, errcode);
163176
}
164-
return mp_stream_writeall(self->sock, buf, size, errcode);
177+
178+
if (self->opts & BLOCKING_WRITE) {
179+
dest[2] = mp_const_false;
180+
mp_call_method_n_kw(1, 0, dest);
181+
}
182+
183+
return out_sz;
165184
}
166185

167186
STATIC const mp_map_elem_t websocket_locals_dict_table[] = {

0 commit comments

Comments
 (0)
0