Fix RFC2217 server death

We now properly kick the connected clients hanging in reads (cu) instead
of locking up.
This commit is contained in:
Kim Woelders
2018-10-17 13:50:47 +02:00
parent 1e05632ec0
commit 673ddd9739
+10 -5
View File
@@ -56,7 +56,8 @@ static struct ttynvt_param {
typedef struct { typedef struct {
pthread_mutex_t tty_lock; pthread_mutex_t tty_lock;
pthread_mutex_t poll_lock; pthread_mutex_t poll_lock;
pthread_t thread_id; pthread_t ptid_poll;
pthread_t ptid_read;
struct fuse_pollhandle *ph; struct fuse_pollhandle *ph;
@@ -186,8 +187,8 @@ static void ttynvt_release(fuse_req_t req, struct fuse_file_info *info)
close(tty->fds[FD_MASTER].fd); close(tty->fds[FD_MASTER].fd);
close(tty->fds[FD_SLAVE].fd); close(tty->fds[FD_SLAVE].fd);
pthread_cancel(tty->thread_id); pthread_cancel(tty->ptid_poll);
pthread_join(tty->thread_id, NULL); pthread_join(tty->ptid_poll, NULL);
pthread_mutex_destroy(&tty->tty_lock); pthread_mutex_destroy(&tty->tty_lock);
pthread_mutex_destroy(&tty->poll_lock); pthread_mutex_destroy(&tty->poll_lock);
@@ -302,6 +303,8 @@ static void *_read_net(void *arg)
} }
DBG2("%s: done\n", __func__); DBG2("%s: done\n", __func__);
if (tty->ptid_read)
pthread_kill(tty->ptid_read, SIGUSR2);
tty->error = 1; tty->error = 1;
_notify(tty); _notify(tty);
@@ -508,7 +511,7 @@ static void ttynvt_open(fuse_req_t req, struct fuse_file_info *info)
} }
if ((res = pthread_mutex_init(&tty->tty_lock, NULL) < 0) || if ((res = pthread_mutex_init(&tty->tty_lock, NULL) < 0) ||
(res = pthread_mutex_init(&tty->poll_lock, NULL) < 0) || (res = pthread_mutex_init(&tty->poll_lock, NULL) < 0) ||
(res = pthread_create(&tty->thread_id, NULL, &_read_net, tty))) (res = pthread_create(&tty->ptid_poll, NULL, &_read_net, tty)))
{ {
errno = res; errno = res;
goto open_err; goto open_err;
@@ -569,9 +572,11 @@ ttynvt_read(fuse_req_t req, size_t size, off_t off,
if (size > TMP_BUF_SIZE) if (size > TMP_BUF_SIZE)
size = TMP_BUF_SIZE; size = TMP_BUF_SIZE;
fuse_req_interrupt_func(req, ttynvt_interrupted, (void *)pthread_self()); tty->ptid_read = pthread_self();
fuse_req_interrupt_func(req, ttynvt_interrupted, (void *)tty->ptid_read);
res = _is_interrupted ? -2 : read(tty->fds[FD_SLAVE].fd, buf, size); res = _is_interrupted ? -2 : read(tty->fds[FD_SLAVE].fd, buf, size);
_is_interrupted = 0; _is_interrupted = 0;
tty->ptid_read = 0;
tty->n_fds = 3; /* Enable polling of Slave */ tty->n_fds = 3; /* Enable polling of Slave */
fuse_req_interrupt_func(req, NULL, NULL); fuse_req_interrupt_func(req, NULL, NULL);
if (res < 0) if (res < 0)