[MLton] Multithreading issue when using FFI with C/C++

Weiqi Sun <[email protected]> Tue, 8 Mar 2022 18:56:47 -0500
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <CABxDVXDiM8b7eZCQ9+8=j1zn1Kh3-seGid-z-QUP2LAgq2RxEw@mail.gmail.com>
--===============7748551252535435074==
Content-Type: multipart/alternative; boundary="0000000000008291ee05d9bdbcc3"

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

Hi,

I have some sml code that I want to export to C or C++ using the mlton FFI
feature. However, I encountered an issue when calling the exported sml
function from C/C++ in a multithreading environment. I simplified the issue
as the following:

I export a dummy sml function called ffi_func that always returns an
integer 1 in =E2=80=9Clibtest.sml=E2=80=9D:

val f =3D _export "ffi_func": (unit -> int) -> unit;
val _ =3D f(fn () =3D> 1);

Then I compiled it to an archive named libtest.a and export a header file
test_ffi.h using the following command:

mlton -default-ann 'allowFFI true' -export-header test_ffi.h -format
archive -libname libtest libtest.sml

With the compiled archive, I can call the ffi_func function in C code
=E2=80=9Cmain.c=E2=80=9D. But when I call it inside threading, it throws a =
segmentation
fault.

#include <stdio.h>
#include <pthread.h>
#include "test_ffi.h"

void* callOut(void *thread_id) {
    int *myid =3D (int *)thread_id;
    for (int i =3D 0; i < 100; ++i) {
        int rc =3D ffi_func();
        printf("call out: %d - %d - %d\n", *myid, i, rc);
    }
    return NULL;
}

void multiRun(int n) {
    printf("num thread: %d\n", n);

    pthread_t thread[n];
    int thread_num[n];
    for (int i =3D 0; i < n; ++i) {
        thread_num[i] =3D i;
        pthread_create(&thread[i], NULL, callOut, (void *)&thread_num[i]);
    }

    for (int i =3D 0; i < n; ++i) {
        pthread_join(thread[i], NULL);
    }
}

int main(int argc, const char** argv) {
    libtest_open(argc, argv);

    int n =3D *argv[1] - '0';
    multiRun(n);

    libtest_close();
}

The code is compiled by:

gcc -o test_c main.c -L. -ltest -lpthread

If I run test_c with only one thread, it works well. But if I use more than
one thread, I got segmentation fault. And different runs give different
error messages. For example, by running ./test_c 3 multiple times, I could
get the following error messages

unhandled exception: Option
MLton bug: Mlton.Exit.halt
Please send a bug report to [email protected]
Thread.atomicSwitch didn't set r.

zsh: segmentation fault ./test_c 3

Or

unhandled exception: Fail8
Thread.atomicSwitch didn't set r.
MLton bug: MLton.Exit.halt
Please send a bug report to [email protected].

zsh: bus error ./test_c 3

I tested this with both MLton 20201002 and MLton 20210117 and they give the
same errors. And this problem appears on both Mac and Linux.

Any advice will be appreciated.

Thanks,
Weiqi

--=20
You received this message because you are subscribed to the Google Groups "=
MLton" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to [email protected].

--0000000000008291ee05d9bdbcc3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"markdown-here-wrapper" style=3D""><p style=
=3D"margin:0px 0px 1.2em!important">Hi,</p><p style=3D"margin:0px 0px 1.2em=
!important">I have some sml code that I want to export to C or C++ using th=
e mlton FFI feature. However, I encountered an issue when calling the expor=
ted sml function from C/C++ in a multithreading environment. I simplified t=
he issue as the following:</p>
<p style=3D"margin:0px 0px 1.2em!important">I export a dummy sml function c=
alled <code style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Cour=
ier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;bord=
er:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radi=
us:3px;display:inline">ffi_func</code> that always returns an integer <code=
 style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospa=
