Shadowing special variables in threaded handlers

Stelian Ionescu sionescu at cddr.org
Fri Dec 31 09:36:36 UTC 2021


On Fri, 2021-12-31 at 10:09 +0100, Chun Tian wrote:
> Hi,
> 
> Imagine the following simple "algorithm" (or strategy): "shadowed
> values always have priority, otherwise the current value of global
> variables are used."

That's called rebinding a special variable.

>   Problem is that, how could the lambda function know it was called
> with a shadowed value?

The whole point of special variables is to make it oblivious whether
one is using the global binding or a thread-local binding, so code
shouldn't be aware of that in general.


>  An easy way is to use another global variable which should be never
> changed by SETQ:
> 
> So consider the following modified examples:
> 
> (defvar *foo* "original value")
> (defvar *shadowed* nil)
> 
> (defun create-server (&optional (port 1965))
>   (usocket:socket-server "0.0.0.0" port
>                          (let ((foo *foo*) (shadowed *shadowed*))
>                            (lambda (stream)
>                              (let ((v (if shadowed foo *foo*)))
>                                (write v :stream stream))))
>                          ()
>                          :multi-threading t
>                          :element-type 'character
>                          :in-new-thread t))
> 

Yes, you can do something like that but it's a dubious use of special
variables and likely prone to bugs. For the stated use of allowing a
global binding during production use and injecting other values during
testing, the code I showed works fine.


> But note that, in general, if you change the value of a global
> variable from one thread, the change may not be immediately visible
> from another thread, unless you use something like locks (or atomic
> updates) from multi-threading libraries.

For interactive development, the change is practically immediate. When
they warn that writes take time to propagate to other cores, we're
talking about perhaps hundreds of usec instead of the usual <1usec, not
smething that is humanly visible.

-- 
Stelian Ionescu

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part
URL: <https://mailman.common-lisp.net/pipermail/usocket-devel/attachments/20211231/47addb39/attachment.sig>


More information about the usocket-devel mailing list