apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jerenkra...@apache.org
Subject svn commit: rev 76072 - in apr/apr/branches/1.0.x: . atomic/netware atomic/unix atomic/win32 build file_io/netware file_io/os2 file_io/unix file_io/win32 include include/arch include/arch/netware include/arch/win32 memory/unix misc/unix network_io/win32 poll/unix random/unix shmem/unix tables test threadproc/beos threadproc/win32
Date Wed, 17 Nov 2004 01:07:04 GMT
Author: jerenkrantz
Date: Tue Nov 16 17:07:02 2004
New Revision: 76072

Modified:
   apr/apr/branches/1.0.x/.cvsignore
   apr/apr/branches/1.0.x/CHANGES
   apr/apr/branches/1.0.x/Makefile.in
   apr/apr/branches/1.0.x/STATUS
   apr/apr/branches/1.0.x/atomic/netware/apr_atomic.c
   apr/apr/branches/1.0.x/atomic/unix/apr_atomic.c
   apr/apr/branches/1.0.x/atomic/win32/apr_atomic.c
   apr/apr/branches/1.0.x/build/apr_hints.m4
   apr/apr/branches/1.0.x/build/jlibtool.c
   apr/apr/branches/1.0.x/configure.in
   apr/apr/branches/1.0.x/file_io/netware/mktemp.c
   apr/apr/branches/1.0.x/file_io/os2/filesys.c
   apr/apr/branches/1.0.x/file_io/unix/readwrite.c
   apr/apr/branches/1.0.x/file_io/win32/dir.c
   apr/apr/branches/1.0.x/file_io/win32/filedup.c
   apr/apr/branches/1.0.x/file_io/win32/open.c
   apr/apr/branches/1.0.x/file_io/win32/readwrite.c
   apr/apr/branches/1.0.x/include/apr.hw
   apr/apr/branches/1.0.x/include/apr_network_io.h
   apr/apr/branches/1.0.x/include/apr_shm.h
   apr/apr/branches/1.0.x/include/apr_version.h
   apr/apr/branches/1.0.x/include/arch/apr_private_common.h
   apr/apr/branches/1.0.x/include/arch/netware/apr_private.h
   apr/apr/branches/1.0.x/include/arch/win32/apr_arch_threadproc.h
   apr/apr/branches/1.0.x/include/arch/win32/apr_private.h
   apr/apr/branches/1.0.x/memory/unix/apr_pools.c
   apr/apr/branches/1.0.x/misc/unix/charset.c
   apr/apr/branches/1.0.x/misc/unix/errorcodes.c
   apr/apr/branches/1.0.x/network_io/win32/sendrecv.c
   apr/apr/branches/1.0.x/poll/unix/poll.c
   apr/apr/branches/1.0.x/random/unix/apr_random.c
   apr/apr/branches/1.0.x/shmem/unix/shm.c
   apr/apr/branches/1.0.x/tables/apr_hash.c
   apr/apr/branches/1.0.x/test/Makefile.in
   apr/apr/branches/1.0.x/test/Makefile.win
   apr/apr/branches/1.0.x/test/testrand2.c
   apr/apr/branches/1.0.x/test/teststr.c
   apr/apr/branches/1.0.x/threadproc/beos/.cvsignore
   apr/apr/branches/1.0.x/threadproc/win32/proc.c
   apr/apr/branches/1.0.x/threadproc/win32/thread.c
Log:
Merge in changes from trunk to 1.0.x.

Changes have been reviewed to be binary compatible with 1.0.0 by Justin to
the best of his sleep-deprived ability.


Modified: apr/apr/branches/1.0.x/.cvsignore
==============================================================================
--- apr/apr/branches/1.0.x/.cvsignore	(original)
+++ apr/apr/branches/1.0.x/.cvsignore	Tue Nov 16 17:07:02 2004
@@ -6,6 +6,7 @@
 configure
 libtool
 apr-config
+apr-*-config
 apr-config.out
 LibD
 LibR
@@ -38,4 +39,5 @@
 *.bbg
 *.da
 coverage
-apr.pc
+apr*.pc
+apr.spec

Modified: apr/apr/branches/1.0.x/CHANGES
==============================================================================
--- apr/apr/branches/1.0.x/CHANGES	(original)
+++ apr/apr/branches/1.0.x/CHANGES	Tue Nov 16 17:07:02 2004
@@ -1,3 +1,37 @@
+Changes for APR 1.0.1
+
+  *) Fix HUP return codes in pollset when using KQueue.
+     [Paul Querna]
+
+  *) Prevent unbounded memory use during repeated operations on a hash table.
+     [Julian Foad <julianfoad btopenworld.com>
+
+  *) Moved repository to SVN
+     [Hackathon]
+
+  *) jlibtool: Ignore '-export-symbols-regexp' option.
+     [Justin Erenkrantz]
+
+  *) fix apr_file_dup and apr_file_dup2 win32 implementations
+     to create a mutex [Steve Hay <steve.hay uk.radan.com>]
+
+  *) Makes the threads to behave like on posix. If the thread is created
+     without APR_DETACH expect that the thread_join will be called, so don't
+     close the handle in advance, if the thread has already finished.
+     [Mladen Turk]
+
+  *) The apr/test/Makefile.win is missing a target to build a
+     readchild.exe that test is depending on but is never built.
+     [Mladen Turk]
+
+  *) Improve apr_file_gets() performance on buffered files. [Justin Erenkrantz]
+
+  *) Win32: Fix bug in apr_socket_sendfile that interferred with
+     Win32 LSPs. PR 23982 [Jan Bilek, Bill Stoddard]
+
+  *) Win32: Fix bug tracking the file pointer on a file opened for 
+     overlapped/APR_XTHREAD io. [Bill Stoddard]
+
 Changes with APR 1.0
 
   *) Only install apr-$MAJOR-config and add appropriate detection code to

Modified: apr/apr/branches/1.0.x/Makefile.in
==============================================================================
--- apr/apr/branches/1.0.x/Makefile.in	(original)
+++ apr/apr/branches/1.0.x/Makefile.in	Tue Nov 16 17:07:02 2004
@@ -76,7 +76,7 @@
 	for f in libtool shlibtool; do \
 	    if test -f $${f}; then $(INSTALL) -m 755 $${f} $(DESTDIR)$(installbuilddir); fi; \
 	done
-	$(INSTALL) -m 755 build/mkdir.sh $(DESTDIR)$(installbuilddir)
+	$(INSTALL) -m 755 $(top_srcdir)/build/mkdir.sh $(DESTDIR)$(installbuilddir)
 	for f in make_exports.awk make_var_export.awk; do \
 	    $(INSTALL_DATA) $(top_srcdir)/build/$${f} $(DESTDIR)$(installbuilddir); \
 	done

Modified: apr/apr/branches/1.0.x/STATUS
==============================================================================
--- apr/apr/branches/1.0.x/STATUS	(original)
+++ apr/apr/branches/1.0.x/STATUS	Tue Nov 16 17:07:02 2004
@@ -1,5 +1,5 @@
 APACHE PORTABLE RUNTIME (APR) LIBRARY STATUS:			-*-text-*-
-Last modified at [$Date: 2004/06/30 11:29:48 $]
+Last modified at [$Date$]
 
 Releases:
 
@@ -23,10 +23,7 @@
     2.0a1     : released March 10, 2000
 
 
-RELEASE 0.9 SHOWSTOPPERS:
-
-
-RELEASE 1.0 SHOWSTOPPERS:
+RELEASE 1.0.1 SHOWSTOPPERS:
 
 
 CURRENT VOTES:

Modified: apr/apr/branches/1.0.x/atomic/netware/apr_atomic.c
==============================================================================
--- apr/apr/branches/1.0.x/atomic/netware/apr_atomic.c	(original)
+++ apr/apr/branches/1.0.x/atomic/netware/apr_atomic.c	Tue Nov 16 17:07:02 2004
@@ -60,8 +60,7 @@
 
 APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) 
 {
-    atomic_dec((unsigned long *)mem);
-    return *mem; 
+    return (atomic_xchgadd((unsigned long *)mem, 0xFFFFFFFF) - 1);
 }
 
 APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp)

Modified: apr/apr/branches/1.0.x/atomic/unix/apr_atomic.c
==============================================================================
--- apr/apr/branches/1.0.x/atomic/unix/apr_atomic.c	(original)
+++ apr/apr/branches/1.0.x/atomic/unix/apr_atomic.c	Tue Nov 16 17:07:02 2004
@@ -21,6 +21,12 @@
 
 #include <stdlib.h>
 
