At Tue, 1 Oct 2019 23:52:05 -0400, David Storrs wrote:
> ; main dispatcher loop in the server.  Receives messages, dispatches
> to child thread for processing
>  (struct file-info (hash) #:transparent)
>  (define channels (make-weak-hash))
>  (let loop ()
>     (define msg (get-next-message)) ; e.g. (file-info "sha1-hash-of-file-X")
>     (hash-set! channels (file-info-hash msg) ch)
>     (thread (thunk (process-file msg ch)))))
>     (loop))
> 
> 1) Am I correct that this does not work? The string that came out of
> file-info-hash is not eq? to the one stored inside msg, meaning that
> it's not referenced from anywhere else, so it's going to disappear the
> moment it goes into the weak hash.

Right.

> 2) The following also would not work:
> (let loop ()
>     (define msg (get-next-message))
>     (define the-str (file-info-hash msg))  ;; save the value out before using 
> it
>     (hash-set! channels the-str ch)
>     (thread (thunk (process-file msg ch)))))
>     (loop))
> 
> The (loop) is in tail position, so this is not a recursive call.  That
> means the stack frame is cleared, so 'the-str' is not reachable and
> it's cleared from the weak hash.

Also right.

This variant would retain the hash string until `process-file`
completes:

     (define the-str (file-info-hash msg))
     (hash-set! channels (file-info-hash msg) ch)
     (thread (thunk (process-file msg ch)
                    (hash-remove! channels the-str)))

In this case, it's handy that `hash-remove!` is a sensible use of
`the-str`, and that use's effect means `the-str` really must be
retained.

In cases where there's no sensible way to use a value like that, as a
last resort `void/reference-sink` from `ffi/unsafe` can ensure that a
value remains reachable.

> 2) This WOULD work:
> (let loop ()
>     (define msg (get-next-message)) ; e.g. (file-info "sha1-hash-of-file-X")
>     (hash-set! channels msg ch)
>     (thread (thunk (process-file msg ch)))))
>     (loop))
> 
> In this case, 'msg' is still reachable from the processing thread, so
> it remains in the weak hash until the processing thread terminates, at
> which point it is removed from the weak hash and the corresponding
> channel is GC'd.

It depends on `process-file`. If `process-file` retains `msg` until it
is otherwise done, then yes. But if `process-file` ignores the argument
for `msg` or only uses it for the first part of its work, then `msg`
can get GCed before `process-file` returns.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/5d949b2c.1c69fb81.39696.051cSMTPIN_ADDED_MISSING%40gmr-mx.google.com.

Reply via email to