commit 19f4cef528d3a75f1cc1449cc82814d3c05a6ca5 from: rsc date: Mon Jun 26 05:48:10 2006 UTC use pin commit - df970459f9b37386fbfd4b7f3646825c8029caa8 commit + 19f4cef528d3a75f1cc1449cc82814d3c05a6ca5 blob - 8fe1b79f24a5f2b1deaab1c1699134de334d4fb8 blob + 1fb5e080dca1053954e9db874098dc4bb9bf7f74 --- src/libdraw/drawclient.c +++ src/libdraw/drawclient.c @@ -38,7 +38,12 @@ _displayconnect(Display *d) dup(p[1], 0); dup(p[1], 1); /* execl("strace", "strace", "-o", "drawsrv.out", "drawsrv", nil); */ - execl("devdraw", "devdraw", nil); + /* + * The argv0 has no meaning to devdraw. + * Pass it along only so that the various + * devdraws in psu -a can be distinguished. + */ + execl("devdraw", "devdraw", argv0, nil); sysfatal("exec devdraw: %r"); } close(p[1]); @@ -157,7 +162,28 @@ displayrpc(Display *d, Wsysmsg *tx, Wsysmsg *rx, void fprint(2, "%r\n"); return -1; } + /* + * This is the only point where we might reschedule. + * Muxrpc might need to acquire d->mux->lk, which could + * be held by some other proc (e.g., the one reading from + * the keyboard via Trdkbd messages). If we need to wait + * for the lock, don't let other threads from this proc + * run. This keeps up the appearance that writes to /dev/draw + * don't cause rescheduling. If you *do* allow rescheduling + * here, then flushimage(display, 1) happening in two different + * threads in the same proc can cause a buffer of commands + * to be written out twice, leading to interesting results + * on the screen. + * + * Threadpin and threadunpin were added to the thread library + * to solve exactly this problem. Be careful! They are dangerous. + * + * _pin and _unpin are aliases for threadpin and threadunpin + * in a threaded program and are no-ops in unthreaded programs. + */ + _pin(); rpkt = muxrpc(d->mux, tpkt); + _unpin(); free(tpkt); if(rpkt == nil){ werrstr("muxrpc: %r");