ce;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px soli=
d rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;disp=
lay:inline">1</code> in =E2=80=9Clibtest.sml=E2=80=9D:</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">val f =3D _export &quot;f=
fi_func&quot;: (unit -&gt; int) -&gt; unit;
val _ =3D f(fn () =3D&gt; 1);
</code></pre><p style=3D"margin:0px 0px 1.2em!important">Then I compiled it=
 to an archive named <code style=3D"font-size:0.85em;font-family:Consolas,I=
nconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-spac=
e:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,2=
48);border-radius:3px;display:inline">libtest.a</code> and export a header =
file <code style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Couri=
er,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;borde=
r:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radiu=
s:3px;display:inline">test_ffi.h</code> using the following command:</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">mlton -default-ann &#39;a=
llowFFI true&#39; -export-header test_ffi.h -format archive -libname libtes=
t libtest.sml
</code></pre><p style=3D"margin:0px 0px 1.2em!important">With the compiled =
archive, I can call the <code style=3D"font-size:0.85em;font-family:Consola=
s,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-s=
pace:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,24=
8,248);border-radius:3px;display:inline">ffi_func</code> function in C code=
 =E2=80=9Cmain.c=E2=80=9D. But when I call it inside threading, it throws a=
 segmentation fault.</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;
#include &quot;test_ffi.h&quot;

void* callOut(void *thread_id) {
    int *myid =3D (int *)thread_id;
    for (int i =3D 0; i &lt; 100; ++i) {
        int rc =3D ffi_func();
        printf(&quot;call out: %d - %d - %d\n&quot;, *myid, i, rc);
    }
    return NULL;
}

void multiRun(int n) {
    printf(&quot;num thread: %d\n&quot;, n);

    pthread_t thread[n];
    int thread_num[n];
    for (int i =3D 0; i &lt; n; ++i) {
        thread_num[i] =3D i;
        pthread_create(&amp;thread[i], NULL, callOut, (void *)&amp;thread_n=
um[i]);
    }

    for (int i =3D 0; i &lt; n; ++i) {
        pthread_join(thread[i], NULL);
    }
}

int main(int argc, const char** argv) {
    libtest_open(argc, argv);

    int n =3D *argv[1] - &#39;0&#39;;
    multiRun(n);

    libtest_close();
}
</code></pre><p style=3D"margin:0px 0px 1.2em!important">The code is compil=
ed by:</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">gcc -o test_c main.c -L. =
-ltest -lpthread
</code></pre><p style=3D"margin:0px 0px 1.2em!important">If I run <code sty=
le=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;m=
argin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rg=
b(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:=
inline">test_c</code> with only one thread, it works well. But if I use mor=
e than one thread, I got segmentation fault. And different runs give differ=
ent error messages. For example, by running <code style=3D"font-size:0.85em=
;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;paddi=
ng:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);backgro=
und-color:rgb(248,248,248);border-radius:3px;display:inline">./test_c 3</co=
de> multiple times, I could get the following error messages</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">unhandled exception: Opti=
on
MLton bug: Mlton.Exit.halt
Please send a bug report to <a href=3D"mailto:[email protected]">MLton@mlton.=
org</a>
Thread.atomicSwitch didn&#39;t set r.

zsh: segmentation fault ./test_c 3
</code></pre><p style=3D"margin:0px 0px 1.2em!important">Or</p>
<pre style=3D"font-size:0.85em;font-family:Consolas,Inconsolata,Courier,mon=
ospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style=3D"fon=
t-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px=
 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234=
,234);background-color:rgb(248,248,248);border-radius:3px;display:inline;wh=
ite-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,=
204);padding:0.5em 0.7em;display:block!important">unhandled exception: Fail=
8
Thread.atomicSwitch didn&#39;t set r.
MLton bug: MLton.Exit.halt
Please send a bug report to <a href=3D"mailto:[email protected]">MLton@mlton.=
org</a>.

zsh: bus error ./test_c 3
</code></pre><p style=3D"margin:0px 0px 1.2em!important">I tested this with=
 both MLton 20201002 and MLton 20210117 and they give the same errors. And =
