From b24fdd90aee29a5e6362be5d8f061f7cbd500052 Mon Sep 17 00:00:00 2001 From: Gediminas Jakutis Date: Tue, 21 May 2019 19:01:32 +0300 Subject: daemon: added stdio (null) im proto stubs. Signed-off-by: Gediminas Jakutis --- src/daemon/meson.build | 2 ++ src/daemon/proto_stdio.c | 69 ++++++++++++++++++++++++++++++++++++++++ src/daemon/proto_stdio_private.h | 42 ++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/daemon/proto_stdio.c create mode 100644 src/daemon/proto_stdio_private.h (limited to 'src/daemon') diff --git a/src/daemon/meson.build b/src/daemon/meson.build index aa0aa75..d900949 100644 --- a/src/daemon/meson.build +++ b/src/daemon/meson.build @@ -3,8 +3,10 @@ d_filenames = [ 'settings.c', 'net.c', 'purple.c', + 'proto_stdio.c', 'settings_private.h', 'purple_private.h', + 'proto_stdio_private.h', ] d_conf_filenames = [ diff --git a/src/daemon/proto_stdio.c b/src/daemon/proto_stdio.c new file mode 100644 index 0000000..ee4af9a --- /dev/null +++ b/src/daemon/proto_stdio.c @@ -0,0 +1,69 @@ +/* + * Usurpation – null (stdio) im proto + * + * Copyright (C) 2019 Gediminas Jakutis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "proto_stdio.h" +#include "proto_stdio_private.h" + +/* TODO: stub! */ +static void *read_stdin(void *arg) +{ + return arg; +} + +/* TODO: stub! */ +static void *write_stdout(void *arg) +{ + return arg; +} + +int proto_stdio_init(void) +{ + + int ret = 0; + + /* aquire the """singleton""" mutex */ + if (pthread_mutex_trylock(&state.mutex)) { + /* TODO: use proper error numbers */ + ret = 1; + } else { + if ((ret = pthread_create(&state.stdio_in, NULL, read_stdin, NULL))) { + proto_stdio_close(); + } + + if ((ret = pthread_create(&state.stdio_out, NULL, write_stdout, NULL))) { + proto_stdio_close(); + } + } + + return ret; +} + +void proto_stdio_close(void) +{ + if (pthread_mutex_trylock(&state.mutex) == EBUSY) { + pthread_cancel(state.stdio_in); + pthread_cancel(state.stdio_out); + pthread_join(state.stdio_in, NULL); + pthread_join(state.stdio_out, NULL); + } + + pthread_mutex_unlock(&state.mutex); +} diff --git a/src/daemon/proto_stdio_private.h b/src/daemon/proto_stdio_private.h new file mode 100644 index 0000000..bed159b --- /dev/null +++ b/src/daemon/proto_stdio_private.h @@ -0,0 +1,42 @@ +/* + * Usurpation – null (stdio) im proto + * + * Copyright (C) 2019 Gediminas Jakutis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef USURPATION_PROTO_STDIO_PRIVATE_H +#define USURPATION_PROTO_STDIO_PRIVATE_H + +#include +#include + +static struct state { + pthread_mutex_t mutex; + pthread_t stdio_in; + pthread_t stdio_out; + pthread_mutex_t in_m; + pthread_mutex_t out_m; + char *readbuf; + char *writebuf; + ssize_t readbufsize; + ssize_t writebufsize; +} state = {PTHREAD_MUTEX_INITIALIZER, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, NULL, NULL, 0, 0}; + +static void *read_stdin(void *arg); +static void *write_stdout(void *arg); + +#endif /* USURPATION_PROTO_STDIO_PRIVATE_H */ -- cgit v1.2.3 From 92dbb5804e65b9802cdb8e788e6a7503d31a89e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulius=20Ratkevi=C4=8Dius?= Date: Tue, 21 May 2019 20:04:23 +0300 Subject: daemon: implemented stdio interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paulius Ratkevičius --- src/daemon/proto_stdio.c | 54 +++++++++++++++++++++++++++++++++++++--- src/daemon/proto_stdio_private.h | 3 ++- 2 files changed, 52 insertions(+), 5 deletions(-) (limited to 'src/daemon') diff --git a/src/daemon/proto_stdio.c b/src/daemon/proto_stdio.c index ee4af9a..35fd467 100644 --- a/src/daemon/proto_stdio.c +++ b/src/daemon/proto_stdio.c @@ -2,6 +2,7 @@ * Usurpation – null (stdio) im proto * * Copyright (C) 2019 Gediminas Jakutis + * Copyright (C) 2019 Paulius Ratkevičius * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,18 +23,63 @@ #include "proto_stdio.h" #include "proto_stdio_private.h" -/* TODO: stub! */ + +void message_receive(char *arg) +{ + int done = 0; + while(!done) + { + pthread_mutex_lock(&state.out_m); + if(!state.writebuf) + { + state.writebuf = strdup(arg); + done = 1; + } + pthread_mutex_unlock(&state.out_m); + } +} + +char * message_send(void) +{ + char * ret; + pthread_mutex_lock(&state.out_m); + ret = strdup(state.writebuf); + free(state.writebuf); + state.writebuf = NULL; + pthread_mutex_unlock(&state.out_m); + return ret; +} + static void *read_stdin(void *arg) { - return arg; + while(1) + { + pthread_mutex_lock(&state.in_m); + if(!state.readbuf) + { + state.readbufsize = getline(&state.readbuf,NULL, stdin); + } + pthread_mutex_unlock(&state.in_m); + } } -/* TODO: stub! */ + static void *write_stdout(void *arg) { - return arg; + while(1) + { + pthread_mutex_lock(&state.out_m); + if(state.writebuf) + { + printf("%s", state.writebuf); + free(state.writebuf); + state.writebuf = NULL; + } + pthread_mutex_unlock(&state.out_m); + } } + int proto_stdio_init(void) { diff --git a/src/daemon/proto_stdio_private.h b/src/daemon/proto_stdio_private.h index bed159b..1fa48d4 100644 --- a/src/daemon/proto_stdio_private.h +++ b/src/daemon/proto_stdio_private.h @@ -2,7 +2,7 @@ * Usurpation – null (stdio) im proto * * Copyright (C) 2019 Gediminas Jakutis - * + * Copyright (C) 2019 Paulius Ratkevičius * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 @@ -21,6 +21,7 @@ #ifndef USURPATION_PROTO_STDIO_PRIVATE_H #define USURPATION_PROTO_STDIO_PRIVATE_H +#include #include #include -- cgit v1.2.3 From 9e3e2a9d886f8191bccc69ccc356f683e4a0c561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulius=20Ratkevi=C4=8Dius?= Date: Tue, 21 May 2019 20:13:34 +0300 Subject: daemon: fixed some dumb mistakes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paulius Ratkevičius --- src/daemon/proto_stdio.c | 2 ++ src/daemon/proto_stdio_private.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/daemon') diff --git a/src/daemon/proto_stdio.c b/src/daemon/proto_stdio.c index 35fd467..533dc76 100644 --- a/src/daemon/proto_stdio.c +++ b/src/daemon/proto_stdio.c @@ -61,6 +61,7 @@ static void *read_stdin(void *arg) } pthread_mutex_unlock(&state.in_m); } + return NULL; } @@ -77,6 +78,7 @@ static void *write_stdout(void *arg) } pthread_mutex_unlock(&state.out_m); } + return NULL; } diff --git a/src/daemon/proto_stdio_private.h b/src/daemon/proto_stdio_private.h index 1fa48d4..4b0ab6f 100644 --- a/src/daemon/proto_stdio_private.h +++ b/src/daemon/proto_stdio_private.h @@ -21,6 +21,8 @@ #ifndef USURPATION_PROTO_STDIO_PRIVATE_H #define USURPATION_PROTO_STDIO_PRIVATE_H +#include +#include #include #include #include -- cgit v1.2.3 From 81602e816f9d1e9ae0fa06482037e79bb8750806 Mon Sep 17 00:00:00 2001 From: Gediminas Jakutis Date: Sun, 26 May 2019 15:58:13 +0300 Subject: daemon: improve threading logic on null proto. Functions now prevent interruptions that can produce an inconsistent state in the program. Also, cosmetic changes. Signed-off-by: Gediminas Jakutis --- src/daemon/proto_stdio.c | 116 +++++++++++++++++++++++++-------------- src/daemon/proto_stdio_private.h | 2 + 2 files changed, 77 insertions(+), 41 deletions(-) (limited to 'src/daemon') diff --git a/src/daemon/proto_stdio.c b/src/daemon/proto_stdio.c index 533dc76..f0a22a6 100644 --- a/src/daemon/proto_stdio.c +++ b/src/daemon/proto_stdio.c @@ -26,59 +26,93 @@ void message_receive(char *arg) { - int done = 0; - while(!done) - { - pthread_mutex_lock(&state.out_m); - if(!state.writebuf) - { - state.writebuf = strdup(arg); - done = 1; - } - pthread_mutex_unlock(&state.out_m); - } + int cancelstate; + int done = 0; + + while (!done) { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate); + pthread_mutex_lock(&state.out_m); + if (!state.writebuf) { + state.writebuf = strdup(arg); + done = 1; + } + pthread_mutex_unlock(&state.out_m); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate); + pthread_testcancel(); + } } -char * message_send(void) +char *message_send(void) { - char * ret; - pthread_mutex_lock(&state.out_m); - ret = strdup(state.writebuf); - free(state.writebuf); - state.writebuf = NULL; - pthread_mutex_unlock(&state.out_m); - return ret; + char *ret; + int cancelstate; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate); + pthread_mutex_lock(&state.out_m); + ret = strdup(state.readbuf); + free(state.readbuf); + state.readbuf = NULL; + state.readbufsize = 0; + pthread_mutex_unlock(&state.out_m); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate); + pthread_testcancel(); + + return ret; } static void *read_stdin(void *arg) { - while(1) - { - pthread_mutex_lock(&state.in_m); - if(!state.readbuf) - { - state.readbufsize = getline(&state.readbuf,NULL, stdin); - } - pthread_mutex_unlock(&state.in_m); - } - return NULL; + int cancelstate; + + (void) arg; + + while(1) { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate); + pthread_mutex_lock(&state.in_m); + + if (!state.readbuf) { + state.readbufsize = getline(&state.readbuf, NULL, stdin); + } + + pthread_mutex_unlock(&state.in_m); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate); + pthread_testcancel(); + nanosleep(&respite, NULL); + } + + return NULL; } static void *write_stdout(void *arg) { - while(1) - { - pthread_mutex_lock(&state.out_m); - if(state.writebuf) - { - printf("%s", state.writebuf); - free(state.writebuf); - state.writebuf = NULL; - } - pthread_mutex_unlock(&state.out_m); - } - return NULL; + int cancelstate; + + (void) arg; + + while(1) { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate); + pthread_mutex_lock(&state.out_m); + + if (state.writebuf) { + if (state.writebuf[strlen(state.writebuf) - 1] == '\n') { + printf("%s", state.writebuf); + } else { + printf("%s\n", state.writebuf); + } + + free(state.writebuf); + state.writebuf = NULL; + state.writebufsize = 0; + } + + pthread_mutex_unlock(&state.out_m); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate); + pthread_testcancel(); + nanosleep(&respite, NULL); + } + + return NULL; } diff --git a/src/daemon/proto_stdio_private.h b/src/daemon/proto_stdio_private.h index 4b0ab6f..209d191 100644 --- a/src/daemon/proto_stdio_private.h +++ b/src/daemon/proto_stdio_private.h @@ -42,4 +42,6 @@ static struct state { static void *read_stdin(void *arg); static void *write_stdout(void *arg); +static const struct timespec respite = {0, 10 * 1000 * 1000}; /* 10ms */ + #endif /* USURPATION_PROTO_STDIO_PRIVATE_H */ -- cgit v1.2.3