From 1197549e5bf8867a58c92ed07a00dc6f0362129e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 8 Sep 2017 09:57:55 +0530 Subject: [PATCH] Remove the last use of the python threading module --- kitty/child-monitor.c | 71 ++++++++++++++++++++++++++++++++++++------- kitty/child.py | 6 +--- kitty/data-types.c | 1 + kitty/data-types.h | 1 + 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 39e778ea8..b0c9f004c 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -61,6 +61,18 @@ static int signal_fds[2], wakeup_fds[2]; static void *glfw_window_id = NULL; +static inline void +set_thread_name(const char *name) { + int ret = 0; +#ifdef __APPLE__ + ret = pthread_setname_np(name); +#else + ret = pthread_setname_np(pthread_self(), name); +#endif + if (ret != 0) perror("Failed to set thread name"); +} + + // Main thread functions {{{ #define FREE_CHILD(x) \ @@ -430,6 +442,54 @@ render(ChildMonitor *self, double *timeout) { return true; } +typedef struct { int fd; uint8_t *buf; size_t sz; } ThreadWriteData; + +static inline ThreadWriteData* +alloc_twd(size_t sz) { + ThreadWriteData *data = malloc(sizeof(ThreadWriteData)); + if (data != NULL) { + data->sz = sz; + data->buf = malloc(sz); + if (data->buf == NULL) { free(data); data = NULL; } + } + return data; +} + +static inline void +free_twd(ThreadWriteData *x) { + if (x != NULL) free(x->buf); + free(x); +} + +static void* +thread_write(void *x) { + ThreadWriteData *data = (ThreadWriteData*)x; + set_thread_name("KittyWriteStdin"); + FILE *f = fdopen(data->fd, "w"); + if (fwrite(data->buf, 1, data->sz, f) != data->sz) { + fprintf(stderr, "Failed to write all data\n"); + } + fclose(f); + free_twd(data); + return 0; +} + +PyObject* +cm_thread_write(PyObject UNUSED *self, PyObject *args) { + static pthread_t thread; + int fd; + Py_ssize_t sz; + const char *buf; + if (!PyArg_ParseTuple(args, "is#", &fd, &buf, &sz)) return NULL; + ThreadWriteData *data = alloc_twd(sz); + if (data == NULL) return PyErr_NoMemory(); + data->fd = fd; + memcpy(data->buf, buf, data->sz); + int ret = pthread_create(&thread, NULL, thread_write, data); + if (ret != 0) { free_twd(data); return PyErr_SetFromErrno(PyExc_OSError); } + Py_RETURN_NONE; +} + static PyObject* main_loop(ChildMonitor *self) { #define main_loop_doc "The main thread loop" @@ -479,17 +539,6 @@ static pid_t pid_buf[MAX_CHILDREN] = {0}; static size_t pid_buf_pos = 0; static pthread_t reap_thread; -static inline void -set_thread_name(const char *name) { - int ret = 0; -#ifdef __APPLE__ - ret = pthread_setname_np(name); -#else - ret = pthread_setname_np(pthread_self(), name); -#endif - if (ret != 0) perror("Failed to set thread name"); -} - static void* reap(void *pid_p) { diff --git a/kitty/child.py b/kitty/child.py index 50e8dace3..4ac316b7f 100644 --- a/kitty/child.py +++ b/kitty/child.py @@ -5,7 +5,6 @@ import fcntl import os import sys -from threading import Thread import kitty.fast_data_types as fast_data_types @@ -38,7 +37,6 @@ class Child: if stdin is not None: stdin_read_fd, stdin_write_fd = os.pipe() remove_cloexec(stdin_read_fd) - stdin_file = os.fdopen(stdin_write_fd, 'wb') pid = os.fork() if pid == 0: # child try: @@ -75,7 +73,5 @@ class Child: self.pid = pid self.child_fd = master if stdin is not None: - t = Thread(name='WriteStdin', target=stdin_file.write, args=(stdin,)) - t.daemon = True - t.start() + fast_data_types.thread_write(stdin_write_fd, stdin) return pid diff --git a/kitty/data-types.c b/kitty/data-types.c index e3c946bb2..004ec9476 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -68,6 +68,7 @@ stop_profiler(PyObject UNUSED *self) { static PyMethodDef module_methods[] = { GL_METHODS {"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""}, + {"thread_write", (PyCFunction)cm_thread_write, METH_VARARGS, ""}, {"parse_bytes", (PyCFunction)parse_bytes, METH_VARARGS, ""}, {"parse_bytes_dump", (PyCFunction)parse_bytes_dump, METH_VARARGS, ""}, {"redirect_std_streams", (PyCFunction)redirect_std_streams, METH_VARARGS, ""}, diff --git a/kitty/data-types.h b/kitty/data-types.h index 0b82b5cdc..cfa4468c3 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -356,6 +356,7 @@ void timers_call(Timers*); bool timers_add(Timers *self, double delay, bool, PyObject *callback, PyObject *args); bool timers_add_if_missing(Timers *self, double delay, PyObject *callback, PyObject *args); bool timers_add_if_before(Timers *self, double delay, PyObject *callback, PyObject *args); +PyObject* cm_thread_write(PyObject *self, PyObject *args); bool set_iutf8(int, bool); color_type colorprofile_to_color(ColorProfile *self, color_type entry, color_type defval);