]> granicus.if.org Git - zziplib/commitdiff
multi threading notes
authorGuido Draheim <guidod@gmx.de>
Mon, 12 Dec 2005 05:25:58 +0000 (05:25 +0000)
committerGuido Draheim <guidod@gmx.de>
Mon, 12 Dec 2005 05:25:58 +0000 (05:25 +0000)
 (.)

ChangeLog
configure
m4/ax_enable_builddir.m4
zzip/Makefile.am
zzip/Makefile.in
zzip/file.c
zzip/file.h
zzip/lib.h

index ac58a90789f6e79413611ff9b9a0106add2809bd..6315b929037698053b621a3fc0fc2687c2f4471f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2005-12-11
+ * there have been reports about multithreading problems
+ * one source of problems: access to the dir->cache members.
+       fixed by using an explicit semaphore variable, otherwise
+       just allocate/deallocate the buffer / filehandle
+ * second source of problems: the zip file is opened _and_ read
+       with only one filehandle for multiple threads that
+       share the same "dir" handle. Look for "->currentfp".
+ * that is not fixed away - while access to the cache variables
+       can continue in the case of a "locked" state that is not
+       possible for open/reads. In the "locked" case the thread
+       must be blocked but that is a system-specific call.
+ * there are two ways to fix it - (a) push down the sysfile to
+       each zzip_file by "dup(2)"licating the sysfile handle.
+       However zzip looses a feature that was helping a lot on
+       system with a low number of sysfile hands (e.g. dos and
+       some embedded operating systems that I did work with).
+       and (b) provide an indirect ->lock() call that can be
+       filled by the caller application upon zzip invokation,
+       perhaps add it to the io-plugin structure. Well (c) is
+       it possible to support both styles? Dynamically?
+
 2005-12-10
  * testing on sourceforge compilefarm - including "make check"
  * there was an error on bsd'ish systems (implicit 64on32)
index 96d8e09916899ef839a232bd34c1c19ba29b096d..e12707004a48b155d94908b666d04612b612517c 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac Revision: 1.4 .
+# From configure.ac Revision: 1.5 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -1746,8 +1746,10 @@ else
 echo "${ECHO_T}no" >&6
 fi
 
-ax_enable_builddir_auxdir="$ac_aux_dir" ; test ".$ax_enable_builddir_auxdir" = "." && ax_enable_builddir_auxdir="."
+ax_enable_builddir_auxdir="$ac_aux_dir"
 ax_enable_builddir_auxdir=`echo "$ax_enable_builddir_auxdir" | $ax_enable_builddir_sed -e "s|$ac_top_srcdir|.|"`
+test ".$ax_enable_builddir_auxdir" = "." && ax_enable_builddir_auxdir="$ac_aux_dir"
+test ".$ax_enable_builddir_auxdir" = "." && ax_enable_builddir_auxdir="."
           ac_config_commands="$ac_config_commands buildir"
 
  # --------------------------------------------
@@ -4369,7 +4371,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4372 "configure"' > conftest.$ac_ext
+  echo '#line 4374 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6190,7 +6192,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:6193:" \
+echo "$as_me:6195:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -7288,11 +7290,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7291: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7293: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7295: \$? = $ac_status" >&5
+   echo "$as_me:7297: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7550,11 +7552,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7553: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7555: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7557: \$? = $ac_status" >&5
+   echo "$as_me:7559: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7612,11 +7614,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7615: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7617: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7619: \$? = $ac_status" >&5
+   echo "$as_me:7621: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9852,7 +9854,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9855 "configure"
+#line 9857 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9950,7 +9952,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9953 "configure"
+#line 9955 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12198,11 +12200,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12201: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12203: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:12205: \$? = $ac_status" >&5
+   echo "$as_me:12207: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -12260,11 +12262,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12263: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12265: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:12267: \$? = $ac_status" >&5
+   echo "$as_me:12269: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -13629,7 +13631,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 13632 "configure"
+#line 13634 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13727,7 +13729,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 13730 "configure"
+#line 13732 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14612,11 +14614,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14615: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14617: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14619: \$? = $ac_status" >&5
+   echo "$as_me:14621: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14674,11 +14676,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14677: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14679: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14681: \$? = $ac_status" >&5
+   echo "$as_me:14683: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -16796,11 +16798,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16799: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16801: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16803: \$? = $ac_status" >&5
+   echo "$as_me:16805: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17058,11 +17060,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17061: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17063: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17065: \$? = $ac_status" >&5
+   echo "$as_me:17067: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17120,11 +17122,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17123: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17125: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:17127: \$? = $ac_status" >&5
+   echo "$as_me:17129: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -19360,7 +19362,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 19363 "configure"
+#line 19365 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19458,7 +19460,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 19461 "configure"
+#line 19463 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
index 42635125f5701a871ec3f738c25187803c38bde3..db1f6b6ffea023ba2c1707f7d9e554b2a04b0b0b 100644 (file)
@@ -92,8 +92,10 @@ if test ".$srcdir" = ".." ; then
 fi fi
 dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"
 AC_PATH_PROG(SED,gsed sed, sed)
