diff options
author | Jacob Moody <moody@posixcafe.org> | 2022-08-21 22:24:45 +0000 |
---|---|---|
committer | Jacob Moody <moody@posixcafe.org> | 2022-08-21 22:24:45 +0000 |
commit | 6c8de2713c34622799504f9817afe6876c5621cf (patch) | |
tree | 53c0c2158472165514455977924695ffa8de1934 /sys/src/cmd/rio | |
parent | aea866a49300a5e31e737d8fe54763711e693f05 (diff) |
rio: kbdtap deadlocks are verboden
This should make kbdtap related deadlocks
impossible. The tap thread has been rewritten
to use one alt which always allows for the window
handling code to nofiy us regardless if we're send'ing or
recv'ing. We also move the start/stop messages to their
own channel and can the reset code for now.
Diffstat (limited to 'sys/src/cmd/rio')
-rw-r--r-- | sys/src/cmd/rio/dat.h | 17 | ||||
-rw-r--r-- | sys/src/cmd/rio/rio.c | 105 | ||||
-rw-r--r-- | sys/src/cmd/rio/wind.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/rio/xfid.c | 4 |
4 files changed, 83 insertions, 47 deletions
diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index 6d9ba8495..bca6cfc79 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -121,12 +121,6 @@ struct Mouseinfo uchar qfull; /* filled the queue; no more recording until client comes back */ }; -enum{ - Tapon = 'b', - Tapoff = 'e', - Tapreset = 'r', -}; - struct Window { Ref; @@ -322,8 +316,15 @@ int nwindow; int snarffd; int gotscreen; int servekbd; -Channel *fromtap; /* input from kbd tap program to window */ -Channel *totap; /* our keyboard input to tap program */ + +enum{ + Tapon = 'b', + Tapoff = 'e', +}; +Channel *ctltap; /* on/off messages */ +Channel *fromtap; /* input from kbd tap program to window */ +Channel *totap; /* our keyboard input to tap program */ +Channel *wintap; /* tell the tapthread which Window to send to */ Window *input; QLock all; /* BUG */ Filsys *filsys; diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index 982272183..d3cd581de 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -198,6 +198,8 @@ threadmain(int argc, char *argv[]) error("can't find keyboard"); totap = chancreate(sizeof(char*), 32); fromtap = chancreate(sizeof(char*), 32); + wintap = chancreate(sizeof(Window*), 0); + ctltap = chancreate(sizeof(Window*), 0); proccreate(keyboardtap, nil, STACK); wscreen = allocscreen(screen, background, 0); @@ -339,62 +341,93 @@ killprocs(void) void keyboardtap(void*) { - char *s; - Channel *out; + char *s, *ctl; + Window *w, *cur; int mode; - enum { Kdev, Ktap, NALT}; + enum { Awin, Actl, Afrom, Adev, Ato, Ainp, NALT }; enum { Mnorm, Mtap }; threadsetname("keyboardtap"); static Alt alts[NALT+1]; - alts[Kdev].c = kbdchan; - alts[Kdev].v = &s; - alts[Kdev].op = CHANRCV; - alts[Ktap].c = fromtap; - alts[Ktap].v = &s; - alts[Ktap].op = CHANRCV; + /* ctl */ + alts[Awin].c = wintap; + alts[Awin].v = &w; + alts[Awin].op = CHANRCV; + alts[Actl].c = ctltap; + alts[Actl].v = &ctl; + alts[Actl].op = CHANRCV; + /* kbd input */ + alts[Afrom].c = fromtap; + alts[Afrom].v = &s; + alts[Afrom].op = CHANRCV; + alts[Adev].c = kbdchan; + alts[Adev].v = &s; + alts[Adev].op = CHANRCV; + /* kbd output */ + alts[Ato].c = totap; + alts[Ato].v = &s; + alts[Ato].op = CHANNOP; + alts[Ainp].c = nil; + alts[Ainp].v = &s; + alts[Ainp].op = CHANNOP; alts[NALT].op = CHANEND; - out = nil; + cur = nil; mode = Mnorm; for(;;) switch(alt(alts)){ - case Ktap: - switch(*s){ - case 'K': case 'k': case 'c': + case Awin: + cur = w; + if(cur != nil){ + alts[Ainp].c = cur->ck; break; - case Tapreset: - if(mode != Mtap) - goto Next; - goto Send; - case Tapoff: - mode = Mnorm; - goto Next; + } + if(alts[Ainp].op != CHANNOP || alts[Ato].op != CHANNOP) + free(s); + goto Reset; + case Actl: + switch(*ctl){ case Tapon: mode = Mtap; - /* fallthrough */ - default: - Next: - free(s); - continue; + break; + case Tapoff: + mode = Mnorm; + break; } - out = input == nil ? nil : input->ck; - goto Send; - case Kdev: - switch(mode){ - case Mnorm: - out = input == nil ? nil : input->ck; + free(ctl); + break; + case Afrom: + if(cur == nil){ + free(s); break; - case Mtap: - out = totap; + } + alts[Afrom].op = CHANNOP; + alts[Adev].op = CHANNOP; + alts[Ato].op = CHANNOP; + alts[Ainp].op = CHANSND; + break; + case Adev: + if(mode == Mnorm && cur == nil){ + free(s); break; } - Send: + alts[Afrom].op = CHANNOP; + alts[Adev].op = CHANNOP; + if(mode == Mnorm) + alts[Ainp].op = CHANSND; + else + alts[Ato].op = CHANSND; + break; + case Ainp: if(*s == 'k' || *s == 'K') shiftdown = utfrune(s+1, Kshift) != nil; - if(out == nil || sendp(out, s) <= 0) - free(s); + case Ato: + Reset: + alts[Ainp].op = CHANNOP; + alts[Ato].op = CHANNOP; + alts[Afrom].op = CHANRCV; + alts[Adev].op = CHANRCV; break; } } diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c index d6e6c3ff6..0bb63c83a 100644 --- a/sys/src/cmd/rio/wind.c +++ b/sys/src/cmd/rio/wind.c @@ -83,13 +83,14 @@ wcurrent(Window *w) Channel *c; if(input == nil){ + sendp(wintap, w); input = w; return; } if(w == input) return; - chanprint(fromtap, "%c", Tapreset); incref(input); + sendp(wintap, w); c = chancreate(sizeof(Window*), 0); wsendctlmesg(input, Repaint, ZR, c); sendp(c, w); /* send the new input */ @@ -1304,6 +1305,7 @@ wclunk(Window *w) return; w->deleted = TRUE; if(w == input){ + sendp(wintap, nil); input = nil; riosetcursor(nil); } diff --git a/sys/src/cmd/rio/xfid.c b/sys/src/cmd/rio/xfid.c index 383d2cee7..cd7f57387 100644 --- a/sys/src/cmd/rio/xfid.c +++ b/sys/src/cmd/rio/xfid.c @@ -308,7 +308,7 @@ xfidopen(Xfid *x) } break; case Qtap: - chanprint(fromtap, "%c", Tapon); + chanprint(ctltap, "%c", Tapon); break; } t.qid = x->f->qid; @@ -365,7 +365,7 @@ xfidclose(Xfid *x) w->wctlopen = FALSE; break; case Qtap: - chanprint(fromtap, "%c", Tapoff); + chanprint(ctltap, "%c", Tapoff); break; } wclose(w); |