guile-devel
[Top][All Lists]
Advanced

[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));

reply via email to

[Prev in Thread] Current Thread [Next in Thread]