[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Trouble joining with threads from C
From: |
Mark H Weaver |
Subject: |
Re: Trouble joining with threads from C |
Date: |
Wed, 09 Mar 2011 01:48:52 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) |
Having further investigated, I'm convinced that this is a bug.
Attached are two minimal C programs. Both create threads that do
nothing but sleep for 2 seconds and then exit. The parent tries to join
with the child thread, with a timeout of 10 seconds.
The only difference is that test1 uses scm_spawn_thread, and test2 uses
scm_call_with_new_thread. test1 always times out, and test2 works
properly.
Having looked at the code in threads.c, I'm surprised that either of
them work. Both scm_spawn_thread and scm_call_with_new_thread arrange
for pthread_detach to be called in the child (in spawn_thread and
launch_thread, respectively). This is supposed to make the child
un-joinable.
I've attached not only test1.c and test2.c, but also the diff
between them. I compiled them as follows:
gcc -o test1 test1.c $(pkg-config --cflags --libs guile-2.0)
gcc -o test2 test2.c $(pkg-config --cflags --libs guile-2.0)
Any ideas?
Thanks,
Mark
#include <libguile.h>
static SCM
thread_main (void *data)
{
/* scm_sleep (scm_from_signed_integer (20)); /* This should cause a timeout
*/
/* scm_sleep (SCM_BOOL_T); /* This should throw an
exception */
scm_sleep (scm_from_signed_integer (2)); /* This should finish */
return scm_from_latin1_string ("finished");
}
static SCM
thread_handler (void *data, SCM key, SCM args)
{
return scm_from_latin1_string ("exception thrown");
}
static void *
inner_main (void *data)
{
SCM thread = scm_spawn_thread (thread_main, 0, thread_handler, 0);
SCM timeout = scm_sum (scm_current_time(), scm_from_signed_integer (10));
SCM result = scm_join_thread_timed (thread, timeout, scm_from_latin1_string
("timed out"));
scm_simple_format (SCM_BOOL_T, scm_from_latin1_string ("~A\n"), scm_list_1
(result));
}
int
main (int argc, char **argv)
{
scm_with_guile (inner_main, 0);
return 0;
}
#include <libguile.h>
static SCM
thread_main (void)
{
/* scm_sleep (scm_from_signed_integer (20)); /* This should cause a timeout
*/
/* scm_sleep (SCM_BOOL_T); /* This should throw an
exception */
scm_sleep (scm_from_signed_integer (2)); /* This should finish */
return scm_from_latin1_string ("finished");
}
static SCM
thread_handler (SCM handler, SCM key, SCM args)
{
return scm_from_latin1_string ("exception thrown");
}
static void *
inner_main (void *data)
{
SCM thread_main_proc = scm_c_make_gsubr ("thread-main", 0, 0, 0, thread_main);
SCM thread_handler_proc = scm_c_make_gsubr ("thread-handler", 2, 0, 1,
thread_handler);
SCM thread = scm_call_with_new_thread (thread_main_proc, thread_handler_proc);
SCM timeout = scm_sum (scm_current_time(), scm_from_signed_integer (10));
SCM result = scm_join_thread_timed (thread, timeout, scm_from_latin1_string
("timed out"));
scm_simple_format (SCM_BOOL_T, scm_from_latin1_string ("~A\n"), scm_list_1
(result));
}
int
main (int argc, char **argv)
{
scm_with_guile (inner_main, 0);
return 0;
}
--- test1.c 2011-03-09 01:33:36.000000000 -0500
+++ test2.c 2011-03-09 01:34:18.000000000 -0500
@@ -1,7 +1,7 @@
#include <libguile.h>
static SCM
-thread_main (void *data)
+thread_main (void)
{
/* scm_sleep (scm_from_signed_integer (20)); /* This should cause a timeout
*/
/* scm_sleep (SCM_BOOL_T); /* This should throw an
exception */
@@ -10,7 +10,7 @@
}
static SCM
-thread_handler (void *data, SCM key, SCM args)
+thread_handler (SCM handler, SCM key, SCM args)
{
return scm_from_latin1_string ("exception thrown");
}
@@ -18,7 +18,9 @@
static void *
inner_main (void *data)
{
+ SCM thread_main_proc = scm_c_make_gsubr ("thread-main", 0, 0, 0,
thread_main);
+ SCM thread_handler_proc = scm_c_make_gsubr ("thread-handler", 2, 0, 1,
thread_handler);
- SCM thread = scm_spawn_thread (thread_main, 0, thread_handler, 0);
+ SCM thread = scm_call_with_new_thread (thread_main_proc,
thread_handler_proc);
SCM timeout = scm_sum (scm_current_time(), scm_from_signed_integer (10));
SCM result = scm_join_thread_timed (thread, timeout, scm_from_latin1_string
("timed out"));
scm_simple_format (SCM_BOOL_T, scm_from_latin1_string ("~A\n"), scm_list_1
(result));