libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fix the locking issue


From: Ralf Wildenhues
Subject: fix the locking issue
Date: Thu, 9 Feb 2006 16:31:46 +0100
User-agent: Mutt/1.5.11

It is just intricate.  I'm don't mind a merge after 2.0, but if you deem
it ok, I'd put it in CVS HEAD now.

Prologue
--------
We assume that the user is not so stup^H^H^H^Hadventurous to do
something along these lines:
  $LIBTOOL --mode=compile --tag=CC  $CC  -c baz.c -o foo.$OBJEXT
  $LIBTOOL --mode=compile --tag=F77 $F77 -c foo.f -o bar.$OBJEXT

(i.e., one of the _desired_ object file names is the one that
a(nother) possibly losing compiler would create by default)?

Otherwise, we'd need to enable locking for _all_ compilers if at least
one of them turns out to be broken.  :-/

We document a similar example in the manual and state that it needs to
be avoided anyway.


Main part
---------
If above may be ruled out, then the patch at the end of this post should
fix this locking issue:
http://lists.gnu.org/archive/html/libtool-patches/2005-03/msg00252.html

Notes:
- The creation of the .libs/LoCk_SrC file may cause spurious errors on
  w32 systems, thus the drop of stderr.
- We cannot remove the .libs/LoCk_SrC file in compile mode: that could
  defeat another libtool process concurrently running.  For the same
  reason, it does not make sense to put the object file name in its
  _name_.
- Not creating the bugger in dry mode is necessary for mdemo-dryrun to
  succeed.
- Testing for its existence in clean mode before removing is a hack,
  and won't save us in case the user is strange enough to do a parallel
  clean with `rm' as opposed to `rm -f'.  The fact that it is removed on
  the command line of the first object may seem a bit strange, however I
  could not see a good reason to add more special code for this.
- If the user actually passes a non-existing object file `foo.lo' as the
  first one for this directory, then the `LoCk_SrC' file will not be
  removed.
- Surely it breaks for a 'libtool --mode=clean' concurrently with a
  'libtool --mode=compile'.  Some sanity has to be expected from the user.
- If any program has name `LoCk_SrC' and needs to be relinked upon
  execution, things break horribly.


Epilogue
--------
Unfixed issue (which I don't intend to attack now):

- need_locks is not tagged ATM.  It should not be (compiler_c_o already
  is), but tests for later tags should not be able to set it to NO, if
  earlier ones set it to something else.

- putting the object file name in the _contents_ of the lock file is
  wrong, too, but AFAICS harmless, so it will be fixed later.

Cheers,
Ralf

        * libltdl/config/ltmain.m4sh (func_mode_compile): When locking
        is necessary, hard-link against `.libs/lock_src' instead of
        `$progpath'.
        (func_mode_uninstall): In clean mode, remove `LoCk_SrC' if
        present, along with the first object we remove.
        Fixes potential hang reported by Marcin Siennicki and others.

Index: libltdl/config/ltmain.m4sh
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v
retrieving revision 1.35
diff -u -r1.35 ltmain.m4sh
--- libltdl/config/ltmain.m4sh  5 Feb 2006 11:06:31 -0000       1.35
+++ libltdl/config/ltmain.m4sh  5 Feb 2006 20:11:07 -0000
@@ -1330,6 +1330,14 @@
     # not support -o with -c
     if test "$compiler_c_o" = no; then
       output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 
's%\.[[^.]]*$%%'`.${objext}
+      lock_src="$xdir$objdir/LoCk_SrC"
+      $opt_dry_run || {
+       func_mkdir_p "$xdir$objdir"
+       test -f "$lock_src" || {
+         { touch "$lock_src" || echo dummy > "$lock_src"; } 2>/dev/null
+         test -f "$lock_src" || func_fatal_error "Cannot create $lock_src for 
locking."
+       }
+      }
       lockfile="$output_obj.lock"
       removelist="$removelist $output_obj $lockfile"
       trap "$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE" 1 2 15
@@ -1342,7 +1350,7 @@
     # Lock this critical section if it is needed
     # We use this script file to make the link, it avoids creating a new file
     if test "$need_locks" = yes; then
-      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+      until $opt_dry_run || ln "$lock_src" "$lockfile" 2>/dev/null; do
        func_echo "Waiting for $lockfile to be removed"
        sleep 2
       done
@@ -6691,12 +6701,18 @@
       func_basename "$file"
       name="$func_basename_result"
       test "$mode" = uninstall && objdir="$dir"
+      rmfiles=
 
       # Remember objdir for removal later, being careful to avoid duplicates
       if test "$mode" = clean; then
        case " $rmdirs " in
          *" $objdir "*) ;;
-         *) rmdirs="$rmdirs $objdir" ;;
+         *)
+           rmdirs="$rmdirs $objdir"
+           if test "$need_locks" = yes && test -f "$objdir/LoCk_SrC"; then
+             rmfiles="$rmfiles $objdir/LoCk_SrC"
+           fi
+         ;;
        esac
       fi
 
@@ -6712,7 +6728,7 @@
        continue
       fi
 
-      rmfiles="$file"
+      rmfiles="$rmfiles $file"
 
       case $name in
       *.la)




reply via email to

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