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 .keys import interpret_text_event, interpret_key_event
|
||||||
from .utils import resize_pty, create_pty, sanitize_title
|
from .utils import resize_pty, create_pty, sanitize_title
|
||||||
from .fast_data_types import (
|
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.window, self.opts = window, opts
|
||||||
self.screen = Screen(self)
|
self.screen = Screen(self)
|
||||||
self.char_grid = CharGrid(self.screen, opts, window_width, window_height)
|
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'')
|
self.write_buf = memoryview(b'')
|
||||||
glfw.glfwSetCharModsCallback(window, self.on_text_input)
|
glfw.glfwSetCharModsCallback(window, self.on_text_input)
|
||||||
glfw.glfwSetKeyCallback(window, self.on_key)
|
glfw.glfwSetKeyCallback(window, self.on_key)
|
||||||
@ -201,16 +201,8 @@ class Boss(Thread):
|
|||||||
def read_ready(self):
|
def read_ready(self):
|
||||||
if self.shutting_down:
|
if self.shutting_down:
|
||||||
return
|
return
|
||||||
try:
|
if self.read_bytes(self.screen, self.child_fd) is False:
|
||||||
data = os.read(self.child_fd, 100 * io.DEFAULT_BUFFER_SIZE)
|
self.shutdown() # EOF
|
||||||
except BlockingIOError:
|
|
||||||
return
|
|
||||||
except EnvironmentError:
|
|
||||||
data = b''
|
|
||||||
if data:
|
|
||||||
self.parse_bytes(self.screen, data)
|
|
||||||
else: # EOF
|
|
||||||
self.shutdown()
|
|
||||||
|
|
||||||
def write_ready(self):
|
def write_ready(self):
|
||||||
if not self.shutting_down:
|
if not self.shutting_down:
|
||||||
|
|||||||
@ -13,6 +13,8 @@ static PyMethodDef module_methods[] = {
|
|||||||
GL_METHODS
|
GL_METHODS
|
||||||
{"parse_bytes", (PyCFunction)parse_bytes, METH_VARARGS, ""},
|
{"parse_bytes", (PyCFunction)parse_bytes, METH_VARARGS, ""},
|
||||||
{"parse_bytes_dump", (PyCFunction)parse_bytes_dump, 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 */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -231,6 +231,7 @@ typedef struct {
|
|||||||
} SavepointBuffer;
|
} SavepointBuffer;
|
||||||
|
|
||||||
#define PARSER_BUF_SZ 8192
|
#define PARSER_BUF_SZ 8192
|
||||||
|
#define READ_BUF_SZ (1024*1024)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
@ -250,6 +251,7 @@ typedef struct {
|
|||||||
uint8_t parser_buf[PARSER_BUF_SZ];
|
uint8_t parser_buf[PARSER_BUF_SZ];
|
||||||
unsigned int parser_state, parser_text_start, parser_buf_pos;
|
unsigned int parser_state, parser_text_start, parser_buf_pos;
|
||||||
bool parser_has_pending_text;
|
bool parser_has_pending_text;
|
||||||
|
uint8_t read_buf[READ_BUF_SZ];
|
||||||
|
|
||||||
} Screen;
|
} Screen;
|
||||||
PyTypeObject Screen_Type;
|
PyTypeObject Screen_Type;
|
||||||
@ -275,6 +277,8 @@ int init_SpriteMap(PyObject *);
|
|||||||
int init_ChangeTracker(PyObject *);
|
int init_ChangeTracker(PyObject *);
|
||||||
int init_Screen(PyObject *);
|
int init_Screen(PyObject *);
|
||||||
PyObject* create_256_color_table();
|
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_dump(PyObject UNUSED *, PyObject *);
|
||||||
PyObject* parse_bytes(PyObject UNUSED *, PyObject *);
|
PyObject* parse_bytes(PyObject UNUSED *, PyObject *);
|
||||||
uint16_t* translation_table(char);
|
uint16_t* translation_table(char);
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
#include "control-codes.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);
|
_parse_bytes(screen, pybuf.buf, pybuf.len, dump_callback);
|
||||||
Py_RETURN_NONE;
|
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