diff options
author | qwx <qwx@sciops.net> | 2022-08-18 05:33:31 +0000 |
---|---|---|
committer | qwx <qwx@sciops.net> | 2022-08-18 05:33:31 +0000 |
commit | e7d03d19100fe3180906c8ce3f2cab3ba9387fe8 (patch) | |
tree | eca8dc5f945c65ba01370a1783c927c3c0670dcb /sys/src/9/pc/devvga.c | |
parent | 218d21f3b5743ddaddb7252b7088946a62b49244 (diff) |
devvga: fix race condition between writes to vgactl
to reproduce:
for(i in `{seq 10}) echo softscreen off >/dev/vgactl
Diffstat (limited to 'sys/src/9/pc/devvga.c')
-rw-r--r-- | sys/src/9/pc/devvga.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c index 07f2c407c..f52be3291 100644 --- a/sys/src/9/pc/devvga.c +++ b/sys/src/9/pc/devvga.c @@ -280,8 +280,10 @@ vgactl(VGAscr *scr, Cmdbuf *cb) error("bad channel"); if(chantodepth(chan) != z) error("depth, channel do not match"); + qlock(&drawlock); deletescreenimage(); setscreensize(scr, r.max.x, r.max.y, z, chan, scr->tilt); + qunlock(&drawlock); return; case CMactualsize: @@ -296,6 +298,7 @@ vgactl(VGAscr *scr, Cmdbuf *cb) error(Ebadarg); if(r.max.x > scr->width || r.max.y > scr->height) error("physical screen bigger than virtual"); + qlock(&drawlock); deletescreenimage(); setactualsize(scr, r); goto Resized; @@ -324,6 +327,7 @@ vgactl(VGAscr *scr, Cmdbuf *cb) } if(scr->gscreen == nil) return; + qlock(&drawlock); r = actualscreensize(scr); chan = scr->gscreen->chan; z = scr->gscreen->depth; @@ -331,9 +335,11 @@ vgactl(VGAscr *scr, Cmdbuf *cb) setscreensize(scr, scr->width, scr->height, z, chan, tilt); setactualsize(scr, r); /* no break */ - case CMdrawinit: - if(scr->gscreen == nil) + Init: + if(scr->gscreen == nil){ + qunlock(&drawlock); error(Enoscreen); + } if(scr->dev && scr->dev->drawinit) scr->dev->drawinit(scr); hwblank = scr->blank != nil; @@ -341,8 +347,13 @@ vgactl(VGAscr *scr, Cmdbuf *cb) Resized: vgascreenwin(scr); resetscreenimage(); + qunlock(&drawlock); return; + case CMdrawinit: + qlock(&drawlock); + goto Init; + case CMlinear: if(cb->nf!=2 && cb->nf!=3) error(Ebadarg); |