-AUX="$ac_aux_dir" ; test ".$AUX" = "." && AUX="."
+AUX="$ac_aux_dir" 
 AUX=`echo "$AUX" | $SED -e "s|$ac_top_srcdir|.|"` 
+test ".$AUX" = "." && AUX="$ac_aux_dir"
+test ".$AUX" = "." && AUX="."
 AS_VAR_POPDEF([SED])dnl
 AS_VAR_POPDEF([AUX])dnl
 AS_VAR_POPDEF([SUB])dnl
index 951210b955f727d989d8e90dfbc35e787a4950d4..95fb8f17f78a3bf003623d1fec166114cfe4fc10 100644 (file)
@@ -115,9 +115,11 @@ zzip-zlib-config.pc : Makefile
        echo 'Cflags: $${zlib_cflags}' >>$@
 
 zzipmmapped.pc : zziplib.pc
-       sed -e 's/-lzzip/-lzzipmmapped/' -e 's/zziplib/zzipmmapped/' $< >$@
+       sed -e 's/-lzzip/-lzzipmmapped/' -e 's/zziplib/zzipmmapped/' \
+       zziplib.pc >$@
 zzipfseeko.pc : zziplib.pc
-       sed -e 's/-lzzip/-lzzipfseeko/' -e 's/zziplib/zzipfseeko/' $< >$@
+       sed -e 's/-lzzip/-lzzipfseeko/' -e 's/zziplib/zzipfseeko/' \
+       zziplib.pc >$@
 
 __zziplib.pc : Makefile
        @ echo "prefix=$(prefix)" >$@
index dfcbce21a6a2dd42d63bb4685b906c0b2d8806e3..3ebe0b31b6a3940cbd8a4fa0e4868981bb18f62b 100644 (file)
@@ -682,9 +682,11 @@ zzip-zlib-config.pc : Makefile
        echo 'Cflags: $${zlib_cflags}' >>$@
 
 zzipmmapped.pc : zziplib.pc
-       sed -e 's/-lzzip/-lzzipmmapped/' -e 's/zziplib/zzipmmapped/' $< >$@
+       sed -e 's/-lzzip/-lzzipmmapped/' -e 's/zziplib/zzipmmapped/' \
+       zziplib.pc >$@
 zzipfseeko.pc : zziplib.pc
-       sed -e 's/-lzzip/-lzzipfseeko/' -e 's/zziplib/zzipfseeko/' $< >$@
+       sed -e 's/-lzzip/-lzzipfseeko/' -e 's/zziplib/zzipfseeko/' \
+       zziplib.pc >$@
 
 __zziplib.pc : Makefile
        @ echo "prefix=$(prefix)" >$@
index 86713aff9132184bc4bfa567469bec08ed3484a8..4944cd7c74aada153e094c6f3c0138508054a81a 100644 (file)
 int 
 zzip_file_close(ZZIP_FILE * fp)
 {
+    auto int self;
     ZZIP_DIR * dir = fp->dir;
     
     if (fp->method)
         inflateEnd(&fp->d_stream); /* inflateEnd() can be called many times */
 
+    if (dir->cache.locked == NULL) 
+       dir->cache.locked = &self;
+
     if (fp->buf32k)
     {
-        if (dir->cache.buf32k == NULL) dir->cache.buf32k = fp->buf32k;
+        if (dir->cache.locked == &self &&
+           dir->cache.buf32k == NULL) dir->cache.buf32k = fp->buf32k;
         else free(fp->buf32k);
     }
 
@@ -64,8 +69,12 @@ zzip_file_close(ZZIP_FILE * fp)
     /* ease to notice possible dangling reference errors */
     memset(fp, 0, sizeof(*fp)); 
 
-    if (dir->cache.fp == NULL) dir->cache.fp = fp;
+    if (dir->cache.locked == &self &&
+       dir->cache.fp == NULL) dir->cache.fp = fp;
     else free(fp);
+
+    if (dir->cache.locked == &self) 
+       dir->cache.locked = NULL;
     
     if (! dir->refcount) return zzip_dir_close(dir); else return 0;
 }
