summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/devvga.c
diff options
context:
space:
mode:
authorqwx <qwx@sciops.net>2022-08-18 05:33:31 +0000
committerqwx <qwx@sciops.net>2022-08-18 05:33:31 +0000
commite7d03d19100fe3180906c8ce3f2cab3ba9387fe8 (patch)
treeeca8dc5f945c65ba01370a1783c927c3c0670dcb /sys/src/9/pc/devvga.c
parent218d21f3b5743ddaddb7252b7088946a62b49244 (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.c15
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);