diff options
author | Russ Cox <rsc@swtch.com> | 2020-01-10 00:11:55 -0500 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2020-01-13 16:46:14 -0500 |
commit | 41547af3f614061dd2c94bb52ae118f146925743 (patch) | |
tree | 06fe3d4c73e95a496e54882afe63006cffaa7a2d /src/cmd/devdraw/devdraw.h | |
parent | b1a086dee9bf5846b31323ba2c438f8853a9c87f (diff) | |
download | plan9port-41547af3f614061dd2c94bb52ae118f146925743.tar.gz plan9port-41547af3f614061dd2c94bb52ae118f146925743.tar.bz2 plan9port-41547af3f614061dd2c94bb52ae118f146925743.zip |
devdraw: more cleanup, clearer locking
Diffstat (limited to 'src/cmd/devdraw/devdraw.h')
-rw-r--r-- | src/cmd/devdraw/devdraw.h | 91 |
1 files changed, 63 insertions, 28 deletions
diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h index 30586228..dd7fc8ba 100644 --- a/src/cmd/devdraw/devdraw.h +++ b/src/cmd/devdraw/devdraw.h @@ -7,7 +7,6 @@ typedef struct Mousebuf Mousebuf; typedef struct Tagbuf Tagbuf; typedef struct Client Client; -typedef struct Draw Draw; typedef struct DImage DImage; typedef struct DScreen DScreen; typedef struct CScreen CScreen; @@ -16,11 +15,6 @@ typedef struct Refresh Refresh; typedef struct Refx Refx; typedef struct DName DName; -struct Draw -{ - QLock lk; -}; - struct Kbdbuf { Rune r[256]; @@ -51,6 +45,19 @@ struct Tagbuf struct Client { + int rfd; + + // wfdlk protects writes to wfd, which can be issued from either + // the RPC thread or the graphics thread. + QLock wfdlk; + int wfd; + uchar* mbuf; + int nmbuf; + + // drawlk protects the draw data structures. + // It can be acquired by an RPC thread or a graphics thread + // but must not be held on one thread while waiting for the other. + QLock drawlk; /*Ref r;*/ DImage* dimage[NHASH]; CScreen* cscreen; @@ -64,7 +71,6 @@ struct Client int refreshme; int infoid; int op; - int displaydpi; int forcedpi; int waste; @@ -75,11 +81,11 @@ struct Client DName* name; int namevers; - int rfd; - int wfd; + // Only accessed/modified by the graphics thread. const void* view; - QLock inputlk; + // eventlk protects the keyboard and mouse events. + QLock eventlk; Kbdbuf kbd; Mousebuf mouse; Tagbuf kbdtags; @@ -157,30 +163,59 @@ struct DScreen DScreen* next; }; -int _drawmsgread(Client*, void*, int); -int _drawmsgwrite(Client*, void*, int); -void _initdisplaymemimage(Client*, Memimage*); -void _drawreplacescreenimage(Client*, Memimage*); - -int _latin1(Rune*, int); -int parsewinsize(char*, Rectangle*, int*); -int mouseswap(int); - +// For the most part, the graphics driver-specific code in files +// like mac-screen.m runs in the graphics library's main thread, +// while the RPC service code in srv.c runs on the RPC service thread. +// The exceptions in each file, which are called by the other, +// are marked with special prefixes: gfx_* indicates code that +// is in srv.c but nonetheless runs on the main graphics thread, +// while rpc_* indicates code that is in, say, mac-screen.m but +// nonetheless runs on the RPC service thread. +// +// The gfx_* and rpc_* calls typically synchronize with the other +// code in the file by acquiring a lock (or running a callback on the +// target thread, which amounts to the same thing). +// To avoid deadlock, callers of those routines must not hold any locks. + +// gfx_* routines are called on the graphics thread, +// invoked from graphics driver callbacks to do RPC work. +// No locks are held on entry. void gfx_abortcompose(Client*); void gfx_keystroke(Client*, int); +void gfx_main(void); void gfx_mousetrack(Client*, int, int, int, uint); +void gfx_replacescreenimage(Client*, Memimage*); +void gfx_started(void); -void rpc_setmouse(Client*, Point); -void rpc_setcursor(Client*, Cursor*, Cursor2*); -void rpc_setlabel(Client*, char*); +// rpc_* routines are called on the RPC thread, +// invoked by the RPC server code to do graphics work. +// No locks are held on entry. +Memimage *rpc_attach(Client*, char*, char*); +char* rpc_getsnarf(void); +void rpc_putsnarf(char*); void rpc_resizeimg(Client*); void rpc_resizewindow(Client*, Rectangle); +void rpc_serve(Client*); +void rpc_setcursor(Client*, Cursor*, Cursor2*); +void rpc_setlabel(Client*, char*); +void rpc_setmouse(Client*, Point); +void rpc_shutdown(void); void rpc_topwin(Client*); -char* rpc_getsnarf(void); -void rpc_putsnarf(char*); -Memimage *rpc_attachscreen(Client*, char*, char*); -void rpc_flushmemscreen(Client*, Rectangle); +void rpc_main(void); + +// TODO: rpc_flush is called from draw_datawrite, +// which holds c->drawlk. Is this OK? +void rpc_flush(Client*, Rectangle); -extern Client *client0; +// draw* routines are called on the RPC thread, +// invoked by the RPC server to do pixel pushing. +// c->drawlk is held on entry. +int draw_dataread(Client*, void*, int); +int draw_datawrite(Client*, void*, int); +void draw_initdisplaymemimage(Client*, Memimage*); + +// utility routines +int latin1(Rune*, int); +int mouseswap(int); +int parsewinsize(char*, Rectangle*, int*); -void servep9p(Client*); |