From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kevin Ryde Newsgroups: gmane.lisp.guile.devel Subject: Re: crypt mutex Date: Sat, 24 Jul 2004 09:53:11 +1000 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <87fz7ii8m0.fsf@zip.com.au> References: <87znbdi85m.fsf@zip.com.au> <87znb98v9x.fsf@zagadka.ping.de> <87hdwjnnxq.fsf@zagadka.ping.de> <878yhv3zea.fsf@zip.com.au> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1090626837 981 80.91.224.253 (23 Jul 2004 23:53:57 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 23 Jul 2004 23:53:57 +0000 (UTC) Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Jul 24 01:53:49 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1Bo9rI-0003SS-00 for ; Sat, 24 Jul 2004 01:53:48 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1Bo9uC-0003Vr-Tl for guile-devel@m.gmane.org; Fri, 23 Jul 2004 19:56:48 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1Bo9uA-0003Vj-Cv for guile-devel@gnu.org; Fri, 23 Jul 2004 19:56:46 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1Bo9u8-0003V9-Vk for guile-devel@gnu.org; Fri, 23 Jul 2004 19:56:45 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1Bo9u8-0003V6-TV for guile-devel@gnu.org; Fri, 23 Jul 2004 19:56:44 -0400 Original-Received: from [61.8.0.85] (helo=mailout2.pacific.net.au) by monty-python.gnu.org with esmtp (Exim 4.34) id 1Bo9qx-0005fe-DR for guile-devel@gnu.org; Fri, 23 Jul 2004 19:53:27 -0400 Original-Received: from mailproxy1.pacific.net.au (mailproxy1.pacific.net.au [61.8.0.86]) by mailout2.pacific.net.au (8.12.3/8.12.3/Debian-6.6) with ESMTP id i6NNrNje031025 for ; Sat, 24 Jul 2004 09:53:23 +1000 Original-Received: from localhost (ppp2D37.dyn.pacific.net.au [61.8.45.55]) by mailproxy1.pacific.net.au (8.12.3/8.12.3/Debian-6.6) with ESMTP id i6NNrKvd014951 for ; Sat, 24 Jul 2004 09:53:21 +1000 Original-Received: from gg by localhost with local (Exim 3.36 #1 (Debian)) id 1Bo9qi-00030K-00; Sat, 24 Jul 2004 09:53:12 +1000 Original-To: guile-devel@gnu.org Mail-Copies-To: never User-Agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3 (gnu/linux) 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: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.lisp.guile.devel:3881 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:3881 --=-=-= It took a while but I made the change below to protect crypt, introducing a new scm_i_misc_mutex intended for miscellaneous uses, like this one, which don't rate highly enough to deserve their own personal mutex. * threads.c, threads.h (scm_i_misc_mutex): New SCM_GLOBAL_MUTEX. * posix.c (scm_crypt): Use it to protect static data in crypt(). Thread trouble in the old code can be provoked fairly easily with something like the following. It's not the sort of thing that can be added to a test suite, but at least it shows the change has an effect :-). (use-modules (ice-9 threads)) (define k1 "blahblah") (define s1 "99") (define e1 (crypt k1 s1)) (define k2 "foobar") (define s2 "77") (define e2 (crypt k2 s2)) (begin-thread (while #t (display "-") (let ((e (crypt k1 s1))) (if (not (string=? e1 e)) (begin (format #t "oops, wrong e1, got ~s want ~s\n" e e1) (exit 1)))))) (while #t (display ".") (let ((e (crypt k2 s2))) (if (not (string=? e2 e)) (begin (format #t "oops, wrong e2, got ~s want ~s\n" e e2) (exit 1))))) --=-=-= Content-Disposition: attachment; filename=posix.c.crypt.diff --- posix.c.~1.132.~ 2004-07-14 10:19:36.000000000 +1000 +++ posix.c 2004-07-23 17:12:23.000000000 +1000 @@ -1426,20 +1426,46 @@ #undef FUNC_NAME #endif /* HAVE_SYNC */ + +/* crypt() returns a pointer to a static buffer, so we use scm_i_misc_mutex + to avoid another thread overwriting it. A test program running crypt + continuously in two threads can be quickly seen tripping this problem. + crypt() is pretty slow normally, so a mutex shouldn't add much overhead. + + glibc has a thread-safe crypt_r, but (in version 2.3.2) it runs a lot + slower (about 5x) than plain crypt if you pass an uninitialized data + block each time. Presumably there's some one-time setups. The best way + to use crypt_r to allow parallel execution in multiple threads would + probably be to maintain a little pool of initialized crypt_data + structures, take one and use it, then return it to the pool. That pool + could be garbage collected so it didn't add permanently to memory use in + case only a few crypt calls are made. But we expect crypt will be used + rarely, and even more rarely will there be any desire for lots of + parallel execution on multiple cpus. So for now we don't bother with + anything fancy, just ensure it's thread-safe. */ + #if HAVE_CRYPT -SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0, +SCM_DEFINE (scm_crypt, "crypt", 2, 0, 0, (SCM key, SCM salt), "Encrypt @var{key} using @var{salt} as the salt value to the\n" "crypt(3) library call.") #define FUNC_NAME s_scm_crypt { - char * p; - + SCM ret; SCM_VALIDATE_STRING (1, key); SCM_VALIDATE_STRING (2, salt); - p = crypt (SCM_STRING_CHARS (key), SCM_STRING_CHARS (salt)); - return scm_makfrom0str (p); + scm_frame_begin (0); + scm_frame_unwind_handler ((void(*)(void*)) scm_mutex_unlock, + &scm_i_misc_mutex, + SCM_F_WIND_EXPLICITLY); + scm_mutex_lock (&scm_i_misc_mutex); + + ret = scm_makfrom0str (crypt (SCM_STRING_CHARS (key), + SCM_STRING_CHARS (salt))); + + scm_frame_end (); + return ret; } #undef FUNC_NAME #endif /* HAVE_CRYPT */ --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel --=-=-=--