From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.devel Subject: Re: Trouble joining with threads from C Date: Wed, 09 Mar 2011 01:48:52 -0500 Message-ID: <8762rswzzf.fsf@netris.org> References: <87y64rzd5p.fsf@netris.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: dough.gmane.org 1299653373 21192 80.91.229.12 (9 Mar 2011 06:49:33 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 9 Mar 2011 06:49:33 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Wed Mar 09 07:49:27 2011 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PxDD4-0008NS-3x for guile-devel@m.gmane.org; Wed, 09 Mar 2011 07:49:26 +0100 Original-Received: from localhost ([127.0.0.1]:44350 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxDCs-0004ZS-Pf for guile-devel@m.gmane.org; Wed, 09 Mar 2011 01:49:14 -0500 Original-Received: from [140.186.70.92] (port=41692 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxDCe-0004X5-JH for guile-devel@gnu.org; Wed, 09 Mar 2011 01:49:01 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PxDCd-0008Qe-Gj for guile-devel@gnu.org; Wed, 09 Mar 2011 01:49:00 -0500 Original-Received: from world.peace.net ([216.204.32.208]:34605) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PxDCd-0008QN-9J for guile-devel@gnu.org; Wed, 09 Mar 2011 01:48:59 -0500 Original-Received: from ip68-9-118-38.ri.ri.cox.net ([68.9.118.38] helo=freedomincluded) by world.peace.net with esmtpa (Exim 4.69) (envelope-from ) id 1PxDCX-0008J2-BE; Wed, 09 Mar 2011 01:48:53 -0500 Original-Received: from mhw by freedomincluded with local (Exim 4.69) (envelope-from ) id 1PxDCW-0004Is-LJ; Wed, 09 Mar 2011 01:48:52 -0500 In-Reply-To: <87y64rzd5p.fsf@netris.org> (Mark H. Weaver's message of "Mon, 07 Mar 2011 00:56:50 -0500") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 216.204.32.208 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:11837 Archived-At: --=-=-= 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 --=-=-= Content-Type: text/x-csrc Content-Disposition: inline; filename=test1.c Content-Description: test1.c, which uses scm_spawn_thread #include 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; } --=-=-= Content-Type: text/x-csrc Content-Disposition: inline; filename=test2.c Content-Description: test2.c, which uses scm_call_with_new_thread #include 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; } --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=test1-to-test2.diff Content-Description: Diff between test1.c and test2.c --- 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 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)); --=-=-=--