Fix invalid ICANON reader notification

This commit is contained in:
Mark 2020-06-01 12:58:51 +03:00
parent c66f205712
commit 2dd7933c0d
4 changed files with 12 additions and 1 deletions

View File

@ -8,6 +8,7 @@ struct thread;
#define RING_SIGNAL_BRK (1 << 0)
#define RING_SIGNAL_EOF (1 << 1)
#define RING_SIGNAL_RET (1 << 2)
#define RING_RAW (1 << 3)
// Ring buffer
struct ring {

View File

@ -97,7 +97,9 @@ int ring_putc(struct thread *ctx, struct ring *ring, char c, int wait) {
ring->base[ring->wr] = c;
ring_advance_write(ring);
thread_notify_io(&ring->wait);
if (ring->flags & RING_RAW) {
thread_notify_io(&ring->wait);
}
return 0;
}

View File

@ -162,6 +162,11 @@ static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg) {
return 0;
case TCSETS:
memcpy(&tty->tc, arg, sizeof(struct termios));
if (tty->tc.c_iflag & ICANON) {
tty->buffer.flags &= ~RING_RAW;
} else {
tty->buffer.flags |= RING_RAW;
}
return 0;
case TIOCGWINSZ:
// TODO: See comment on tty data struct

View File

@ -49,6 +49,7 @@ void thread_notify_io(struct io_notify *n) {
spin_lock_irqsave(&n->lock, &irq);
++n->value;
t = n->owner;
kdebug("%p->owner = %p\n", n, t);
n->owner = NULL;
spin_release_irqrestore(&n->lock, &irq);
@ -59,8 +60,10 @@ void thread_notify_io(struct io_notify *n) {
void thread_wait_io_add(struct thread *thr, struct io_notify *n) {
uintptr_t irq;
_assert(n);
spin_lock_irqsave(&n->lock, &irq);
_assert(!n->owner);
kdebug("%p->owner = %p\n", n, thr);
n->owner = thr;
list_add(&n->own_link, &thr->wait_head);
spin_release_irqrestore(&n->lock, &irq);