Re: thread resource leaks if thread terminates with uncaught exception

Shiro Kawai <[email protected]> Fri, 10 Jan 2025 02:26:10 -1000
Newsgroups gmane.lisp.scheme.gauche
Message-ID <CALN0JNFvyyJ=Jo3EW6Tc85fBUc2kCbAyXAHd0Ys2+0mB_Tmw=w@mail.gmail.com>
--===============3513772231521601938==
Content-Type: multipart/alternative; boundary="000000000000ce57e6062b5933fa"

--000000000000ce57e6062b5933fa
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Regarding pmap semantics in case of uncaught exception, it is not defined
at all; I guess I thought to leave the caller handle any exceptions within
proc, but that's probably a bad API.

I'll come back regarding the resource leak.

On Fri, Jan 10, 2025 at 12:56=E2=80=AFAM Jens Thiele <[email protected]> wrote=
:

> Jens Thiele <[email protected]> writes:
>
> > Jens Thiele <[email protected]> writes:
> >
> >>                 (pmap (lambda(i) (http-get-body))
> >>                       (iota 400)
> >>                       :mapper (make-fully-concurrent-mapper
> >>                                0.1 'timeout)))
> >
> > wanted to improve the pmap method (with fully-concurrent-mapper with
> > timeout):
> >
> > (define-method run-map ((mapper <fully-concurrent-mapper>) proc coll)
> >   (let ([unique (list #f)]
> >         [ts (map (^e (make-thread (^[] (proc e)))) coll)]
> >         [timeout (absolute-time (~ mapper'timeout))]
> >         [timeout-val (~ mapper'timeout-val)])
> >     (%start-threads ts)
> >     (if timeout
> >       ($ map (^r (if (and (pair? r) (eq? (car r) unique))
> >                    (begin (thread-terminate! (cdr r)) timeout-val)
> >                    r))
> >          $ map (^t (thread-join! t timeout (cons unique t))) ts)
> >       (map thread-join! ts))))
> >
> > but I am not even sure what should happen if there are multiple uncaugh=
t
> > exceptions. At the moment the first uncaught exception is raised by
> > thread-join!
>
> maybe just keep it like that
>
> but this seems not to be good enough:
>
> (with-module control.pmap
> (define-method run-map ((mapper <fully-concurrent-mapper>) proc coll)
>   (let* ([unique (list #f)]
>          [ts (map (^e (make-thread (^[] (proc e)))) coll)]
>          [cleanup-ts (lambda()
>                        (let loop ((ts ts))
>                          (unless (null? ts)
>                            (set-car! ts #f)
>                            (loop (cdr ts)))))]
>          [timeout (absolute-time (~ mapper'timeout))]
>          [timeout-val (~ mapper'timeout-val)])
>     (%start-threads ts)
>     (if timeout
>       (let1 results (guard (e [(uncaught-exception-condition? e)
>                                ;; kill still running threads
>                                (for-each thread-terminate! ts)
>                                ;; otherwise we get thread died a
>                                ;; lonely death with an uncaught
>                                ;; exception
>                                (for-each
>                                 (lambda(t)
>                                   (guard
>                                    (e [(terminated-thread-exception? e)
>                                        #t]
>                                       [else
>                                        ;; #?=3De
>                                        #t
>                                        ])
>                                    (thread-join! t)))
>                                 ts)
>                                (cleanup-ts)
>                                (raise e)])
>                            (map (lambda(t)
>                                   (thread-join! t
>                                                 timeout
>                                                 (cons unique t)))
>                                 ts))
>         (cleanup-ts)
>         (map
>          (lambda(r)
>            (if (and (pair? r) (eq? (car r) unique))
>              (begin
>                (thread-terminate! (cdr r))
>                (set-cdr! r #f)
>                timeout-val)
>              r))
>          results))
>       (map thread-join! ts))))
> )
>
> The complete reverse proxy example that still fails for me:
>
> #!/bin/sh
> #| -*- mode: scheme; coding: utf-8; -*-
> #export GC_PRINT_STATS=3D1
> exec gosh -I. -- $0 "$@"
> |#
> (use makiki)
> (use text.html-lite)
> (use rfc.http)
> (use gauche.threads)
> (use file.util)
> (use gauche.sequence)
> (use control.pmap)
>
> (with-module control.pmap
> (define-method run-map ((mapper <fully-concurrent-mapper>) proc coll)
>   (let* ([unique (list #f)]
>          [ts (map (^e (make-thread (^[] (proc e)))) coll)]
>          [cleanup-ts (lambda()
>                        (let loop ((ts ts))
>                          (unless (null? ts)
>                            (set-car! ts #f)
>                            (loop (cdr ts)))))]
>          [timeout (absolute-time (~ mapper'timeout))]
>          [timeout-val (~ mapper'timeout-val)])
>     (%start-threads ts)
>     (if timeout
>       (let1 results (guard (e [(uncaught-exception-condition? e)
>                                ;; kill still running threads
>                                (for-each thread-terminate! ts)
>                                ;; otherwise we get thread died a
>                                ;; lonely death with an uncaught
>                                ;; exception
>                                (for-each
>                                 (lambda(t)
>                                   (guard
>                                    (e [(terminated-thread-exception? e)
>                                        #t]
>                                       [else
>                                        ;; #?=3De
>                                        #t
>                                        ])
>                                    (thread-join! t)))
>                                 ts)
>                                (cleanup-ts)
>                                (raise e)])
>                            (map (lambda(t)
>                                   (thread-join! t
>                                                 timeout
>                                                 (cons unique t)))
>                                 ts))
>         (cleanup-ts)
>         (map
>          (lambda(r)
>            (if (and (pair? r) (eq? (car r) unique))
>              (begin
>                (thread-terminate! (cdr r))
>                (set-cdr! r #f)
>                timeout-val)
>              r))
>          results))
>       (map thread-join! ts))))
> )
>
> ;; todo: linux specific
> (define (num-open-files)
>   (guard (e
>           [else
>            +nan.0])
>          (length (directory-list "/proc/self/fd" :children? #t))))
>
> (define (num-threads)
>   (guard (e
>           [else
>            +nan.0])
>          (length (directory-list "/proc/self/task" :children? #t))))
>
> (define-http-handler (GET) "/" (^[req app]
>                                  (receive (status headers body)
>                                      (http-get "localhost:8081" "/")
>                                    (respond/ok req body))))
>
> (define (http-get-body)
>   (receive (status headers body)
>       ;; todo: detect host name and use it to force a real
>       ;; dns lookup to occur?
>       (http-get "localhost:8081" "/slow")
>     body))
>
> (define-http-handler (GET)
>   "/timeout"
>   (lambda(req app)
>     (let1 r (guard (e
>                     [(uncaught-exception-condition? e)
>                      #?=3D(uncaught-exception-condition-reason e)]
>                     [else #?=3De])
>                    (pmap (lambda(i) (http-get-body))
>                          (iota 400)
>                          :mapper (make-fully-concurrent-mapper
>                                   0.1 'timeout)))
>       (cond [(and (list? r) (eq? (car r) 'timeout))
>              (respond/ok req
>                          (list
>                           (html-doctype)
>                           (html:html
>                            (html:head (html:title "timeout"))
>                            (html:body
>                             (html:p "timeout")
>                             (html:p
>                              (string-append
>                               (x->string (num-open-files))
>                               " open files"))))))]
>             [(list? r)
>              (car body)]
>             [else
>              (request-error :body r)]))))
>
> (define (main args)
>   #?=3D(sys-getpid)
>   (debug-print-width 4000)
>   (start-http-server :port 8080 :error-log #t)
>   0)
>
> running out of ideas - should I just stop it?
>
> Jens
>
>
> _______________________________________________
> Gauche-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/gauche-devel
>

--000000000000ce57e6062b5933fa
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+UmVnYXJkaW5nIHBtYXAgc2VtYW50aWNzIGluIGNhc2Ugb2YgdW5jYXVn
aHQgZXhjZXB0aW9uLCBpdCBpcyBub3QgZGVmaW5lZCBhdCBhbGw7IEkgZ3Vlc3MgSSB0aG91Z2h0
IHRvIGxlYXZlIHRoZSBjYWxsZXIgaGFuZGxlIGFueSBleGNlcHRpb25zIHdpdGhpbiBwcm9jLCBi
dXQgdGhhdCYjMzk7cyBwcm9iYWJseSBhIGJhZCBBUEkuPGRpdj48YnI+PC9kaXY+PGRpdj5JJiMz
OTtsbCBjb21lIGJhY2sgcmVnYXJkaW5nIHRoZSByZXNvdXJjZcKgbGVhay7CoMKgPC9kaXY+PC9k
aXY+PGJyPjxkaXYgY2xhc3M9ImdtYWlsX3F1b3RlIGdtYWlsX3F1b3RlX2NvbnRhaW5lciI+PGRp
diBkaXI9Imx0ciIgY2xhc3M9ImdtYWlsX2F0dHIiPk9uIEZyaSwgSmFuIDEwLCAyMDI1IGF0IDEy
OjU24oCvQU0gSmVucyBUaGllbGUgJmx0OzxhIGhyZWY9Im1haWx0bzprYXJtZUBrYXJtZS5kZSI+
a2FybWVAa2FybWUuZGU8L2E+Jmd0OyB3cm90ZTo8YnI+PC9kaXY+PGJsb2NrcXVvdGUgY2xhc3M9
ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBweCAwcHggMHB4IDAuOGV4O2JvcmRlci1sZWZ0
OjFweCBzb2xpZCByZ2IoMjA0LDIwNCwyMDQpO3BhZGRpbmctbGVmdDoxZXgiPkplbnMgVGhpZWxl
ICZsdDs8YSBocmVmPSJtYWlsdG86a2FybWVAa2FybWUuZGUiIHRhcmdldD0iX2JsYW5rIj5rYXJt
ZUBrYXJtZS5kZTwvYT4mZ3Q7IHdyaXRlczo8YnI+DQo8YnI+DQomZ3Q7IEplbnMgVGhpZWxlICZs
dDs8YSBocmVmPSJtYWlsdG86a2FybWVAa2FybWUuZGUiIHRhcmdldD0iX2JsYW5rIj5rYXJtZUBr
YXJtZS5kZTwvYT4mZ3Q7IHdyaXRlczo8YnI+DQomZ3Q7PGJyPg0KJmd0OyZndDvCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoChwbWFwIChsYW1iZGEoaSkgKGh0dHAtZ2V0LWJvZHkpKTxicj4NCiZn
dDsmZ3Q7wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoaW90YSA0MDApPGJyPg0K
Jmd0OyZndDvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDptYXBwZXIgKG1ha2Ut
ZnVsbHktY29uY3VycmVudC1tYXBwZXI8YnI+DQomZ3Q7Jmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIDAuMSAmIzM5O3RpbWVvdXQpKSk8YnI+DQomZ3Q7
PGJyPg0KJmd0OyB3YW50ZWQgdG8gaW1wcm92ZSB0aGUgcG1hcCBtZXRob2QgKHdpdGggZnVsbHkt
Y29uY3VycmVudC1tYXBwZXIgd2l0aDxicj4NCiZndDsgdGltZW91dCk6PGJyPg0KJmd0Ozxicj4N
CiZndDsgKGRlZmluZS1tZXRob2QgcnVuLW1hcCAoKG1hcHBlciAmbHQ7ZnVsbHktY29uY3VycmVu
dC1tYXBwZXImZ3Q7KSBwcm9jIGNvbGwpPGJyPg0KJmd0O8KgIMKgKGxldCAoW3VuaXF1ZSAobGlz
dCAjZildPGJyPg0KJmd0O8KgIMKgIMKgIMKgIMKgW3RzIChtYXAgKF5lIChtYWtlLXRocmVhZCAo
XltdIChwcm9jIGUpKSkpIGNvbGwpXTxicj4NCiZndDvCoCDCoCDCoCDCoCDCoFt0aW1lb3V0IChh
YnNvbHV0ZS10aW1lICh+IG1hcHBlciYjMzk7dGltZW91dCkpXTxicj4NCiZndDvCoCDCoCDCoCDC
oCDCoFt0aW1lb3V0LXZhbCAofiBtYXBwZXImIzM5O3RpbWVvdXQtdmFsKV0pPGJyPg0KJmd0O8Kg
IMKgIMKgKCVzdGFydC10aHJlYWRzIHRzKTxicj4NCiZndDvCoCDCoCDCoChpZiB0aW1lb3V0PGJy
Pg0KJmd0O8KgIMKgIMKgIMKgKCQgbWFwICheciAoaWYgKGFuZCAocGFpcj8gcikgKGVxPyAoY2Fy
IHIpIHVuaXF1ZSkpPGJyPg0KJmd0O8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChiZWdp
biAodGhyZWFkLXRlcm1pbmF0ZSEgKGNkciByKSkgdGltZW91dC12YWwpPGJyPg0KJmd0O8KgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHIpKTxicj4NCiZndDvCoCDCoCDCoCDCoCDCoCAkIG1h
cCAoXnQgKHRocmVhZC1qb2luISB0IHRpbWVvdXQgKGNvbnMgdW5pcXVlIHQpKSkgdHMpPGJyPg0K
Jmd0O8KgIMKgIMKgIMKgKG1hcCB0aHJlYWQtam9pbiEgdHMpKSkpPGJyPg0KJmd0Ozxicj4NCiZn
dDsgYnV0IEkgYW0gbm90IGV2ZW4gc3VyZSB3aGF0IHNob3VsZCBoYXBwZW4gaWYgdGhlcmUgYXJl
IG11bHRpcGxlIHVuY2F1Z2h0PGJyPg0KJmd0OyBleGNlcHRpb25zLiBBdCB0aGUgbW9tZW50IHRo
ZSBmaXJzdCB1bmNhdWdodCBleGNlcHRpb24gaXMgcmFpc2VkIGJ5PGJyPg0KJmd0OyB0aHJlYWQt
am9pbiE8YnI+DQo8YnI+DQptYXliZSBqdXN0IGtlZXAgaXQgbGlrZSB0aGF0PGJyPg0KPGJyPg0K
YnV0IHRoaXMgc2VlbXMgbm90IHRvIGJlIGdvb2QgZW5vdWdoOjxicj4NCjxicj4NCih3aXRoLW1v
ZHVsZSBjb250cm9sLnBtYXA8YnI+DQooZGVmaW5lLW1ldGhvZCBydW4tbWFwICgobWFwcGVyICZs
dDtmdWxseS1jb25jdXJyZW50LW1hcHBlciZndDspIHByb2MgY29sbCk8YnI+DQrCoCAobGV0KiAo
W3VuaXF1ZSAobGlzdCAjZildPGJyPg0KwqAgwqAgwqAgwqAgwqBbdHMgKG1hcCAoXmUgKG1ha2Ut
dGhyZWFkICheW10gKHByb2MgZSkpKSkgY29sbCldPGJyPg0KwqAgwqAgwqAgwqAgwqBbY2xlYW51
cC10cyAobGFtYmRhKCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChs
ZXQgbG9vcCAoKHRzIHRzKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCh1bmxlc3MgKG51bGw/IHRzKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgKHNldC1jYXIhIHRzICNmKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgKGxvb3AgKGNkciB0cykpKSkpXTxicj4NCsKgIMKgIMKgIMKgIMKg
W3RpbWVvdXQgKGFic29sdXRlLXRpbWUgKH4gbWFwcGVyJiMzOTt0aW1lb3V0KSldPGJyPg0KwqAg
wqAgwqAgwqAgwqBbdGltZW91dC12YWwgKH4gbWFwcGVyJiMzOTt0aW1lb3V0LXZhbCldKTxicj4N
CsKgIMKgICglc3RhcnQtdGhyZWFkcyB0cyk8YnI+DQrCoCDCoCAoaWYgdGltZW91dDxicj4NCsKg
IMKgIMKgIChsZXQxIHJlc3VsdHMgKGd1YXJkIChlIFsodW5jYXVnaHQtZXhjZXB0aW9uLWNvbmRp
dGlvbj8gZSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoDs7IGtpbGwgc3RpbGwgcnVubmluZyB0aHJlYWRzPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoZm9yLWVhY2ggdGhyZWFkLXRlcm1pbmF0ZSEg
dHMpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqA7
OyBvdGhlcndpc2Ugd2UgZ2V0IHRocmVhZCBkaWVkIGE8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDs7IGxvbmVseSBkZWF0aCB3aXRoIGFuIHVuY2F1
Z2h0PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqA7
OyBleGNlcHRpb248YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoChmb3ItZWFjaDxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIChsYW1iZGEodCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoZ3VhcmQ8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChlIFsodGVybWluYXRlZC10aHJlYWQtZXhj
ZXB0aW9uPyBlKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgI3RdPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgW2Vsc2U8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDs7ICM/PWU8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCN0
PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqBdKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgKHRocmVhZC1qb2luISB0KSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdHMpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoY2xlYW51cC10cyk8YnI+DQrCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChyYWlzZSBlKV0pPGJyPg0KwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAobWFwIChsYW1iZGEodCk8YnI+DQrC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAodGhyZWFk
LWpvaW4hIHQ8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0aW1lb3V0PGJyPg0KwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
KGNvbnMgdW5pcXVlIHQpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCB0cykpPGJyPg0KwqAgwqAgwqAgwqAgKGNsZWFudXAtdHMpPGJyPg0KwqAg
wqAgwqAgwqAgKG1hcDxicj4NCsKgIMKgIMKgIMKgIMKgKGxhbWJkYShyKTxicj4NCsKgIMKgIMKg
IMKgIMKgIMKgKGlmIChhbmQgKHBhaXI/IHIpIChlcT8gKGNhciByKSB1bmlxdWUpKTxicj4NCsKg
IMKgIMKgIMKgIMKgIMKgIMKgKGJlZ2luPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAodGhy
ZWFkLXRlcm1pbmF0ZSEgKGNkciByKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChzZXQt
Y2RyISByICNmKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdGltZW91dC12YWwpPGJyPg0K
wqAgwqAgwqAgwqAgwqAgwqAgwqByKSk8YnI+DQrCoCDCoCDCoCDCoCDCoHJlc3VsdHMpKTxicj4N
CsKgIMKgIMKgIChtYXAgdGhyZWFkLWpvaW4hIHRzKSkpKTxicj4NCik8YnI+DQo8YnI+DQpUaGUg
Y29tcGxldGUgcmV2ZXJzZSBwcm94eSBleGFtcGxlIHRoYXQgc3RpbGwgZmFpbHMgZm9yIG1lOjxi
cj4NCjxicj4NCiMhL2Jpbi9zaDxicj4NCiN8IC0qLSBtb2RlOiBzY2hlbWU7IGNvZGluZzogdXRm
LTg7IC0qLTxicj4NCiNleHBvcnQgR0NfUFJJTlRfU1RBVFM9MTxicj4NCmV4ZWMgZ29zaCAtSS4g
LS0gJDAgJnF1b3Q7JEAmcXVvdDs8YnI+DQp8Izxicj4NCih1c2UgbWFraWtpKTxicj4NCih1c2Ug
dGV4dC5odG1sLWxpdGUpPGJyPg0KKHVzZSByZmMuaHR0cCk8YnI+DQoodXNlIGdhdWNoZS50aHJl
YWRzKTxicj4NCih1c2UgZmlsZS51dGlsKTxicj4NCih1c2UgZ2F1Y2hlLnNlcXVlbmNlKTxicj4N
Cih1c2UgY29udHJvbC5wbWFwKTxicj4NCjxicj4NCih3aXRoLW1vZHVsZSBjb250cm9sLnBtYXA8
YnI+DQooZGVmaW5lLW1ldGhvZCBydW4tbWFwICgobWFwcGVyICZsdDtmdWxseS1jb25jdXJyZW50
LW1hcHBlciZndDspIHByb2MgY29sbCk8YnI+DQrCoCAobGV0KiAoW3VuaXF1ZSAobGlzdCAjZild
PGJyPg0KwqAgwqAgwqAgwqAgwqBbdHMgKG1hcCAoXmUgKG1ha2UtdGhyZWFkICheW10gKHByb2Mg
ZSkpKSkgY29sbCldPGJyPg0KwqAgwqAgwqAgwqAgwqBbY2xlYW51cC10cyAobGFtYmRhKCk8YnI+
DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChsZXQgbG9vcCAoKHRzIHRzKSk8
YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCh1bmxlc3MgKG51bGw/
IHRzKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKHNldC1j
YXIhIHRzICNmKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
KGxvb3AgKGNkciB0cykpKSkpXTxicj4NCsKgIMKgIMKgIMKgIMKgW3RpbWVvdXQgKGFic29sdXRl
LXRpbWUgKH4gbWFwcGVyJiMzOTt0aW1lb3V0KSldPGJyPg0KwqAgwqAgwqAgwqAgwqBbdGltZW91
dC12YWwgKH4gbWFwcGVyJiMzOTt0aW1lb3V0LXZhbCldKTxicj4NCsKgIMKgICglc3RhcnQtdGhy
ZWFkcyB0cyk8YnI+DQrCoCDCoCAoaWYgdGltZW91dDxicj4NCsKgIMKgIMKgIChsZXQxIHJlc3Vs
dHMgKGd1YXJkIChlIFsodW5jYXVnaHQtZXhjZXB0aW9uLWNvbmRpdGlvbj8gZSk8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDs7IGtpbGwgc3RpbGwg
cnVubmluZyB0aHJlYWRzPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAoZm9yLWVhY2ggdGhyZWFkLXRlcm1pbmF0ZSEgdHMpPGJyPg0KwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqA7OyBvdGhlcndpc2Ugd2UgZ2V0
IHRocmVhZCBkaWVkIGE8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoDs7IGxvbmVseSBkZWF0aCB3aXRoIGFuIHVuY2F1Z2h0PGJyPg0KwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqA7OyBleGNlcHRpb248YnI+DQrC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChmb3ItZWFjaDxi
cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChsYW1i
ZGEodCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCAoZ3VhcmQ8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoChlIFsodGVybWluYXRlZC10aHJlYWQtZXhjZXB0aW9uPyBlKTxicj4NCsKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
I3RdPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgW2Vsc2U8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoDs7ICM/PWU8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCN0PGJyPg0KwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBdKTxicj4NCsKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKHRocmVh
ZC1qb2luISB0KSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgdHMpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAoY2xlYW51cC10cyk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoChyYWlzZSBlKV0pPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAobWFwIChsYW1iZGEodCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAodGhyZWFkLWpvaW4hIHQ8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCB0aW1lb3V0PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGNvbnMgdW5pcXVlIHQpKSk8
YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB0cykp
PGJyPg0KwqAgwqAgwqAgwqAgKGNsZWFudXAtdHMpPGJyPg0KwqAgwqAgwqAgwqAgKG1hcDxicj4N
CsKgIMKgIMKgIMKgIMKgKGxhbWJkYShyKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgKGlmIChhbmQg
KHBhaXI/IHIpIChlcT8gKGNhciByKSB1bmlxdWUpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKg
KGJlZ2luPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAodGhyZWFkLXRlcm1pbmF0ZSEgKGNk
ciByKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChzZXQtY2RyISByICNmKTxicj4NCsKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgdGltZW91dC12YWwpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg
wqByKSk8YnI+DQrCoCDCoCDCoCDCoCDCoHJlc3VsdHMpKTxicj4NCsKgIMKgIMKgIChtYXAgdGhy
ZWFkLWpvaW4hIHRzKSkpKTxicj4NCik8YnI+DQo8YnI+DQo7OyB0b2RvOiBsaW51eCBzcGVjaWZp
Yzxicj4NCihkZWZpbmUgKG51bS1vcGVuLWZpbGVzKTxicj4NCsKgIChndWFyZCAoZTxicj4NCsKg
IMKgIMKgIMKgIMKgIFtlbHNlPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqArbmFuLjBdKTxicj4NCsKg
IMKgIMKgIMKgIMKgKGxlbmd0aCAoZGlyZWN0b3J5LWxpc3QgJnF1b3Q7L3Byb2Mvc2VsZi9mZCZx
dW90OyA6Y2hpbGRyZW4/ICN0KSkpKTxicj4NCjxicj4NCihkZWZpbmUgKG51bS10aHJlYWRzKTxi
cj4NCsKgIChndWFyZCAoZTxicj4NCsKgIMKgIMKgIMKgIMKgIFtlbHNlPGJyPg0KwqAgwqAgwqAg
wqAgwqAgwqArbmFuLjBdKTxicj4NCsKgIMKgIMKgIMKgIMKgKGxlbmd0aCAoZGlyZWN0b3J5LWxp
c3QgJnF1b3Q7L3Byb2Mvc2VsZi90YXNrJnF1b3Q7IDpjaGlsZHJlbj8gI3QpKSkpPGJyPg0KPGJy
Pg0KKGRlZmluZS1odHRwLWhhbmRsZXIgKEdFVCkgJnF1b3Q7LyZxdW90OyAoXltyZXEgYXBwXTxi
cj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKHJl
Y2VpdmUgKHN0YXR1cyBoZWFkZXJzIGJvZHkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoaHR0cC1nZXQgJnF1b3Q7bG9jYWxob3N0
OjgwODEmcXVvdDsgJnF1b3Q7LyZxdW90Oyk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChyZXNwb25kL29rIHJlcSBib2R5KSkpKTxicj4N
Cjxicj4NCihkZWZpbmUgKGh0dHAtZ2V0LWJvZHkpPGJyPg0KwqAgKHJlY2VpdmUgKHN0YXR1cyBo
ZWFkZXJzIGJvZHkpPGJyPg0KwqAgwqAgwqAgOzsgdG9kbzogZGV0ZWN0IGhvc3QgbmFtZSBhbmQg
dXNlIGl0IHRvIGZvcmNlIGEgcmVhbDxicj4NCsKgIMKgIMKgIDs7IGRucyBsb29rdXAgdG8gb2Nj
dXI/PGJyPg0KwqAgwqAgwqAgKGh0dHAtZ2V0ICZxdW90O2xvY2FsaG9zdDo4MDgxJnF1b3Q7ICZx
dW90Oy9zbG93JnF1b3Q7KTxicj4NCsKgIMKgIGJvZHkpKTxicj4NCjxicj4NCihkZWZpbmUtaHR0
cC1oYW5kbGVyIChHRVQpPGJyPg0KwqAgJnF1b3Q7L3RpbWVvdXQmcXVvdDs8YnI+DQrCoCAobGFt
YmRhKHJlcSBhcHApPGJyPg0KwqAgwqAgKGxldDEgciAoZ3VhcmQgKGU8YnI+DQrCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBbKHVuY2F1Z2h0LWV4Y2VwdGlvbi1jb25kaXRpb24/IGUpPGJy
Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAjPz0odW5jYXVnaHQtZXhjZXB0aW9u
LWNvbmRpdGlvbi1yZWFzb24gZSldPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
W2Vsc2UgIz89ZV0pPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAocG1hcCAobGFt
YmRhKGkpIChodHRwLWdldC1ib2R5KSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoChpb3RhIDQwMCk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoDptYXBwZXIgKG1ha2UtZnVsbHktY29uY3VycmVudC1tYXBwZXI8YnI+DQrCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAwLjEgJiMzOTt0aW1l
b3V0KSkpPGJyPg0KwqAgwqAgwqAgKGNvbmQgWyhhbmQgKGxpc3Q/IHIpIChlcT8gKGNhciByKSAm
IzM5O3RpbWVvdXQpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgKHJlc3BvbmQvb2sgcmVxPGJy
Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAobGlzdDxicj4NCsKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChodG1sLWRvY3R5cGUpPGJyPg0KwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGh0bWw6aHRtbDxicj4NCsKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKGh0bWw6aGVhZCAoaHRtbDp0aXRs
ZSAmcXVvdDt0aW1lb3V0JnF1b3Q7KSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoChodG1sOmJvZHk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCAoaHRtbDpwICZxdW90O3RpbWVvdXQmcXVvdDspPGJyPg0KwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGh0bWw6cDxicj4NCsKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKHN0cmluZy1hcHBlbmQ8YnI+DQrCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoeC0mZ3Q7c3RyaW5nIChu
dW0tb3Blbi1maWxlcykpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgJnF1b3Q7IG9wZW4gZmlsZXMmcXVvdDspKSkpKSldPGJyPg0KwqAgwqAgwqAgwqAg
wqAgwqAgWyhsaXN0PyByKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgKGNhciBib2R5KV08YnI+
DQrCoCDCoCDCoCDCoCDCoCDCoCBbZWxzZTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgKHJlcXVl
c3QtZXJyb3IgOmJvZHkgcildKSkpKTxicj4NCjxicj4NCihkZWZpbmUgKG1haW4gYXJncyk8YnI+
DQrCoCAjPz0oc3lzLWdldHBpZCk8YnI+DQrCoCAoZGVidWctcHJpbnQtd2lkdGggNDAwMCk8YnI+
DQrCoCAoc3RhcnQtaHR0cC1zZXJ2ZXIgOnBvcnQgODA4MCA6ZXJyb3ItbG9nICN0KTxicj4NCsKg
IDApPGJyPg0KPGJyPg0KcnVubmluZyBvdXQgb2YgaWRlYXMgLSBzaG91bGQgSSBqdXN0IHN0b3Ag
aXQ/PGJyPg0KPGJyPg0KSmVuczxicj4NCjxicj4NCjxicj4NCl9fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fPGJyPg0KR2F1Y2hlLWRldmVsIG1haWxpbmcgbGlz
dDxicj4NCjxhIGhyZWY9Im1haWx0bzpHYXVjaGUtZGV2ZWxAbGlzdHMuc291cmNlZm9yZ2UubmV0
IiB0YXJnZXQ9Il9ibGFuayI+R2F1Y2hlLWRldmVsQGxpc3RzLnNvdXJjZWZvcmdlLm5ldDwvYT48
YnI+DQo8YSBocmVmPSJodHRwczovL2xpc3RzLnNvdXJjZWZvcmdlLm5ldC9saXN0cy9saXN0aW5m
by9nYXVjaGUtZGV2ZWwiIHJlbD0ibm9yZWZlcnJlciIgdGFyZ2V0PSJfYmxhbmsiPmh0dHBzOi8v
bGlzdHMuc291cmNlZm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL2dhdWNoZS1kZXZlbDwvYT48YnI+
DQo8L2Jsb2NrcXVvdGU+PC9kaXY+DQo=
--000000000000ce57e6062b5933fa--


--===============3513772231521601938==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============3513772231521601938==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Gauche-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gauche-devel

--===============3513772231521601938==--