this problem appears on both Mac and Linux.</p>
<p style=3D"margin:0px 0px 1.2em!important">Any advice will be appreciated.=
</p>
<p style=3D"margin:0px 0px 1.2em!important">Thanks,<br>Weiqi</p>
<div title=3D"MDH:PGRpdiBpZD0iZ21haWwtOjE5aiIgY2xhc3M9ImdtYWlsLUFyIGdtYWlsL=
UF1IGdtYWlsLUFvIj48
ZGl2IGlkPSJnbWFpbC06MTlmIiBjbGFzcz0iZ21haWwtQW0gZ21haWwtQWwgZWRpdGFibGUgZ21=
h
aWwtTFctYXZmIGdtYWlsLXRTLXRXIGdtYWlsLXRTLXRZIiBhcmlhLWxhYmVsPSJNZXNzYWdlIEJ=
v
ZHkiIHJvbGU9InRleHRib3giIGFyaWEtbXVsdGlsaW5lPSJ0cnVlIiB0YWJpbmRleD0iMSIgc3R=
5
bGU9ImRpcmVjdGlvbjogbHRyOyBtaW4taGVpZ2h0OiAzMzZweDsiPjxkaXYgaWQ9ImdtYWlsLTp=
4
cCIgY2xhc3M9ImdtYWlsLUFyIGdtYWlsLUF1IGdtYWlsLUFvIj48ZGl2IGlkPSJnbWFpbC06eHQ=
i
IGNsYXNzPSJnbWFpbC1BbSBnbWFpbC1BbCBlZGl0YWJsZSBnbWFpbC1MVy1hdmYgZ21haWwtdFM=
t
dFcgZ21haWwtdFMtdFkiIGFyaWEtbGFiZWw9Ik1lc3NhZ2UgQm9keSIgYXJpYS1tdWx0aWxpbmU=
9
InRydWUiIHRhYmluZGV4PSIxIiBzdHlsZT0iZGlyZWN0aW9uOiBsdHI7IG1pbi1oZWlnaHQ6IDM=
z
NnB4OyI+SGksPGRpdj48YnI+PC9kaXY+PGRpdj5JIGhhdmUgc29tZSA8c3BhbiB6ZXVtNGMxND0=
i
UFJfMV8wIiBkYXRhLWRkbndhYj0iUFJfMV8wIiBhcmlhLWludmFsaWQ9ImdyYW1tYXIiIGNsYXN=
z
PSJMbSBuZyI+c21sPC9zcGFuPiBjb2RlIHRoYXQgSSB3YW50IHRvIGV4cG9ydCB0byBDIG9yIEM=
r
KyB1c2luZyB0aGUgbWx0b24gRkZJIGZlYXR1cmUuIEhvd2V2ZXIsIEkgZW5jb3VudGVyZWQmbmJ=
z
cDthbiBpc3N1ZSB3aGVuIGNhbGxpbmcgdGhlIGV4cG9ydGVkIHNtbCBmdW5jdGlvbiBmcm9tIEM=
v
QysrIDxzcGFuIHpldW00YzE0PSJQUl8yXzAiIGRhdGEtZGRud2FiPSJQUl8yXzAiIGFyaWEtaW5=
2
YWxpZD0iZ3JhbW1hciIgY2xhc3M9IkxtIG5nIj5pbiBtdWx0aXRocmVhZGluZzwvc3Bhbj4gZW5=
2
aXJvbm1lbnQuIEkgc2ltcGxpZmllZCZuYnNwO3RoZSBpc3N1ZSBhcyB0aGUgZm9sbG93aW5nOjw=
v
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SSBleHBvcnQgYSBkdW1teSBzbWwgZnVuY3Rpb24gY2F=
s
bGVkIGBmZmlfZnVuY2AgdGhhdCBhbHdheSByZXR1cm4gYW4gaW50ZWdlciBgMWAgaW4gImxpYnR=
l
c3Quc21sIjo8L2Rpdj48ZGl2PmBgYDwvZGl2PjxkaXY+dmFsIGYgPSBfZXhwb3J0ICJmZmlfZnV=
u
YyI6ICh1bml0IC0mZ3Q7IGludCkgLSZndDsgdW5pdDs8L2Rpdj48ZGl2PnZhbCBfID0gZihmbiA=
o
KSA9Jmd0OyAxKTs8L2Rpdj48ZGl2PmBgYDwvZGl2PjxkaXY+VGhlbiBJIGNvbXBpbGVkIGl0IHR=
v
IGFuIGFyY2hpdmUgbmFtZWQgYGxpYnRlc3QuYWAgYW5kIGV4cG9ydCBhIGhlYWRlciBmaWxlIGB=
0
ZXN0X2ZmaS5oYCB1c2luZyB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6PC9kaXY+PGRpdj5gYGA8L2R=
p
dj48ZGl2Pm1sdG9uIC1kZWZhdWx0LWFubiAnYWxsb3dGRkkgdHJ1ZScgLWV4cG9ydC1oZWFkZXI=
g
dGVzdF9mZmkuaCAtZm9ybWF0IGFyY2hpdmUgLWxpYm5hbWUgbGlidGVzdCBsaWJ0ZXN0LnNtbDw=
v
ZGl2PjxkaXY+YGBgPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5XaXRoIHRoZSBjb21waWxlZCB=
h
cmNoaXZlLCBJIGNhbiBjYWxsIHRoZSBgZmZpX2Z1bmNgIGZ1bmN0aW9uIGluIEMgY29kZSAibWF=
p
bi5jIi4gQnV0IHdoZW4gSSA8c3BhbiB6ZXVtNGMxND0iUFJfMzJfMCIgZGF0YS1kZG53YWI9IlB=
S
XzMyXzAiIGFyaWEtaW52YWxpZD0iZ3JhbW1hciIgY2xhc3M9IkxtIG5nIj5jYWxsaW5nPC9zcGF=
u
PiBpdCBpbnNpZGUgdGhyZWFkaW5nLCBpdCA8c3BhbiB6ZXVtNGMxND0iUFJfMzNfMCIgZGF0YS1=
k
ZG53YWI9IlBSXzMzXzAiIGFyaWEtaW52YWxpZD0iZ3JhbW1hciIgY2xhc3M9IkxtIG5nIj50aHJ=
v
d3Mgc2VnbWVudGF0aW9uPC9zcGFuPiBmYXVsdC48L2Rpdj48ZGl2PmBgYDwvZGl2PjxkaXY+I2l=
u
Y2x1ZGUgJmx0O3N0ZGlvLmgmZ3Q7PC9kaXY+PGRpdj4jaW5jbHVkZSAmbHQ7cHRocmVhZC5oJmd=
0
OzwvZGl2PjxkaXY+I2luY2x1ZGUgInRlc3RfZmZpLmgiPC9kaXY+PGRpdj48YnI+PC9kaXY+PGR=
p
dj52b2lkKiBjYWxsT3V0KHZvaWQgKnRocmVhZF9pZCkgezwvZGl2PjxkaXY+Jm5ic3A7ICZuYnN=
w
OyBpbnQgKm15aWQgPSAoaW50ICopdGhyZWFkX2lkOzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyB=
m
b3IgKGludCBpID0gMDsgaSAmbHQ7IDEwMDsmbmJzcDsrK2kpIHs8L2Rpdj48ZGl2PiZuYnNwOyA=
m
bmJzcDsgJm5ic3A7ICZuYnNwOyBpbnQgcmMgPSBmZmlfZnVuYygpOzwvZGl2PjxkaXY+Jm5ic3A=
7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHByaW50ZigiY2FsbCBvdXQ6ICVkIC0gJWQgLSAlZFxuIiw=
g
Km15aWQsIGksIHJjKTs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgfTwvZGl2PjxkaXY+Jm5ic3A=
7
ICZuYnNwOyByZXR1cm4gTlVMTDs8L2Rpdj48ZGl2Pn08L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl=
2
PnZvaWQgbXVsdGlSdW4oaW50IG4pIHs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgcHJpbnRmKCJ=
u
dW0gdGhyZWFkOiAlZFxuIiwgbik7PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4mbmJzcDsgJm5=
i
c3A7IHB0aHJlYWRfdCB0aHJlYWRbbl07PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGludCB0aHJ=
l
YWRfbnVtW25dOzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBmb3IgKGludCBpID0gMDsgaSAmbHQ=
7
IG47Jm5ic3A7KytpKSB7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgdGh=
y
ZWFkX251bVtpXSA9IGk7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgcHR=
o
cmVhZF9jcmVhdGUoPHNwYW4gemV1bTRjMTQ9IlBSXzVfMCIgZGF0YS1kZG53YWI9IlBSXzVfMCI=
g
YXJpYS1pbnZhbGlkPSJzcGVsbGluZyIgY2xhc3M9IkxJIG5nIj4mYW1wO3RocmVhZDwvc3Bhbj5=
b
aV0sIE5VTEwsIGNhbGxPdXQsICh2b2lkICopJmFtcDt0aHJlYWRfbnVtW2ldKTs8L2Rpdj48ZGl=
2
PiZuYnNwOyAmbmJzcDsgfTwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyB=
m
b3IgKGludCBpID0gMDsgaSAmbHQ7IG47Jm5ic3A7KytpKSB7PC9kaXY+PGRpdj4mbmJzcDsgJm5=
i
c3A7ICZuYnNwOyAmbmJzcDsgcHRocmVhZF9qb2luKHRocmVhZFtpXSwgTlVMTCk7PC9kaXY+PGR=
p
dj4mbmJzcDsgJm5ic3A7IH08L2Rpdj48ZGl2Pn08L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2Pml=
u
dCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyKiogYXJndikgezwvZGl2PjxkaXY+Jm5ic3A7ICZ=
u
YnNwOyBsaWJ0ZXN0X29wZW4oYXJnYywgYXJndik7PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4=
m
bmJzcDsgJm5ic3A7IGludCBuID0gKmFyZ3ZbMV0gLSAnMCc7PC9kaXY+PGRpdj4mbmJzcDsgJm5=
i
c3A7IG11bHRpUnVuKG4pOzwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyB=
s
aWJ0ZXN0X2Nsb3NlKCk7PC9kaXY+PGRpdj59PC9kaXY+PGRpdj5gYGA8L2Rpdj48ZGl2Pjxicj4=
8
L2Rpdj48ZGl2PlRoZSBjb2RlIGlzIGNvbXBpbGVkIGJ5Ojxicj5gYGA8L2Rpdj48ZGl2PmdjYyA=
t
byB0ZXN0X2MgbWFpbi5jIC1MLiAtPHNwYW4gemV1bTRjMTQ9IlBSXzZfMCIgZGF0YS1kZG53YWI=
9
IlBSXzZfMCIgYXJpYS1pbnZhbGlkPSJzcGVsbGluZyIgY2xhc3M9IkxJIG5nIj5sdGVzdDwvc3B=
h
bj4mbmJzcDstbHB0aHJlYWQ8L2Rpdj48ZGl2PmBgYDwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY=
+
SWYgSSBydW4gYHRlc3RfY2Agd2l0aCBvbmx5IG9uZSB0aHJlYWQsIGl0IHdvcmtzIHdlbGwuIEJ=
1
dCBpZiBJIHVzZSBtb3JlIHRoYW4gb25lIHRocmVhZCwgSSA8c3BhbiB6ZXVtNGMxND0iUFJfN18=
w
IiBkYXRhLWRkbndhYj0iUFJfN18wIiBhcmlhLWludmFsaWQ9ImdyYW1tYXIiIGNsYXNzPSJMbSB=
u
ZyI+Z290PC9zcGFuPiBzZWdtZW50YXRpb24gZmF1bHQuIEFuZCBkaWZmZXJlbnQgcnVucyBnaXZ=
l
IGRpZmZlcmVudCBlcnJvciBtZXNzYWdlcy4gRm9yIGV4YW1wbGUsIGJ5IHJ1bm5pbmcgYC4vdGV=
z
dF9jIDNgIG11bHRpcGxlIHRpbWVzLCBJIGNvdWxkIGdldCB0aGUgZm9sbG93aW5nIGVycm9yIG1=
l
c3NhZ2VzPC9kaXY+PGRpdj5gYGA8L2Rpdj48ZGl2PnVuaGFuZGxlZCBleGNlcHRpb246IE9wdGl=
v
bjwvZGl2PjxkaXY+TUx0b24gYnVnOiA8c3BhbiB6ZXVtNGMxND0iUFJfOF8wIiBkYXRhLWRkbnd=
h
Yj0iUFJfOF8wIiBhcmlhLWludmFsaWQ9InNwZWxsaW5nIiBjbGFzcz0iTEkgbmciPk1sdG9uLkV=
4
aXQuaGFsdDwvc3Bhbj48L2Rpdj48ZGl2PlBsZWFzZSBzZW5kIGEgYnVnIHJlcG9ydCB0byBNTHR=
v
bkBtbHRvbi5vcmc8L2Rpdj48ZGl2PlRocmVhZC5hdG9taWNTd2l0Y2ggZGlkbid0IHNldCByLjw=
v
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+enNoOiBzZWdtZW50YXRpb24gZmF1bHQgLi90ZXN0X2M=
g
MzwvZGl2PjxkaXY+YGBgPC9kaXY+PGRpdj5PcjwvZGl2PjxkaXY+YGBgPC9kaXY+PGRpdj51bmh=
h
bmRsZWQgZXhjZXB0aW9uOiBGYWlsODwvZGl2PjxkaXY+VGhyZWFkLmF0b21pY1N3aXRjaCBkaWR=
u
J3Qgc2V0IHIuPC9kaXY+PGRpdj5NTHRvbiBidWc6IE1MdG9uLkV4aXQuaGFsdDwvZGl2PjxkaXY=
+
UGxlYXNlIHNlbmQgYSBidWcgcmVwb3J0IHRvIE1MdG9uQG1sdG9uLm9yZy48L2Rpdj48ZGl2Pjx=
i
cj48L2Rpdj48ZGl2PnpzaDogYnVzIGVycm9yIC4vdGVzdF9jIDM8L2Rpdj48ZGl2PmBgYDwvZGl=
2
PjxkaXY+PGJyPjwvZGl2PjxkaXY+SSB0ZXN0ZWQgdGhpcyB3aXRoIGJvdGggTUx0b24mbmJzcDs=
y
MDIwMTAwMiBhbmQgTUx0b24gMjAyMTAxMTcgYW5kIHRoZXkgZ2l2ZSB0aGUgc2FtZSBlcnJvcnM=
u
IEFuZCB0aGlzIHByb2JsZW0gYXBwZWFycyBvbiBib3RoIE1hYyBhbmQgTGludXguPC9kaXY+PGR=
p
dj48YnI+PC9kaXY+PGRpdj5BbnkgYWR2aWNlIHdpbGwgYmUgYXBwcmVjaWF0ZWQuPC9kaXY+PGR=
p
dj48YnI+PC9kaXY+PGRpdj5UaGFua3MsPC9kaXY+PGRpdj5XZWlxaTwvZGl2PjwvZGl2PjwvZGl=
2
PjwvZGl2PjwvZGl2Pg=3D=3D" style=3D"height:0;width:0;max-height:0;max-width:=
0;overflow:hidden;font-size:0em;padding:0;margin:0"></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;MLton&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">mlton+unsubscribe@ml=
ton.org</a>.<br />

--0000000000008291ee05d9bdbcc3--


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


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

_______________________________________________
MLton-devel mailing list
[email protected]; [email protected]
https://lists.sourceforge.net/lists/listinfo/mlton-devel

--===============7748551252535435074==--