mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-12 03:29:10 +02:00
Do not use the python threading module
Threading in python imposes significant overhead. Instead create the thread using pthreads directly
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from gettext import gettext as _
|
||||
from threading import Thread
|
||||
from time import monotonic
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
@@ -82,12 +81,11 @@ class DumpCommands: # {{{
|
||||
# }}}
|
||||
|
||||
|
||||
class Boss(Thread):
|
||||
class Boss:
|
||||
|
||||
daemon = True
|
||||
|
||||
def __init__(self, glfw_window, opts, args):
|
||||
Thread.__init__(self, name='ChildMonitor')
|
||||
self.window_id_map = WeakValueDictionary()
|
||||
startup_session = create_session(opts, args)
|
||||
self.cursor_blink_zero_time = monotonic()
|
||||
@@ -169,8 +167,10 @@ class Boss(Thread):
|
||||
for window in tab:
|
||||
self.close_window(window)
|
||||
|
||||
def run(self):
|
||||
self.child_monitor.loop()
|
||||
def start(self):
|
||||
if not getattr(self, 'io_thread_started', False):
|
||||
self.child_monitor.start()
|
||||
self.io_thread_started = True
|
||||
|
||||
def on_window_resize(self, window, w, h):
|
||||
# debounce resize events
|
||||
@@ -423,7 +423,7 @@ class Boss(Thread):
|
||||
self.shutting_down = True
|
||||
self.child_monitor.shutdown()
|
||||
wakeup()
|
||||
self.join()
|
||||
self.child_monitor.join()
|
||||
for t in self.tab_manager:
|
||||
t.destroy()
|
||||
del self.tab_manager
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#ifndef __APPLE__
|
||||
// Need _GNU_SOURCE for pthread_setname_np on linux
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#undef _GNU_SOURCE
|
||||
#include "data-types.h"
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
@@ -151,6 +156,25 @@ wakeup_(int fd) {
|
||||
}
|
||||
}
|
||||
|
||||
static void* io_loop(void *data);
|
||||
|
||||
static PyObject *
|
||||
start(ChildMonitor *self) {
|
||||
#define start_doc "start() -> Start the I/O thread"
|
||||
int ret = pthread_create(&self->io_thread, NULL, io_loop, self);
|
||||
if (ret != 0) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
join(ChildMonitor *self) {
|
||||
#define join_doc "join() -> Wait for the I/O thread to finish"
|
||||
int ret = pthread_join(self->io_thread, NULL);
|
||||
if (ret != 0) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
wakeup(ChildMonitor UNUSED *self) {
|
||||
#define wakeup_doc "wakeup() -> wakeup the ChildMonitor I/O thread, forcing it to exit from poll() if it is waiting there."
|
||||
@@ -396,15 +420,21 @@ write_to_child(int fd, Screen *screen) {
|
||||
screen_mutex(unlock, write);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
loop(ChildMonitor *self) {
|
||||
#define loop_doc "loop() -> The monitor loop."
|
||||
static void*
|
||||
io_loop(void *data) {
|
||||
// The I/O thread loop
|
||||
size_t i;
|
||||
int ret;
|
||||
bool has_more, data_received;
|
||||
Screen *screen;
|
||||
ChildMonitor *self = (ChildMonitor*)data;
|
||||
|
||||
#ifdef __APPLE__
|
||||
pthread_setname_np("ChildMonitor");
|
||||
#else
|
||||
pthread_setname_np(self->io_thread, "ChildMonitor");
|
||||
#endif
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
while (LIKELY(!self->shutting_down)) {
|
||||
children_mutex(lock);
|
||||
remove_children(self);
|
||||
@@ -455,8 +485,7 @@ loop(ChildMonitor *self) {
|
||||
remove_children(self);
|
||||
for (i = 0; i < EXTRA_FDS; i++) close(fds[i].fd);
|
||||
children_mutex(unlock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
Py_RETURN_NONE;
|
||||
return 0;
|
||||
}
|
||||
// }}}
|
||||
|
||||
@@ -464,7 +493,8 @@ loop(ChildMonitor *self) {
|
||||
static PyMethodDef methods[] = {
|
||||
METHOD(add_child, METH_VARARGS)
|
||||
METHOD(needs_write, METH_VARARGS)
|
||||
METHOD(loop, METH_NOARGS)
|
||||
METHOD(start, METH_NOARGS)
|
||||
METHOD(join, METH_NOARGS)
|
||||
METHOD(wakeup, METH_NOARGS)
|
||||
METHOD(shutdown, METH_NOARGS)
|
||||
METHOD(parse_input, METH_NOARGS)
|
||||
|
||||
@@ -284,6 +284,7 @@ typedef struct {
|
||||
double repaint_delay;
|
||||
unsigned int count;
|
||||
bool shutting_down;
|
||||
pthread_t io_thread;
|
||||
} ChildMonitor;
|
||||
PyTypeObject ChildMonitor_Type;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user