@@ -142,6 +151,7 @@ static int zzip_inflate_init(ZZIP_FILE *, struct zzip_dir_hdr *);
 ZZIP_FILE * 
 zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
 {
+    auto int self;
     zzip_error_t err = 0;
     struct zzip_file * fp = 0;
     struct zzip_dir_hdr * hdr = dir->hdr0;
@@ -181,7 +191,11 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
                 { err = ZZIP_UNSUPP_COMPR; goto error; }
             }
 
-            if (dir->cache.fp) 
+           if (dir->cache.locked == NULL)
+               dir->cache.locked = &self;
+
+            if (dir->cache.locked == &self &&
+               dir->cache.fp) 
             {
                 fp = dir->cache.fp; dir->cache.fp = NULL;
                 /* memset(zfp, 0, sizeof *fp); cleared in zzip_file_close() */
@@ -195,7 +209,8 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
             fp->io = dir->io;
             dir->refcount++;
         
-            if (dir->cache.buf32k) 
+            if (dir->cache.locked == &self &&
+               dir->cache.buf32k) 
               { fp->buf32k = dir->cache.buf32k; dir->cache.buf32k = NULL; }
             else
             {
@@ -203,6 +218,8 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
                     { err = ZZIP_OUTOFMEM; goto error; }
             }
 
+           if (dir->cache.locked == &self)
+               dir->cache.locked = NULL;
             /*
              * In order to support simultaneous open files in one zip archive
              * we'll fix the fd offset when opening new file/changing which
index e3b3497f3337f5d5958d4c1b3aa8fc8669578936..7a35aeb14823680368b429cd274ef02d613b1b53 100644 (file)
 \r
 struct zzip_file\r
 {\r
-  struct zzip_dir* dir; \r
-  int fd;\r
-  int method;\r
-  zzip_size_t restlen;\r
-  zzip_size_t crestlen;\r
-  zzip_size_t usize;\r
-  zzip_size_t csize;\r
-  /* added dataoffset member - data offset from start of zipfile*/\r
-  zzip_off_t dataoffset;\r
-  char* buf32k;\r
-  zzip_off_t offset; /* offset from the start of zipfile... */\r
-  z_stream d_stream;\r
-  zzip_plugin_io_t io;\r
+    struct zzip_dir* dir; \r
+    int fd;\r
+    int method;\r
+    zzip_size_t restlen;\r
+    zzip_size_t crestlen;\r
+    zzip_size_t usize;\r
+    zzip_size_t csize;\r
+    /* added dataoffset member - data offset from start of zipfile*/\r
+    zzip_off_t dataoffset;\r
+    char* buf32k;\r
+    zzip_off_t offset; /* offset from the start of zipfile... */\r
+    z_stream d_stream;\r
+    zzip_plugin_io_t io;\r
 };\r
 \r
 #endif /* _ZZIP_FILE_H */\r
index 9cb6ec68c3b1c82976ef0f71e33494e1df2d8a68..d5608cd4e99d3452dfe5d1b7654c02faa3728e7c 100644 (file)
@@ -48,9 +48,10 @@ struct zzip_dir
     int fd;
     int errcode; /* zzip_error_t */
     long refcount;
-    struct {
-        struct zzip_file * fp;  /* reduce a lot of alloc/deallocations by */
-        char * buf32k;         /* caching one entry of these data structures */
+    struct { /* reduce a lot of alloc/deallocations by caching these: */
+       volatile int* locked;
+        volatile struct zzip_file * fp;  
+        volatile char * buf32k; 
     } cache;
     struct zzip_dir_hdr * hdr0;  /* zfi; */
     struct zzip_dir_hdr * hdr;   /* zdp; directory pointer, for dirent stuff */