diff options
Diffstat (limited to 'auto-virtserial-guest.c')
-rw-r--r-- | auto-virtserial-guest.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/auto-virtserial-guest.c b/auto-virtserial-guest.c index eebf1f0..2c84c27 100644 --- a/auto-virtserial-guest.c +++ b/auto-virtserial-guest.c @@ -24,6 +24,7 @@ #include <error.h> #include <fcntl.h> #include <poll.h> +#include <pthread.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -44,6 +45,8 @@ static int g_bigfile_fd; static int g_length; /* The 'name' field in the sysfs port info */ static char g_sysfs_name[1024]; +/* The thread that performs a blocking read operation */ +static pthread_t g_read_thread_id; static ssize_t safewrite(int fd, const void *buf, size_t count) @@ -413,6 +416,50 @@ out: return ret; } +static void *t_blocked_read(void *arg) +{ + int port_nr = *(int *)arg; + int *ret; + + ret = malloc(sizeof(int)); + if (!ret) + return NULL; + + *ret = read_port(port_nr); + + return ret; +} + +static int create_read_thread(int nr) +{ + int ret; + + ret = pthread_create(&g_read_thread_id, NULL, &t_blocked_read, &nr); + if (ret) + return -errno; + + /* Give a chance to the thread to start and block */ + sleep(2); + + return 0; +} + +static int join_read_thread(int nr) +{ + int ret; + void *ret2; + + ret = pthread_join(g_read_thread_id, &ret2); + if (ret) + return ret; + + ret = *(int *)ret2; + + free(ret2); + + return ret; +} + static void send_report(int cfd, int ret) { struct guest_packet gpkt; @@ -539,6 +586,14 @@ back_to_open: ret = send_guest_csum(gpkt.value); send_report(cfd, ret); break; + case KEY_CREATE_READ_THREAD: + ret = create_read_thread(gpkt.value); + send_report(cfd, ret); + break; + case KEY_JOIN_READ_THREAD: + ret = join_read_thread(gpkt.value); + send_report(cfd, ret); + break; } } return 0; |