Speed un reading from child process
Do the reading into a pre-allocated buffer to avoid mallocs in the inner loop.
This commit is contained in:
parent
6e7f537850
commit
d87e4eeb95
@ -21,7 +21,7 @@ from .char_grid import CharGrid
|
||||
from .keys import interpret_text_event, interpret_key_event
|
||||
from .utils import resize_pty, create_pty, sanitize_title
|
||||
from .fast_data_types import (
|
||||
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, parse_bytes_dump, parse_bytes
|
||||
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump, read_bytes
|
||||
)
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ class Boss(Thread):
|
||||
self.window, self.opts = window, opts
|
||||
self.screen = Screen(self)
|
||||
self.char_grid = CharGrid(self.screen, opts, window_width, window_height)
|
||||
self.parse_bytes = partial(parse_bytes_dump, print) if args.dump_commands else parse_bytes
|
||||
self.read_bytes = partial(read_bytes_dump, print) if args.dump_commands else read_bytes
|
||||
self.write_buf = memoryview(b'')
|
||||
glfw.glfwSetCharModsCallback(window, self.on_text_input)
|
||||
glfw.glfwSetKeyCallback(window, self.on_key)
|
||||
@ -201,16 +201,8 @@ class Boss(Thread):
|
||||
def read_ready(self):
|
||||
if self.shutting_down:
|
||||
return
|
||||
try:
|
||||
data = os.read(self.child_fd, 100 * io.DEFAULT_BUFFER_SIZE)
|
||||
except BlockingIOError:
|
||||
return
|
||||
except EnvironmentError:
|
||||
data = b''
|
||||
if data:
|
||||
self.parse_bytes(self.screen, data)
|
||||
else: # EOF
|
||||
self.shutdown()
|
||||
if self.read_bytes(self.screen, self.child_fd) is False:
|
||||
self.shutdown() # EOF
|
||||
|
||||
def write_ready(self):
|
||||
if not self.shutting_down:
|
||||
|
||||
@ -13,6 +13,8 @@ static PyMethodDef module_methods[] = {
|
||||
GL_METHODS
|
||||
{"parse_bytes", (PyCFunction)parse_bytes, METH_VARARGS, ""},
|
||||
{"parse_bytes_dump", (PyCFunction)parse_bytes_dump, METH_VARARGS, ""},
|
||||
{"read_bytes", (PyCFunction)read_bytes, METH_VARARGS, ""},
|
||||
{"read_bytes_dump", (PyCFunction)read_bytes_dump, METH_VARARGS, ""},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
@ -231,6 +231,7 @@ typedef struct {
|
||||
} SavepointBuffer;
|
||||
|
||||
#define PARSER_BUF_SZ 8192
|
||||
#define READ_BUF_SZ (1024*1024)
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
@ -250,6 +251,7 @@ typedef struct {
|
||||
uint8_t parser_buf[PARSER_BUF_SZ];
|
||||
unsigned int parser_state, parser_text_start, parser_buf_pos;
|
||||
bool parser_has_pending_text;
|
||||
uint8_t read_buf[READ_BUF_SZ];
|
||||
|
||||
} Screen;
|
||||
PyTypeObject Screen_Type;
|
||||
@ -275,6 +277,8 @@ int init_SpriteMap(PyObject *);
|
||||
int init_ChangeTracker(PyObject *);
|
||||
int init_Screen(PyObject *);
|
||||
PyObject* create_256_color_table();
|
||||
PyObject* read_bytes_dump(PyObject UNUSED *, PyObject *);
|
||||
PyObject* read_bytes(PyObject UNUSED *, PyObject *);
|
||||
PyObject* parse_bytes_dump(PyObject UNUSED *, PyObject *);
|
||||
PyObject* parse_bytes(PyObject UNUSED *, PyObject *);
|
||||
uint16_t* translation_table(char);
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "data-types.h"
|
||||
#include "control-codes.h"
|
||||
|
||||
@ -554,3 +556,34 @@ parse_bytes(PyObject UNUSED *self, PyObject *args) {
|
||||
_parse_bytes(screen, pybuf.buf, pybuf.len, dump_callback);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
#ifdef DUMP_COMMANDS
|
||||
read_bytes_dump(PyObject UNUSED *self, PyObject *args) {
|
||||
#else
|
||||
read_bytes(PyObject UNUSED *self, PyObject *args) {
|
||||
#endif
|
||||
PyObject *dump_callback = NULL;
|
||||
Py_ssize_t len;
|
||||
Screen *screen;
|
||||
int fd;
|
||||
#ifdef DUMP_COMMANDS
|
||||
if (!PyArg_ParseTuple(args, "OOi", &dump_callback, &screen, &fd)) return NULL;
|
||||
#else
|
||||
if (!PyArg_ParseTuple(args, "Oi", &screen, &fd)) return NULL;
|
||||
#endif
|
||||
|
||||
while(true) {
|
||||
len = read(fd, screen->read_buf, READ_BUF_SZ);
|
||||
if (len == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
if (errno == EIO) { Py_RETURN_FALSE; }
|
||||
return PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_parse_bytes(screen, screen->read_buf, len, dump_callback);
|
||||
if(len > 0) { Py_RETURN_TRUE; }
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user