+#if defined(__GNUC__) && defined(__STRICT_ANSI__) && !defined(USE_GENERIC_ATOMICS)
+/* force use of generic atomics if building e.g. with -std=c89, which
+ * doesn't allow inline asm */
+#define USE_GENERIC_ATOMICS
+#endif
+
 #if (defined(__i386__) || defined(__x86_64__)) \
     && defined(__GNUC__) && !defined(USE_GENERIC_ATOMICS)
 

Modified: apr/apr/branches/1.0.x/atomic/win32/apr_atomic.c
==============================================================================
--- apr/apr/branches/1.0.x/atomic/win32/apr_atomic.c	(original)
+++ apr/apr/branches/1.0.x/atomic/win32/apr_atomic.c	Tue Nov 16 17:07:02 2004
@@ -40,7 +40,11 @@
 
 APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
 {
+#if (defined(_M_IA64) || defined(_M_AMD64))
+    return InterlockedExchangeAdd(mem, val);
+#else
     return ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val);
+#endif
 }
 
 /* Of course we want the 2's compliment of the unsigned value, val */
@@ -48,7 +52,11 @@
 
 APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
 {
+#if (defined(_M_IA64) || defined(_M_AMD64))
+    InterlockedExchangeAdd(mem, -val);
+#else
     ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, -val);
+#endif
 }
 
 APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem)

Modified: apr/apr/branches/1.0.x/build/apr_hints.m4
==============================================================================
--- apr/apr/branches/1.0.x/build/apr_hints.m4	(original)
+++ apr/apr/branches/1.0.x/build/apr_hints.m4	Tue Nov 16 17:07:02 2004
@@ -131,6 +131,9 @@
         ;;
     *-openbsd*)
 	APR_ADDTO(CPPFLAGS, [-D_POSIX_THREADS])
+        # binding to an ephemeral port fails on OpenBSD so override
+        # the test for O_NONBLOCK inheritance across accept().
+        APR_SETIFNULL(ac_cv_o_nonblock_inherited, [yes])
 	;;
     *-netbsd*)
 	APR_ADDTO(CPPFLAGS, [-DNETBSD])

Modified: apr/apr/branches/1.0.x/build/jlibtool.c
==============================================================================
--- apr/apr/branches/1.0.x/build/jlibtool.c	(original)
+++ apr/apr/branches/1.0.x/build/jlibtool.c	Tue Nov 16 17:07:02 2004
@@ -66,7 +66,8 @@
 #  define DYNAMIC_LINK_OPTS "-flat_namespace -undefined suppress"
 #  define dynamic_link_version_func darwin_dynamic_link_function
 #  define DYNAMIC_INSTALL_NAME "-install_name"
-//-install_name  /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0
+/*-install_name  /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
+#  define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
 #endif
 
 #if defined(__linux__) || defined(__FreeBSD__)
@@ -80,8 +81,13 @@
 #  define RANLIB "ranlib"
 #  define PIC_FLAG "-fPIC"
 #  define RPATH "-rpath"
-#  define DYNAMIC_LINK_OPTS "-shared"
+#  define SHARED_OPTS "-shared"
+#  define MODULE_OPTS "-shared"
+#  define DYNAMIC_LINK_OPTS "-export-dynamic"
 #  define LINKER_FLAG_PREFIX "-Wl,"
+#  define ADD_MINUS_L
+#  define LD_RUN_PATH "LD_RUN_PATH"
+#  define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
 #endif
 
 #if defined(_OSD_POSIX)
@@ -92,11 +98,30 @@
 #  define OBJECT_EXT     "o"
 #  define LIBRARIAN      "ar"
 #  define LIBRARIAN_OPTS "cr"
-#  define DYNAMIC_LINK_OPTS "-G"
+#  define SHARED_OPTS "-G"
+#  define MODULE_OPTS "-G"
 #  define LINKER_FLAG_PREFIX "-Wl,"
 #  define NEED_SNPRINTF
 #endif
 
+#if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
+#  define SHELL_CMD  "/usr/bin/sh"
+#  define DYNAMIC_LIB_EXT "so"
+#  define MODULE_LIB_EXT  "so"
+#  define STATIC_LIB_EXT "a"
+#  define OBJECT_EXT     "o"
+#  define LIBRARIAN      "ar"
+#  define LIBRARIAN_OPTS "cr"
+#  define RPATH "-Brpath"
+#  define SHARED_OPTS "-G"
+#  define MODULE_OPTS "-G"
+#  define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"
+#  define LINKER_FLAG_PREFIX "-Wl,"
+#  define NEED_SNPRINTF
+#  define LD_RUN_PATH "LD_RUN_PATH"
+#  define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
+#endif
+
 #ifndef SHELL_CMD
 #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
 #endif
@@ -140,6 +165,14 @@
     pic_AVOID,
 };
 
+enum lib_type {
+    type_UNKNOWN,
+    type_DYNAMIC_LIB,
+    type_STATIC_LIB,
+    type_MODULE_LIB,
+    type_OBJECT,
+};
+
 typedef struct {
     const char **vals;
     int num; 
@@ -383,6 +416,23 @@
     return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);
 }
 
+/*
+ * print configuration
+ * shlibpath_var is used in configure.
+ */
+void print_config()
+{
+#ifdef LD_RUN_PATH
+    printf("runpath_var=%s\n", LD_RUN_PATH);
+#endif
+#ifdef LD_LIBRARY_PATH
+    printf("shlibpath_var=%s\n", LD_LIBRARY_PATH);
+#endif
+#ifdef SHELL_CMD
+    printf("SHELL=\"%s\"\n", SHELL_CMD);
+#endif
+}
+
 int parse_long_opt(char *arg, command_t *cmd_data)
 {
     char *equal_pos = strchr(arg, '=');
@@ -427,6 +477,8 @@
         printf("Version " VERSION "\n");
     } else if (strcmp(var, "help") == 0) {
         printf("Sorry.  No help available.\n");
+    } else if (strcmp(var, "config") == 0) {
+        print_config();
     } else {
         return 0;
     }
@@ -651,7 +703,7 @@
         } 
 
         if (!cmd->options.silent) {
-            printf("Checking: %s\n", newarg);
+            printf("Checking (obj): %s\n", newarg);
         }
         rv = stat(newarg, &sb);
     }
@@ -672,7 +724,7 @@
  * 1 - .libs suffix
  */
 char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
-                           int libdircheck)
+                           int libdircheck, enum lib_type *libtype)
 {
     char *newarg, *ext;
     int pass, rv, newpathlen;
@@ -699,24 +751,29 @@
         case 0:
             if (cmd->options.pic_mode != pic_AVOID || cmd->options.shared) {
                 strcpy(ext, DYNAMIC_LIB_EXT);
+                *libtype = type_DYNAMIC_LIB;
                 break;
             }
             pass = 1;
         case 1:
             strcpy(ext, STATIC_LIB_EXT);
+            *libtype = type_STATIC_LIB;
             break;
         case 2:
             strcpy(ext, MODULE_LIB_EXT);
+            *libtype = type_MODULE_LIB;
             break;
         case 3:
             strcpy(ext, OBJECT_EXT);
+            *libtype = type_OBJECT;
             break;
         default:
+            *libtype = type_UNKNOWN;
             break;
         } 
 
         if (!cmd->options.silent) {
-            printf("Checking: %s\n", newarg);
+            printf("Checking (lib): %s\n", newarg);
         }
         rv = stat(newarg, &sb);
     }
@@ -729,6 +786,72 @@
     return NULL;
 }
 
