[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re:Unable to make threads from scm_c_primitive_load'ed files/Previously
From: |
Remco Bras |
Subject: |
Re:Unable to make threads from scm_c_primitive_load'ed files/Previously scm_c_define_gsubr-defined values unbound in new threads |
Date: |
Mon, 10 Mar 2008 15:12:19 +0100 |
User-agent: |
KMail/1.9.6 (enterprise 0.20070907.709405) |
Hi Neil,
thanks for your reply.
>> Hello,
>>
>> I have run into a double problem with guile, that has to do with threads.
>The
>> situation is roughly as follows. First, scm_init_guile is called from one
>> thread, after which scm_c_define_gsubr is used in that thread and
>> scm_c_primitive_load is called to load several files. The first problem I
>> have encountered is that make-thread is unbound when evaluating the code in
>> the files I load, making it impossible to make threads this way.
>
>That might be resolved by adding (use-modules (ice-9 threads)) to the
>start of the code that calls make-thread. Can you try that?
Indeed, that fixes that problem. Apparently, this module is not mentioned in
the manual. Interestingly, a REPL created by scm_shell can evaluate
(make-thread load "keys.scm") just fine, in case you want to look into that.
>> Other ways
>> to spawn threads fail as well. For example, (call-with-new-thread (lambda
()
>> (load "keys.scm"))) fails with a SIGSEGV. The attachment backtrace.txt
>> contains a backtrace of this particular failure.
>
>Note that the backtrace is describing a Scheme-level error, not a
>SIGSEGV. Are you saying that there was a SIGSEGV as well?
>
>Anyway, the backtrace implies, I think, that the current-load-port had
>previously been set to stdin, and that stdin has been closed. Would
>that make sense in your program?
Ah yes, sorry about that, I got a SIGSEGV, but when trying to track that down
with gdb, I got the scheme level error. At other times, it all worked just
fine.
Based on your idea of stdin being closed, I seem to have managed to track down
the problem. What was happening was that I called scm_c_primitive_load on a
file that ended in (make-thread load "keys.scm"), followed by a similar
construct for "mob_event_test.scm". Apparently, it constructed the thread,
after which it finished loading the file that did so. In finishing that, it
changed the current-load-port (probably by closing it), causing the next
load, when called from the new thread, to fail.
To fix that, I've added a primitive from the C side, called scm_c_safe_load.
Basically, it looks up the value of the Scheme-level binding "load-mutex",
locks the mutex, calls scm_c_primitive_load and unlocks the mutex. The mutex
is recursive, hopefully allowing for nested safe_loads. This has a problem
when loading things that run forever, which get by by unlocking the mutex
manually. I've exposed this primitive to GUILE under the name of safe-load.
Testing with (make-thread safe-load "keys.scm") followed by (make-thread
safe-load "mob_event_test.scm") seems to have worked. Thanks for your
suggestion.
>> Since I had to be able to load files in new threads rather than the
current,
>> I
>> tried doing so with a C function, exposed to Scheme with
scm_c_define_gsubr.
>> The function, in case that is important, is included in the attached file
>> guile.c. Doing things this way succeeds in creating threads, but once it
>> attempts to evaluate any code in the file, it fails because the procedures
I
>> previously defined with scm_c_define_gsubr() are unbound.
>
>Are you able to post (a link to) your complete program? I'm not sure
>I'm understanding everything from your description here.
I can, but I'll apologize in advance for the fact that it's an unreleased GNU
package, so its code is still in Git only. You can examine it using gitweb at
savannah, at http://git.sv.gnu.org/gitweb/?p=rpge.git .
I've already committed the (ugly) workaround I described above, so the
original attempt to do things by loading scripts in separate threads made in
C is not in Git anymore. Therefore, I've written a short sample program using
pthreads and libguile so you can look into that issue. The sample C program
is in test.c (attached), which loads bar.scm (attached) in the working
directory. The test program does not exit normally so GUILE has time to print
the results of bar.scm. foo is unbound in the thread executing bar.scm.
Thanks,
Remco.
bar.scm
Description: Text document
test.c
Description: Text Data