+/* Read the final install location and add it to runtime library search path. */
+#ifdef RPATH
+void add_rpath(count_chars *cc, const char *arg)
+{
+    FILE *f;
+    char path[256];
+    char *tmp;
+    int size=0;
+
+    f = fopen(arg,"r");
+    if (f == NULL) {
+        return;
+    }
+    fgets(path,sizeof(path), f);
+    fclose(f);
+    if (path[strlen(path)-1] == '\n') {
+        path[strlen(path)-1] = '\0';
+    }
+    /* Check that we have an absolut path.
+     * Otherwise the file could be a GNU libtool file.
+     */
+    if (path[0] != '/') {
+        return;
+    }
+#ifdef LINKER_FLAG_PREFIX
+    size = strlen(LINKER_FLAG_PREFIX);
+#endif
+    size = size + strlen(path) + strlen(RPATH) + 2;
+    tmp = malloc(size);
+    if (tmp == NULL) {
+        return;
+    }
+#ifdef LINKER_FLAG_PREFIX
+    strcpy(tmp, LINKER_FLAG_PREFIX); 
+    strcat(tmp, RPATH);
+#else
+    strcpy(tmp, RPATH);
+#endif
+    strcat(tmp, "=");
+    strcat(tmp, path);
+    
+    push_count_chars(cc, tmp);
+}
+#endif
+
+/* use -L -llibname to allow to use installed libraries */
+void add_minus_l(count_chars *cc, const char *arg)
+{
+    char *name = strrchr(arg, '/');
+    char *file = strrchr(arg, '.');
+    char *lib  = strstr(name, "lib");
+
+    if (name !=NULL && file != NULL && lib == name+1) {
+        *name = '\0';
+        *file = '\0';
+        file = name;
+        file = file+4;
+        push_count_chars(cc, "-L ");
+        push_count_chars(cc, arg);
+        push_count_chars(cc, "-l");
+        push_count_chars(cc, file);
+    } else {
+        push_count_chars(cc, arg);
+    }
+}
+
 void add_linker_flag_prefix(count_chars *cc, const char *arg)
 {
 #ifndef LINKER_FLAG_PREFIX
@@ -747,6 +870,7 @@
     char *ext = strrchr(arg, '.');
     char *name = strrchr(arg, '/');
     int pathlen;
+    enum lib_type libtype;
     char *newarg;
 
     if (!ext) {
@@ -788,22 +912,34 @@
         switch (cmd_data->mode) {
         case mLink:
             /* Try the .libs dir first! */
-            newarg = check_library_exists(cmd_data, arg, pathlen, 1);
+            newarg = check_library_exists(cmd_data, arg, pathlen, 1, &libtype);
             if (!newarg) {
                 /* Try the normal dir next. */
-                newarg = check_library_exists(cmd_data, arg, pathlen, 0);
+                newarg = check_library_exists(cmd_data, arg, pathlen, 0, &libtype);
                 if (!newarg) {
                     printf("Can not find suitable library for %s\n", arg);
                     exit(1);
                 }
             }
 
-            if (cmd_data->mode != mLink) {
-                push_count_chars(cmd_data->arglist, newarg);
+            /* It is not ok to just add the file: a library may added with:
+               1 - -L path library_name. (For *.so in Linux).
+               2 - library_name.
+             */
+#ifdef ADD_MINUS_L
+            if (libtype == type_DYNAMIC_LIB) {
+                 add_minus_l(cmd_data->shared_opts.dependencies, newarg);
+            } else {
+                 push_count_chars(cmd_data->shared_opts.dependencies, newarg);
             }
-            else {
-                push_count_chars(cmd_data->shared_opts.dependencies, newarg);
+#else
+            push_count_chars(cmd_data->shared_opts.dependencies, newarg);
+#endif
+#ifdef RPATH
+            if (libtype == type_DYNAMIC_LIB) {
+                 add_rpath(cmd_data->shared_opts.dependencies, arg);
             }
+#endif
             break;
         case mInstall:
             /* If we've already recorded a library to install, we're most
@@ -959,7 +1095,7 @@
     char *arg;
     int argused;
 
-    for (a=1; a < argc; a++) {
+    for (a = 1; a < argc; a++) {
         arg = argv[a];
         argused = 1;
 
@@ -985,6 +1121,10 @@
                     /* Store for later deciphering */
                     cmd_data->version_info = argv[++a];
                     argused = 1;
+                } else if (strcmp(arg+1, "export-symbols-regex") == 0) {
+                    /* Skip the argument. */
+                    ++a;
+                    argused = 1;
                 }
             }
         } else {
@@ -1349,9 +1489,6 @@
             lib_args[2] = NULL;
             external_spawn(cmd_data, RANLIB, lib_args);
 #endif
-            if (!cmd_data->options.dry_run) {
-                //link(
-            }
         }
 
         if (cmd_data->output == otDynamicLibraryOnly ||
@@ -1446,6 +1583,27 @@
     touch_args[2] = NULL;
     return external_spawn(cmd_data, "touch", touch_args);
 }
+#ifdef RPATH
+/* Store the install path in the *.la file */
+int add_for_runtime(command_t *cmd_data)
+{
+    if (cmd_data->mode == mInstall) {
+        return 0;
+    }
+    if (cmd_data->output == otDynamicLibraryOnly ||
+        cmd_data->output == otLibrary) {
+        FILE *f=fopen(cmd_data->fake_output_name,"w");
+        if (f == NULL) {
+            return -1;
+        }
+        fprintf(f,"%s\n", cmd_data->install_path);
+        fclose(f);
+        return(0);
+    } else {
+        return(ensure_fake_uptodate(cmd_data));
+    }
+}
+#endif
 
 int main(int argc, char *argv[])
 {
@@ -1488,7 +1646,11 @@
     rc = run_mode(&cmd_data);
 
     if (!rc) {
+#ifdef RPATH
+       add_for_runtime(&cmd_data); 
+#else
        ensure_fake_uptodate(&cmd_data);
+#endif
     }
 
     cleanup_tmp_dirs(&cmd_data);

Modified: apr/apr/branches/1.0.x/configure.in
==============================================================================
--- apr/apr/branches/1.0.x/configure.in	(original)
+++ apr/apr/branches/1.0.x/configure.in	Tue Nov 16 17:07:02 2004
@@ -155,6 +155,10 @@
         LIBTOOL="$apr_builddir/libtool"
         LIBTOOL_SRC="$apr_srcdir/build/jlibtool.c"
         $CC $CFLAGS $CPPFLAGS -o $LIBTOOL $LIBTOOL_SRC
+        eval `$apr_builddir/libtool --config | grep "^shlibpath_var=[[A-Z_]]*$"`
+        if test "x$shlibpath_var" = "x"; then
+            shlibpath_var=REPLACE_WITH_YOUR_SHLIBPATH_VAR
+        fi
     else
     dnl libtoolize requires that the following not be indented
 AC_PROG_LIBTOOL

Modified: apr/apr/branches/1.0.x/file_io/netware/mktemp.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/netware/mktemp.c	(original)
+++ apr/apr/branches/1.0.x/file_io/netware/mktemp.c	Tue Nov 16 17:07:02 2004
@@ -27,7 +27,7 @@
     apr_status_t rv;
 
     flags = (!flags) ? APR_CREATE | APR_READ | APR_WRITE |  
-                       APR_DELONCLOSE : flags;
+                       APR_DELONCLOSE : flags & ~APR_EXCL;
 
     fd = mkstemp(template);
     if (fd == -1) {

Modified: apr/apr/branches/1.0.x/file_io/os2/filesys.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/os2/filesys.c	(original)
+++ apr/apr/branches/1.0.x/file_io/os2/filesys.c	Tue Nov 16 17:07:02 2004
@@ -94,12 +94,13 @@
 
 apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p)
 {
-    char path[APR_PATH_MAX];
-
-    strcpy(path, root);
-    if (path[1] == ':')
-        path[0] = apr_toupper(path[0]);
-    *rootpath = apr_pstrdup(p, path);
+    if (root[0] && apr_islower(root[0]) && root[1] == ':') {
+        *rootpath = apr_pstrdup(p, root);
+        (*rootpath)[0] = apr_toupper((*rootpath)[0]);
+    }
+    else {
+       *rootpath = root;
+    }
     return APR_SUCCESS;
 }
 

Modified: apr/apr/branches/1.0.x/file_io/unix/readwrite.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/unix/readwrite.c	(original)
+++ apr/apr/branches/1.0.x/file_io/unix/readwrite.c	Tue Nov 16 17:07:02 2004
@@ -24,9 +24,6 @@
 #define USE_WAIT_FOR_IO
 #endif
 
-/* problems: 
- * 1) ungetchar not used for buffered files
- */
 APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
 {
     apr_ssize_t rv;
@@ -311,18 +308,65 @@
         return APR_SUCCESS;
     }
 
-    while (str < final) { /* leave room for trailing '\0' */
-        nbytes = 1;
-        rv = apr_file_read(thefile, str, &nbytes);
-        if (rv != APR_SUCCESS) {
-            break;
+    /* If we have an underlying buffer, we can be *much* more efficient
+     * and skip over the apr_file_read calls.
+     */
+    if (thefile->buffered) {
+
+#if APR_HAS_THREADS
+        if (thefile->thlock) {
+            apr_thread_mutex_lock(thefile->thlock);
+        }
+#endif
+
+        if (thefile->direction == 1) {
+            apr_file_flush(thefile);
+            thefile->direction = 0;
+            thefile->bufpos = 0;
+            thefile->dataRead = 0;
+        }
+
+        while (str < final) { /* leave room for trailing '\0' */
+            /* Force ungetc leftover to call apr_file_read. */
+            if (thefile->bufpos < thefile->dataRead &&
+                thefile->ungetchar == -1) {
+                *str = thefile->buffer[thefile->bufpos++];
+            }
+            else {
+                nbytes = 1;
+                rv = apr_file_read(thefile, str, &nbytes);
+                if (rv != APR_SUCCESS) {
+                    break;
+                }
+            }
+            if (*str == '\n') {
+                ++str;
+                break;
+            }
+            ++str;
         }
-        if (*str == '\n') {
+
+#if APR_HAS_THREADS
+        if (thefile->thlock) {
+            apr_thread_mutex_unlock(thefile->thlock);
+        }
+#endif
+    }
+    else {
+        while (str < final) { /* leave room for trailing '\0' */
+            nbytes = 1;
+            rv = apr_file_read(thefile, str, &nbytes);
+            if (rv != APR_SUCCESS) {
+                break;
+            }
+            if (*str == '\n') {
+                ++str;
+                break;
+            }
             ++str;
-            break;
         }
-        ++str;
     }
+
     /* We must store a terminating '\0' if we've stored any chars. We can
      * get away with storing it if we hit an error first. 
      */

Modified: apr/apr/branches/1.0.x/file_io/win32/dir.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/win32/dir.c	(original)
+++ apr/apr/branches/1.0.x/file_io/win32/dir.c	Tue Nov 16 17:07:02 2004
@@ -49,7 +49,7 @@
 {
     apr_status_t rv;
 
-    int len = strlen(dirname);
+    apr_size_t len = strlen(dirname);
     (*new) = apr_pcalloc(pool, sizeof(apr_dir_t));
     /* Leave room here to add and pop the '*' wildcard for FindFirstFile 
      * and double-null terminate so we have one character to change.
@@ -243,7 +243,7 @@
 #else
             char fspec[APR_PATH_MAX];
 #endif
-            int dirlen = strlen(thedir->dirname);
+            apr_size_t dirlen = strlen(thedir->dirname);
             if (dirlen >= sizeof(fspec))
                 dirlen = sizeof(fspec) - 1;
             apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));

Modified: apr/apr/branches/1.0.x/file_io/win32/filedup.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/win32/filedup.c	(original)
+++ apr/apr/branches/1.0.x/file_io/win32/filedup.c	Tue Nov 16 17:07:02 2004
@@ -44,6 +44,13 @@
     (*new_file)->buffered = FALSE;
     (*new_file)->ungetchar = old_file->ungetchar;
 
+#if APR_HAS_THREADS
+    if (old_file->mutex) {
+        apr_thread_mutex_create(&((*new_file)->mutex),
+                                APR_THREAD_MUTEX_DEFAULT, p);
+    }
+#endif
+
     apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file), file_cleanup,
                         apr_pool_cleanup_null);
 
@@ -117,6 +124,13 @@
     new_file->append = old_file->append;
     new_file->buffered = FALSE;
     new_file->ungetchar = old_file->ungetchar;
+
+#if APR_HAS_THREADS
+    if (old_file->mutex) {
+        apr_thread_mutex_create(&(new_file->mutex),
+                                APR_THREAD_MUTEX_DEFAULT, p);
+    }
+#endif
 
     return APR_SUCCESS;
 #endif /* !defined(_WIN32_WCE) */

Modified: apr/apr/branches/1.0.x/file_io/win32/open.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/win32/open.c	(original)
+++ apr/apr/branches/1.0.x/file_io/win32/open.c	Tue Nov 16 17:07:02 2004
@@ -47,7 +47,7 @@
      * Note that the \\?\ form only works for local drive paths, and
      * \\?\UNC\ is needed UNC paths.
      */
-    int srcremains = strlen(srcstr) + 1;
+    apr_size_t srcremains = strlen(srcstr) + 1;
     apr_wchar_t *t = retstr;
     apr_status_t rv;
 
@@ -101,7 +101,7 @@
      * then transform \\'s back into /'s since the \\?\ form never
      * allows '/' path seperators, and APR always uses '/'s.
      */
-    int srcremains = wcslen(srcstr) + 1;
+    apr_size_t srcremains = wcslen(srcstr) + 1;
     apr_status_t rv;
     char *t = retstr;
     if (srcstr[0] == L'\\' && srcstr[1] == L'\\' && 
@@ -324,6 +324,8 @@
         else {
             return APR_EACCES;
         }
+        if (flag & APR_READCONTROL)
+            oflags |= READ_CONTROL;
     }
 
     if (flag & APR_XTHREAD) {

Modified: apr/apr/branches/1.0.x/file_io/win32/readwrite.c
==============================================================================
--- apr/apr/branches/1.0.x/file_io/win32/readwrite.c	(original)
+++ apr/apr/branches/1.0.x/file_io/win32/readwrite.c	Tue Nov 16 17:07:02 2004
@@ -27,9 +27,10 @@
  * read_with_timeout() 
  * Uses async i/o to emulate unix non-blocking i/o with timeouts.
  */
-static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len, apr_size_t *nbytes)
+static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
 {
     apr_status_t rv;
+    DWORD len = (DWORD)len_in;
     *nbytes = 0;
 
     /* Handle the zero timeout non-blocking case */
@@ -68,7 +69,8 @@
         file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
     }
 
-    rv = ReadFile(file->filehand, buf, len, nbytes, file->pOverlapped);
+    *nbytes = 0;
+    rv = ReadFile(file->filehand, buf, len, (LPDWORD)nbytes, file->pOverlapped);
 
     if (!rv) {
         rv = apr_get_os_error();
@@ -85,7 +87,7 @@
             switch (rv) {
             case WAIT_OBJECT_0:
                 GetOverlappedResult(file->filehand, file->pOverlapped, 
-                                    nbytes, TRUE);
+                                    (LPDWORD)nbytes, TRUE);
                 rv = APR_SUCCESS;
                 break;
             case WAIT_TIMEOUT:
@@ -286,7 +288,7 @@
                 thefile->pOverlapped->Offset     = (DWORD)thefile->filePtr;
                 thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
             }
-            rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
                            thefile->pOverlapped);
             if (thefile->append) {
                 apr_file_unlock(thefile);
@@ -294,7 +296,7 @@
             }
         }
         else {
-            rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+            rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
                            thefile->pOverlapped);
         }
         if (rv) {
@@ -309,7 +311,7 @@
                 rv = WaitForSingleObject(thefile->pOverlapped->hEvent, INFINITE);
                 switch (rv) {
                     case WAIT_OBJECT_0:
-                        GetOverlappedResult(thefile->filehand, thefile->pOverlapped, nbytes, TRUE);
+                        GetOverlappedResult(thefile->filehand, thefile->pOverlapped, (LPDWORD)nbytes, TRUE);
                         rv = APR_SUCCESS;
                         break;
                     case WAIT_TIMEOUT:
@@ -343,7 +345,7 @@
 {
     apr_status_t rv = APR_SUCCESS;
     apr_size_t i;
-    DWORD bwrote = 0;
+    apr_size_t bwrote = 0;
     char *buf;
 
     *nbytes = 0;
@@ -361,7 +363,7 @@
 
 APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
 {
-    DWORD len = 1;
+    apr_size_t len = 1;
 
     return apr_file_write(thefile, &ch, &len);
 }
@@ -375,7 +377,7 @@
 APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
 {
     apr_status_t rc;
-    int bread;
+    apr_size_t bread;
 
     bread = 1;
     rc = apr_file_read(thefile, ch, &bread);
@@ -393,7 +395,7 @@
 
 APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
 {
-    DWORD len = strlen(str);
+    apr_size_t len = strlen(str);
 
     return apr_file_write(thefile, str, &len);
 }
@@ -431,13 +433,34 @@
 APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
 {
     if (thefile->buffered) {
-        DWORD written = 0;
+        DWORD numbytes, written = 0;
         apr_status_t rc = 0;
+        char *buffer;
+        apr_size_t bytesleft;
 
         if (thefile->direction == 1 && thefile->bufpos) {
-            if (!WriteFile(thefile->filehand, thefile->buffer, thefile->bufpos, &written, NULL))
-                rc = apr_get_os_error();
-            thefile->filePtr += written;
+            buffer = thefile->buffer;
+            bytesleft = thefile->bufpos;           
+
+            do {
+                if (bytesleft > APR_DWORD_MAX) {
+                    numbytes = APR_DWORD_MAX;
+                }
+                else {
+                    numbytes = (DWORD)bytesleft;
+                }
+
+                if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
+                    rc = apr_get_os_error();
+                    thefile->filePtr += written;
+                    break;
+                }
+
+                thefile->filePtr += written;
+                bytesleft -= written;
+                buffer += written;
+
+            } while (bytesleft > 0);
 
             if (rc == 0)
                 thefile->bufpos = 0;

Modified: apr/apr/branches/1.0.x/include/apr.hw
==============================================================================
--- apr/apr/branches/1.0.x/include/apr.hw	(original)
+++ apr/apr/branches/1.0.x/include/apr.hw	Tue Nov 16 17:07:02 2004
@@ -363,7 +363,7 @@
 #endif
 
 #ifndef WS2TCPIP_INLINE
-6:09 PM 11/16/2003#define IN6_IS_ADDR_V4MAPPED(a) \
+#define IN6_IS_ADDR_V4MAPPED(a) \
     (   (*(const apr_uint64_t *)(const void *)(&(a)->s6_addr[0]) == 0) \
      && (*(const apr_uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
 #endif

Modified: apr/apr/branches/1.0.x/include/apr_network_io.h
==============================================================================
--- apr/apr/branches/1.0.x/include/apr_network_io.h	(original)
+++ apr/apr/branches/1.0.x/include/apr_network_io.h	Tue Nov 16 17:07:02 2004
@@ -456,7 +456,8 @@
  * @remark
  * <PRE>
  * This functions acts like a blocking write by default.  To change 
- * this behavior, use apr_socket_timeout_set().
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
  *
  * It is possible for both bytes to be sent and an error to be returned.
  *
@@ -475,7 +476,8 @@
  * @remark
  * <PRE>
  * This functions acts like a blocking write by default.  To change 
- * this behavior, use apr_socket_timeout_set().
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
  * The number of bytes actually sent is stored in argument 3.
  *
  * It is possible for both bytes to be sent and an error to be returned.
@@ -526,7 +528,8 @@
  *                       including headers, file, and trailers
  * @param flags APR flags that are mapped to OS specific flags
  * @remark This functions acts like a blocking write by default.  To change 
- *         this behavior, use apr_socket_timeout_set().
+ *         this behavior, use apr_socket_timeout_set() or the
+ *         APR_SO_NONBLOCK socket option.
  *         The number of bytes actually sent is stored in argument 5.
  */
 APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock, 
@@ -547,8 +550,9 @@
  * @remark
  * <PRE>
  * This functions acts like a blocking read by default.  To change 
- * this behavior, use apr_socket_timeout_set().
- * The number of bytes actually sent is stored in argument 3.
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
+ * The number of bytes actually received is stored in argument 3.
  *
  * It is possible for both bytes to be received and an APR_EOF or
  * other error to be returned.
@@ -568,6 +572,11 @@
  *            APR_SO_KEEPALIVE  --  keep connections active
  *            APR_SO_LINGER     --  lingers on close if data is present
  *            APR_SO_NONBLOCK   --  Turns blocking on/off for socket
+ *                                  When this option is enabled, use
+ *                                  the APR_STATUS_IS_EAGAIN() macro to
+ *                                  see if a send or receive function
+ *                                  could not transfer data without
+ *                                  blocking.
  *            APR_SO_REUSEADDR  --  The rules used in validating addresses
  *                                  supplied to bind should allow reuse
  *                                  of local addresses.

Modified: apr/apr/branches/1.0.x/include/apr_shm.h
==============================================================================
--- apr/apr/branches/1.0.x/include/apr_shm.h	(original)
+++ apr/apr/branches/1.0.x/include/apr_shm.h	Tue Nov 16 17:07:02 2004
@@ -114,6 +114,7 @@
  * processes will maintain the same address mapping.
  * @param m The shared memory segment from which to retrieve
  *        the base address.
+ * @return address, aligned by APR_ALIGN_DEFAULT.
  */
 APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m);
 

Modified: apr/apr/branches/1.0.x/include/apr_version.h
==============================================================================
--- apr/apr/branches/1.0.x/include/apr_version.h	(original)
+++ apr/apr/branches/1.0.x/include/apr_version.h	Tue Nov 16 17:07:02 2004
@@ -60,8 +60,13 @@
 #define APR_MINOR_VERSION       0
 
 /** patch level */
-#define APR_PATCH_VERSION       0
+#define APR_PATCH_VERSION       1
 
+/**
+ * This symbol is defined for internal, "development" copies of APR.
+ * This symbol should be #undef'd for releases.
+ */
+#define APR_IS_DEV_VERSION
 
 /** The formatted string of APR's version */
 #define APR_VERSION_STRING \

Modified: apr/apr/branches/1.0.x/include/arch/apr_private_common.h
==============================================================================
--- apr/apr/branches/1.0.x/include/arch/apr_private_common.h	(original)
+++ apr/apr/branches/1.0.x/include/arch/apr_private_common.h	Tue Nov 16 17:07:02 2004
@@ -33,4 +33,9 @@
                                           char separator,
                                           apr_pool_t *p);
 
+/* temporary defines to handle 64bit compile mismatches */
+#define APR_INT_TRUNC_CAST    int
+#define APR_UINT32_TRUNC_CAST apr_uint32_t
+#define APR_UINT32_MAX        0xFFFFFFFFUL
+
 #endif  /*APR_PRIVATE_COMMON_H*/

Modified: apr/apr/branches/1.0.x/include/arch/netware/apr_private.h
==============================================================================
--- apr/apr/branches/1.0.x/include/arch/netware/apr_private.h	(original)
+++ apr/apr/branches/1.0.x/include/arch/netware/apr_private.h	Tue Nov 16 17:07:02 2004
@@ -63,6 +63,8 @@
 #define HAVE_SETENV     1
 #define HAVE_UNSETENV   1
 
+#define HAVE_WRITEV     1
+
 /* 64-bit integer conversion function */
 #define APR_INT64_STRFN	      strtoll
 
@@ -171,6 +173,9 @@
 #else
 #define APR_OFF_T_STRFN       strtol
 #endif
+
+/* used to check DWORD overflow for 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
 
 /*
  * Include common private declarations.

Modified: apr/apr/branches/1.0.x/include/arch/win32/apr_arch_threadproc.h
==============================================================================
--- apr/apr/branches/1.0.x/include/arch/win32/apr_arch_threadproc.h	(original)
+++ apr/apr/branches/1.0.x/include/arch/win32/apr_arch_threadproc.h	Tue Nov 16 17:07:02 2004
@@ -54,6 +54,8 @@
     char *currdir;
     apr_int32_t cmdtype;
     apr_int32_t detached;
+    apr_child_errfn_t *errfn;
+    apr_int32_t errchk;
 };
 
 struct apr_thread_once_t {

Modified: apr/apr/branches/1.0.x/include/arch/win32/apr_private.h
==============================================================================
--- apr/apr/branches/1.0.x/include/arch/win32/apr_private.h	(original)
+++ apr/apr/branches/1.0.x/include/arch/win32/apr_private.h	Tue Nov 16 17:07:02 2004
@@ -158,6 +158,9 @@
 #define APR_OFF_T_STRFN         strtoi
 #endif
 
+/* used to check for DWORD overflow in 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
+
 /*
  * Include common private declarations.
  */

Modified: apr/apr/branches/1.0.x/memory/unix/apr_pools.c
==============================================================================
--- apr/apr/branches/1.0.x/memory/unix/apr_pools.c	(original)
+++ apr/apr/branches/1.0.x/memory/unix/apr_pools.c	Tue Nov 16 17:07:02 2004
@@ -139,9 +139,10 @@
 }
 
 APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
-                                             apr_size_t size)
+                                             apr_size_t in_size)
 {
     apr_uint32_t max_free_index;
+    apr_uint32_t size = (APR_UINT32_TRUNC_CAST)in_size;
 
 #if APR_HAS_THREADS
     apr_thread_mutex_t *mutex;
@@ -168,7 +169,8 @@
 apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t size)
 {
     apr_memnode_t *node, **ref;
-    apr_uint32_t i, index, max_index;
+    apr_uint32_t max_index;
+    apr_size_t i, index;
 
     /* Round up the block size to the next boundary, but always
      * allocate at least a certain size (MIN_ALLOC).
@@ -181,6 +183,10 @@
      * dividing its size by the boundary size
      */
     index = (size >> BOUNDARY_INDEX) - 1;
+    
+    if (index > APR_UINT32_MAX) {
+        return NULL;
+    }
 
     /* First see if there are any nodes in the area we know
      * our node will fit into.
@@ -293,7 +299,7 @@
         return NULL;
 
     node->next = NULL;
-    node->index = index;
+    node->index = (APR_UINT32_TRUNC_CAST)index;
     node->first_avail = (char *)node + APR_MEMNODE_T_SIZE;
     node->endp = (char *)node + size;
 
@@ -582,7 +588,7 @@
 {
     apr_memnode_t *active, *node;
     void *mem;
-    apr_uint32_t free_index;
+    apr_size_t free_index;
 
     size = APR_ALIGN_DEFAULT(size);
     active = pool->active;
@@ -620,7 +626,7 @@
     free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
                             BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
 
-    active->free_index = free_index;
+    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
     node = active->next;
     if (free_index >= node->free_index)
         return mem;
@@ -877,7 +883,7 @@
     apr_size_t cur_len, size;
     char *strp;
     apr_pool_t *pool;
-    apr_uint32_t free_index;
+    apr_size_t free_index;
 
     pool = ps->pool;
     active = ps->node;
@@ -907,7 +913,7 @@
         free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
                                 BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
 
-        active->free_index = free_index;
+        active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
         node = active->next;
         if (free_index < node->free_index) {
             do {
@@ -948,7 +954,7 @@
     char *strp;
     apr_size_t size;
     apr_memnode_t *active, *node;
-    apr_uint32_t free_index;
+    apr_size_t free_index;
 
     ps.node = active = pool->active;
     ps.pool = pool;
@@ -1008,7 +1014,7 @@
     free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
                             BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
 
-    active->free_index = free_index;
+    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
     node = active->next;
 
     if (free_index >= node->free_index)

Modified: apr/apr/branches/1.0.x/misc/unix/charset.c
==============================================================================
--- apr/apr/branches/1.0.x/misc/unix/charset.c	(original)
+++ apr/apr/branches/1.0.x/misc/unix/charset.c	Tue Nov 16 17:07:02 2004
@@ -55,7 +55,7 @@
     }
 
     if ('A' == 0x41) {
-        return "ISO8859-1"; /* not necessarily true */
+        return "ISO-8859-1"; /* not necessarily true */
     }
 
     return "unknown";

Modified: apr/apr/branches/1.0.x/misc/unix/errorcodes.c
==============================================================================
--- apr/apr/branches/1.0.x/misc/unix/errorcodes.c	(original)
+++ apr/apr/branches/1.0.x/misc/unix/errorcodes.c	Tue Nov 16 17:07:02 2004
@@ -374,7 +374,13 @@
     sprintf(err, "Native Error #%d", statcode);
     return stuffbuffer(buf, bufsize, err);
 #else
-    return stuffbuffer(buf, bufsize, strerror(statcode));
+    const char *err = strerror(statcode);
+    if (err) {
+        return stuffbuffer(buf, bufsize, err);
+    } else {
+        return stuffbuffer(buf, bufsize, 
+                           "APR does not understand this error code");
+    }
 #endif
 }
 #endif

Modified: apr/apr/branches/1.0.x/network_io/win32/sendrecv.c
==============================================================================
--- apr/apr/branches/1.0.x/network_io/win32/sendrecv.c	(original)
+++ apr/apr/branches/1.0.x/network_io/win32/sendrecv.c	Tue Nov 16 17:07:02 2004
@@ -43,7 +43,7 @@
     int lasterror;
     DWORD dwBytes = 0;
 
-    wsaData.len = *len;
+    wsaData.len = (u_long)*len;
     wsaData.buf = (char*) buf;
 
 #ifndef _WIN32_WCE
@@ -72,7 +72,7 @@
     DWORD dwBytes = 0;
     DWORD flags = 0;
 
-    wsaData.len = *len;
+    wsaData.len = (u_long)*len;
     wsaData.buf = (char*) buf;
 
 #ifndef _WIN32_WCE
@@ -94,21 +94,49 @@
 
 APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
                                            const struct iovec *vec,
-                                           apr_int32_t nvec, apr_size_t *nbytes)
+                                           apr_int32_t in_vec, apr_size_t *nbytes)
 {
     apr_status_t rc = APR_SUCCESS;
     apr_ssize_t rv;
-    int i;
+    apr_size_t cur_len;
+    apr_int32_t nvec = 0;
+    int i, j = 0;
     DWORD dwBytes = 0;
-    WSABUF *pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
-                                                : malloc(sizeof(WSABUF) * (nvec));
+    WSABUF *pWsaBuf;
 
+    for (i = 0; i < in_vec; i++) {
+        cur_len = vec[i].iov_len;
+        nvec++;
+        while (cur_len > APR_DWORD_MAX) {
+            nvec++;
+            cur_len -= APR_DWORD_MAX;
+        } 
+    }
+
+    pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
+                                         : malloc(sizeof(WSABUF) * (nvec));
     if (!pWsaBuf)
         return APR_ENOMEM;
 
-    for (i = 0; i < nvec; i++) {
-        pWsaBuf[i].buf = vec[i].iov_base;
-        pWsaBuf[i].len = vec[i].iov_len;
+    for (i = 0; i < in_vec; i++) {
+        char * base = vec[i].iov_base;
+        cur_len = vec[i].iov_len;
+        
+        do {
+            if (cur_len > APR_DWORD_MAX) {
+                pWsaBuf[j].buf = base;
+                pWsaBuf[j].len = APR_DWORD_MAX;
+                cur_len -= APR_DWORD_MAX;
+                base += APR_DWORD_MAX;
+            }
+            else {
+                pWsaBuf[j].buf = base;
+                pWsaBuf[j].len = (DWORD)cur_len;
+                cur_len = 0;
+            }
+            j++;
+
+        } while (cur_len > 0);
     }
 #ifndef _WIN32_WCE
     rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL);
@@ -140,7 +168,7 @@
 {
     apr_ssize_t rv;
 
-    rv = sendto(sock->socketdes, buf, (*len), flags, 
+    rv = sendto(sock->socketdes, buf, (int)*len, flags, 
                 (const struct sockaddr*)&where->sa, 
                 where->salen);
     if (rv == SOCKET_ERROR) {
@@ -160,7 +188,7 @@
 {
     apr_ssize_t rv;
 
-    rv = recvfrom(sock->socketdes, buf, (*len), flags, 
+    rv = recvfrom(sock->socketdes, buf, (int)*len, flags, 
                   (struct sockaddr*)&from->sa, &from->salen);
     if (rv == SOCKET_ERROR) {
         (*len) = 0;
@@ -225,13 +253,13 @@
                                               apr_int32_t flags) 
 {
     apr_status_t status = APR_SUCCESS;
-    apr_ssize_t rv;
+    apr_status_t rv;
     apr_off_t curoff = *offset;
     DWORD dwFlags = 0;
-    DWORD nbytes;
+    apr_size_t nbytes;
     TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL;
     int ptr = 0;
-    int bytes_to_send;   /* Bytes to send out of the file (not including headers) */
+    apr_size_t bytes_to_send;   /* Bytes to send out of the file (not including headers) */
     int disconnected = 0;
     int sendv_trailers = 0;
     char hdtrbuf[4096];
@@ -267,11 +295,15 @@
 
     /* Collapse the headers into a single buffer */
     if (hdtr && hdtr->numheaders) {
+        apr_size_t head_length = tfb.HeadLength;
         ptfb = &tfb;
         nbytes = 0;
-        rv = collapse_iovec((char **)&ptfb->Head, &ptfb->HeadLength, 
+        rv = collapse_iovec((char **)&ptfb->Head, &head_length, 
                             hdtr->headers, hdtr->numheaders, 
                             hdtrbuf, sizeof(hdtrbuf));
+
+        tfb.HeadLength = (DWORD)head_length;
+
         /* If not enough buffer, punt to sendv */
         if (rv == APR_INCOMPLETE) {
             rv = apr_socket_sendv(sock, hdtr->headers, hdtr->numheaders, &nbytes);
@@ -289,19 +321,25 @@
         sock->overlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
     }
     while (bytes_to_send) {
+        DWORD xmitbytes;
+
         if (bytes_to_send > MAX_SEGMENT_SIZE) {
-            nbytes = MAX_SEGMENT_SIZE;
+            xmitbytes = MAX_SEGMENT_SIZE;
         }
         else {
             /* Last call to TransmitFile() */
-            nbytes = bytes_to_send;
+            xmitbytes = (DWORD)bytes_to_send;
             /* Collapse the trailers into a single buffer */
             if (hdtr && hdtr->numtrailers) {
+                apr_size_t tail_length = tfb.TailLength;
                 ptfb = &tfb;
-                rv = collapse_iovec((char**) &ptfb->Tail, &ptfb->TailLength,
+                rv = collapse_iovec((char**) &ptfb->Tail, &tail_length,
                                     hdtr->trailers, hdtr->numtrailers,
                                     hdtrbuf + ptfb->HeadLength,
                                     sizeof(hdtrbuf) - ptfb->HeadLength);
+
+                tfb.TailLength = (DWORD)tail_length;
+
                 if (rv == APR_INCOMPLETE) {
                     /* If not enough buffer, punt to sendv, later */
                     sendv_trailers = 1;
@@ -323,7 +361,7 @@
         /* XXX BoundsChecker claims dwFlags must not be zero. */
         rv = TransmitFile(sock->socketdes,  /* socket */
                           file->filehand, /* open file descriptor of the file to be sent */
-                          nbytes,         /* number of bytes to send. 0=send all */
+                          xmitbytes,      /* number of bytes to send. 0=send all */
                           0,              /* Number of bytes per send. 0=use default */
                           sock->overlapped,    /* OVERLAPPED structure */
                           ptfb,           /* header and trailer buffers */
@@ -341,7 +379,7 @@
                     if (!disconnected) {
                         if (!WSAGetOverlappedResult(sock->socketdes,
                                                     sock->overlapped,
-                                                    &nbytes,
+                                                    &xmitbytes,
                                                     FALSE,
                                                     &dwFlags)) {
                             status = apr_get_netos_error();
@@ -351,7 +389,7 @@
                          * tracks bytes sent out of the file.
                          */
                         else if (ptfb) {
-                            nbytes -= (ptfb->HeadLength + ptfb->TailLength);
+                            xmitbytes -= (ptfb->HeadLength + ptfb->TailLength);
                         }
                     }
                 }
@@ -374,9 +412,9 @@
         if (status != APR_SUCCESS)
             break;
 
-        bytes_to_send -= nbytes;
-        curoff += nbytes;
-        *len += nbytes;
+        bytes_to_send -= xmitbytes;
+        curoff += xmitbytes;
+        *len += xmitbytes;
         /* Adjust len for any headers/trailers sent */
         if (ptfb) {
             *len += (ptfb->HeadLength + ptfb->TailLength);

Modified: apr/apr/branches/1.0.x/poll/unix/poll.c
==============================================================================
--- apr/apr/branches/1.0.x/poll/unix/poll.c	(original)
+++ apr/apr/branches/1.0.x/poll/unix/poll.c	Tue Nov 16 17:07:02 2004
@@ -50,7 +50,9 @@
         rv |= APR_POLLIN;
     if (event & EVFILT_WRITE)
         rv |= APR_POLLOUT;
-    if (flags & EV_ERROR || flags & EV_EOF)
+    if (flags & EV_EOF)
+        rv |= APR_POLLHUP;
+    if (flags & EV_ERROR)
         rv |= APR_POLLERR;
 
     return rv;

Modified: apr/apr/branches/1.0.x/random/unix/apr_random.c
==============================================================================
--- apr/apr/branches/1.0.x/random/unix/apr_random.c	(original)
+++ apr/apr/branches/1.0.x/random/unix/apr_random.c	Tue Nov 16 17:07:02 2004
@@ -111,8 +111,8 @@
                     /2)*g->pool_hash->size*2;
     g->reseed_size = APR_RANDOM_DEFAULT_RESEED_SIZE;
 
-    g->H = apr_palloc(p,H_size(g));
-    g->H_waiting = apr_palloc(p,H_size(g));
+    g->H = apr_pcalloc(p,H_size(g));
+    g->H_waiting = apr_pcalloc(p,H_size(g));
 
     g->randomness = apr_palloc(p,B_size(g));
     g->random_bytes = 0;

Modified: apr/apr/branches/1.0.x/shmem/unix/shm.c
==============================================================================
--- apr/apr/branches/1.0.x/shmem/unix/shm.c	(original)
+++ apr/apr/branches/1.0.x/shmem/unix/shm.c	Tue Nov 16 17:07:02 2004
@@ -385,20 +385,28 @@
      * exist before calling ftok(). */
     shmkey = ftok(filename, 1);
     if (shmkey == (key_t)-1) {
-        return errno;
+        goto shm_remove_failed;
     }
 
+    apr_file_close(file);
+
     if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) < 0) {
-        return errno;
+        goto shm_remove_failed;
     }
 
     /* Indicate that the segment is to be destroyed as soon
      * as all processes have detached. This also disallows any
      * new attachments to the segment. */
     if (shmctl(shmid, IPC_RMID, NULL) == -1) {
-        return errno;
+        goto shm_remove_failed;
     }
     return apr_file_remove(filename, pool);
+
+shm_remove_failed:
+    status = errno;
+    /* ensure the file has been removed anyway. */
+    apr_file_remove(filename, pool);
+    return status;
 #endif
 
     /* No support for anonymous shm */

Modified: apr/apr/branches/1.0.x/tables/apr_hash.c
==============================================================================
--- apr/apr/branches/1.0.x/tables/apr_hash.c	(original)
+++ apr/apr/branches/1.0.x/tables/apr_hash.c	Tue Nov 16 17:07:02 2004
@@ -73,6 +73,7 @@
     apr_hash_index_t     iterator;  /* For apr_hash_first(NULL, ...) */
     unsigned int         count, max;
     apr_hashfunc_t       hash_func;
+    apr_hash_entry_t    *free;  /* List of recycled entries */
 };
 
 #define INITIAL_MAX 15 /* tunable == 2^n - 1 */
@@ -92,6 +93,7 @@
     apr_hash_t *ht;
     ht = apr_palloc(pool, sizeof(apr_hash_t));
     ht->pool = pool;
+    ht->free = NULL;
     ht->count = 0;
     ht->max = INITIAL_MAX;
     ht->array = alloc_array(ht, ht->max);
@@ -264,7 +266,10 @@
         return hep;
 
     /* add a new entry for non-NULL values */
-    he = apr_palloc(ht->pool, sizeof(*he));
+    if ((he = ht->free) != NULL)
+        ht->free = he->next;
+    else
+        he = apr_palloc(ht->pool, sizeof(*he));
     he->next = NULL;
     he->hash = hash;
     he->key  = key;
@@ -286,6 +291,7 @@
                     sizeof(*ht->array) * (orig->max + 1) +
                     sizeof(apr_hash_entry_t) * orig->count);
     ht->pool = pool;
+    ht->free = NULL;
     ht->count = orig->count;
     ht->max = orig->max;
     ht->hash_func = orig->hash_func;
@@ -333,7 +339,10 @@
     if (*hep) {
         if (!val) {
             /* delete entry */
+            apr_hash_entry_t *old = *hep;
             *hep = (*hep)->next;
+            old->next = ht->free;
+            ht->free = old;
             --ht->count;
         }
         else {
@@ -396,6 +405,7 @@
 
     res = apr_palloc(p, sizeof(apr_hash_t));
     res->pool = p;
+    res->free = NULL;
     res->hash_func = base->hash_func;
     res->count = base->count;
     res->max = (overlay->max > base->max) ? overlay->max : base->max;

Modified: apr/apr/branches/1.0.x/test/Makefile.in
==============================================================================
--- apr/apr/branches/1.0.x/test/Makefile.in	(original)
+++ apr/apr/branches/1.0.x/test/Makefile.in	Tue Nov 16 17:07:02 2004
@@ -29,7 +29,8 @@
 LOCAL_LIBS=../lib@APR_LIBNAME@.la
 
 CLEAN_TARGETS = testfile.tmp mod_test.slo proc_child@EXEEXT@ occhild@EXEEXT@ \
-readchild@EXEEXT@ tryread@EXEEXT@ sockchid@EXEEXT@
+	readchild@EXEEXT@ tryread@EXEEXT@ sockchild@EXEEXT@ \
+	globalmutexchild@EXEEXT@ lfstests/large.bin
 CLEAN_SUBDIRS = internal
 
 INCDIR=../include

Modified: apr/apr/branches/1.0.x/test/Makefile.win
==============================================================================
--- apr/apr/branches/1.0.x/test/Makefile.win	(original)
+++ apr/apr/branches/1.0.x/test/Makefile.win	Tue Nov 16 17:07:02 2004
@@ -6,7 +6,8 @@
 	sendfile.exe \
 	proc_child.exe \
         tryread.exe \
-	occhild.exe\
+	occhild.exe \
+	readchild.exe \
 	sockchild.exe \
 	testlockperf.exe \
 	testshmproducer.exe \
@@ -39,6 +40,9 @@
 
 occhild.exe: occhild.obj $(LOCAL_LIBS)
 	$(LINK) occhild.obj $(LOCAL_LIBS) $(ALL_LIBS)
+
+readchild.exe: readchild.obj $(LOCAL_LIBS)
+	$(LINK) readchild.obj $(LOCAL_LIBS) $(ALL_LIBS)
 
 proc_child.exe: proc_child.obj $(LOCAL_LIBS)
 	$(LINK) /debug /subsystem:console /machine:I386 \

Modified: apr/apr/branches/1.0.x/test/testrand2.c
==============================================================================
--- apr/apr/branches/1.0.x/test/testrand2.c	(original)
+++ apr/apr/branches/1.0.x/test/testrand2.c	Tue Nov 16 17:07:02 2004
@@ -1,55 +1,16 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
+/* Copyright 2000-2004 The Apache Software Foundation
  *
- * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 #include "apr_general.h"

Modified: apr/apr/branches/1.0.x/test/teststr.c
==============================================================================
--- apr/apr/branches/1.0.x/test/teststr.c	(original)
+++ apr/apr/branches/1.0.x/test/teststr.c	Tue Nov 16 17:07:02 2004
@@ -150,6 +150,7 @@
 static void string_error(abts_case *tc, void *data)
 {
      char buf[128], *rv;
+     apr_status_t n;
 
      buf[0] = '\0';
      rv = apr_strerror(APR_ENOENT, buf, sizeof buf);
@@ -159,6 +160,11 @@
      rv = apr_strerror(APR_TIMEUP, buf, sizeof buf);
      ABTS_PTR_EQUAL(tc, buf, rv);
      ABTS_STR_EQUAL(tc, "The timeout specified has expired", buf);
+     
+     /* throw some randomish numbers at it to check for robustness */
+     for (n = 1; n < 1000000; n *= 2) {
+         apr_strerror(n, buf, sizeof buf);
+     }
 }
 
 #define SIZE 180000

Modified: apr/apr/branches/1.0.x/threadproc/beos/.cvsignore
==============================================================================
--- apr/apr/branches/1.0.x/threadproc/beos/.cvsignore	(original)
+++ apr/apr/branches/1.0.x/threadproc/beos/.cvsignore	Tue Nov 16 17:07:02 2004
@@ -1,5 +1,6 @@
 Makefile
 apr_proc_stub
 *.lo
+*.slo
 .libs
 .deps

Modified: apr/apr/branches/1.0.x/threadproc/win32/proc.c
==============================================================================
--- apr/apr/branches/1.0.x/threadproc/win32/proc.c	(original)
+++ apr/apr/branches/1.0.x/threadproc/win32/proc.c	Tue Nov 16 17:07:02 2004
@@ -245,14 +245,14 @@
 APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
                                                        apr_child_errfn_t *errfn)
 {
-    /* won't ever be called on this platform, so don't save the function pointer */
+    attr->errfn = errfn;
     return APR_SUCCESS;
 }
 
 APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
                                                        apr_int32_t chk)
 {
-    /* won't ever be used on this platform, so don't save the flag */
+    attr->errchk = chk;
     return APR_SUCCESS;
 }
 
@@ -311,6 +311,12 @@
         char *fullpath = NULL;
         if ((rv = apr_filepath_merge(&fullpath, attr->currdir, progname, 
                                      APR_FILEPATH_NATIVE, pool)) != APR_SUCCESS) {
+            if (attr->errfn) {
+                attr->errfn(pool, rv, 
+                            apr_pstrcat(pool, "filepath_merge failed.", 
+                                        " currdir: ", attr->currdir, 
+                                        " progname: ", progname, NULL));
+            }
             return rv;
         }
         progname = fullpath;
@@ -352,6 +358,9 @@
     if (attr->cmdtype == APR_SHELLCMD || attr->cmdtype == APR_SHELLCMD_ENV) {
         char *shellcmd = getenv("COMSPEC");
         if (!shellcmd) {
+            if (attr->errfn) {
+                attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
+            }
             return APR_EINVAL;
         }
         if (shellcmd[0] == '"') {
@@ -388,6 +397,9 @@
         {
             char *shellcmd = getenv("COMSPEC");
             if (!shellcmd) {
+                if (attr->errfn) {
+                    attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
+                }
                 return APR_EINVAL;
             }
             if (shellcmd[0] == '"') {
@@ -479,6 +491,12 @@
                 if ((rv = apr_conv_utf8_to_ucs2(env[i], &in, 
                                                 pNext, &iEnvBlockLen)) 
                         != APR_SUCCESS) {
+                    if (attr->errfn) {
+                        attr->errfn(pool, rv, 
+                                    apr_pstrcat(pool, 
+                                                "utf8 to ucs2 conversion failed" 
+                                                " on this string: ", env[i], NULL));
+                    }
                     return rv;
                 }
                 pNext = wcschr(pNext, L'\0') + 1;
@@ -525,6 +543,12 @@
             wprg = apr_palloc(pool, nwprg * sizeof(wprg[0]));
             if ((rv = apr_conv_utf8_to_ucs2(progname, &nprg, wprg, &nwprg))
                    != APR_SUCCESS) {
+                if (attr->errfn) {
+                    attr->errfn(pool, rv, 
+                                apr_pstrcat(pool, 
+                                            "utf8 to ucs2 conversion failed" 
+                                            " on progname: ", progname, NULL));
+                }
                 return rv;
             }
         }
@@ -535,6 +559,12 @@
             wcmd = apr_palloc(pool, nwcmd * sizeof(wcmd[0]));
             if ((rv = apr_conv_utf8_to_ucs2(cmdline, &ncmd, wcmd, &nwcmd))
                     != APR_SUCCESS) {
+                if (attr->errfn) {
+                    attr->errfn(pool, rv, 
+                                apr_pstrcat(pool, 
+                                            "utf8 to ucs2 conversion failed" 
+                                            " on cmdline: ", cmdline, NULL));
+                }
                 return rv;
             }
         }
@@ -547,6 +577,12 @@
             if ((rv = apr_conv_utf8_to_ucs2(attr->currdir, &ncwd, 
                                             wcwd, &nwcwd))
                     != APR_SUCCESS) {
+                if (attr->errfn) {
+                    attr->errfn(pool, rv, 
+                                apr_pstrcat(pool, 
+                                            "utf8 to ucs2 conversion failed" 
+                                            " on currdir: ", attr->currdir, NULL));
+                }
                 return rv;
             }
         }

Modified: apr/apr/branches/1.0.x/threadproc/win32/thread.c
==============================================================================
--- apr/apr/branches/1.0.x/threadproc/win32/thread.c	(original)
+++ apr/apr/branches/1.0.x/threadproc/win32/thread.c	Tue Nov 16 17:07:02 2004
@@ -85,6 +85,7 @@
 {
     apr_status_t stat;
 	unsigned temp;
+    HANDLE handle;
 
     (*new) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
 
@@ -95,7 +96,7 @@
     (*new)->pool = pool;
     (*new)->data = data;
     (*new)->func = func;
-    
+    (*new)->td   = NULL;
     stat = apr_pool_create(&(*new)->pool, pool);
     if (stat != APR_SUCCESS) {
         return stat;
@@ -105,14 +106,14 @@
      * same size as the calling thread. 
      */
 #ifndef _WIN32_WCE
-    if (((*new)->td = (HANDLE)_beginthreadex(NULL,
+    if ((handle = (HANDLE)_beginthreadex(NULL,
                         attr && attr->stacksize > 0 ? attr->stacksize : 0,
                         (unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
                         (*new), 0, &temp)) == 0) {
         return APR_FROM_OS_ERROR(_doserrno);
     }
 #else
-   if (((*new)->td = CreateThread(NULL,
+   if ((handle = CreateThread(NULL,
                         attr && attr->stacksize > 0 ? attr->stacksize : 0,
                         (unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
                         (*new), 0, &temp)) == 0) {
@@ -120,9 +121,10 @@
     }
 #endif
     if (attr && attr->detach) {
-        CloseHandle((*new)->td);
-        (*new)->td = NULL;
+        CloseHandle(handle);
     }
+    else
+        (*new)->td = handle;
 
     return APR_SUCCESS;
 }
@@ -132,10 +134,8 @@
 {
     thd->exitval = retval;
     apr_pool_destroy(thd->pool);
+    thd->pool = NULL;
 #ifndef _WIN32_WCE
-    if (thd->td) {
-        CloseHandle(thd->td);
-    }
     _endthreadex(0);
 #else
     ExitThread(0);
@@ -146,15 +146,26 @@
 APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
                                           apr_thread_t *thd)
 {
-    apr_status_t rv;
-
+    apr_status_t rv = APR_SUCCESS;
+    
+    if (!thd->td) {
+        /* Can not join on detached threads */
+        return APR_DETACH;
+    }
     rv = WaitForSingleObject(thd->td, INFINITE);
     if ( rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
-        *retval = thd->exitval;
-        return APR_SUCCESS;
-    }
-    /* Wait failed */
-    return apr_get_os_error();;
+        /* If the thread_exit has been called */
+        if (!thd->pool)
+            *retval = thd->exitval;
+        else
+            rv = APR_INCOMPLETE;
+    }
+    else
+        rv = apr_get_os_error();
+    CloseHandle(thd->td);
+    thd->td = NULL;
+
+    return rv;
 }
 
 APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)

Mime
View raw message