[apr] 01/01: Upstream tarball 1.5.2

Stefan Fritsch sf at moszumanska.debian.org
Sat Aug 15 11:19:07 UTC 2015


This is an automated email from the git hooks/post-receive script.

sf pushed a commit to branch upstream
in repository apr.

commit 50c7507712367e3e0b4196daea3baf08d2467b39
Author: Stefan Fritsch <sf at sfritsch.de>
Date:   Sat Aug 15 13:05:43 2015 +0200

    Upstream tarball 1.5.2
---
 CHANGES                     |  63 ++++++-
 CMakeLists.txt              |   9 +-
 Makefile.in                 |   6 +-
 NOTICE                      |   2 +-
 NWGNUmakefile               |   5 +-
 apr.dsp                     |  63 -------
 apr.spec                    |   4 +-
 atomic/win32/apr_atomic.c   |  57 +-----
 build-outputs.mk            |   2 +-
 build/NWGNUenvironment.inc  |  23 ++-
 build/NWGNUmakefile         |  10 +
 build/apr_hints.m4          |   2 +-
 build/config.guess          |  10 +-
 build/config.sub            |  22 ++-
 build/nw_export.inc         |   2 +
 build/rpm/apr.spec.in       |   2 +-
 configure                   |  73 +++++++-
 configure.in                |  35 +++-
 encoding/apr_escape.c       |   2 +
 file_io/win32/pipe.c        |  51 ++++-
 include/apr_skiplist.h      |  16 +-
 include/apr_version.h       |   4 +-
 libapr.dsp                  |  75 +-------
 locks/beos/thread_cond.c    |   3 +-
 locks/unix/proc_mutex.c     |  22 ++-
 memory/unix/apr_pools.c     |  26 +--
 misc/unix/errorcodes.c      |  11 +-
 network_io/unix/sockaddr.c  |  10 +
 network_io/unix/sockets.c   |  34 +++-
 poll/unix/epoll.c           |  45 +++--
 poll/unix/kqueue.c          |  33 +++-
 poll/unix/poll.c            |  30 ++-
 poll/unix/pollcb.c          |   3 +
 poll/unix/port.c            |  33 +++-
 poll/unix/z_asio.c          |  13 +-
 tables/apr_skiplist.c       | 373 +++++++++++++++++++++---------------
 test/Makefile.in            |   2 +-
 test/Makefile.win           |   3 +-
 test/NWGNUaprtest           |   2 +
 test/abts_tests.h           |   3 +-
 test/testatomic.c           |   6 +-
 test/testdll.dsp            |   4 +
 test/testlib.dsp            |   4 +
 test/testpoll.c             |  53 +++++-
 test/testskiplist.c         | 448 ++++++++++++++++++++++++++++++++++++++++++++
 test/testutil.h             |   1 +
 threadproc/netware/thread.c |   8 +-
 47 files changed, 1233 insertions(+), 475 deletions(-)

diff --git a/CHANGES b/CHANGES
index d04ad11..f300ec0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,63 @@
                                                      -*- coding: utf-8 -*-
+Changes for APR 1.5.2
+
+  *) SECURITY: CVE-2015-1829 (cve.mitre.org)
+     APR applications using APR named pipe support on Windows can be 
+     vulnerable to a pipe squatting attack from a local process; the extent
+     of the vulnerability, when present, depends on the application.
+     Initial analysis and report was provided by John Hernandez of Casaba 
+     Security via HP SSRT Security Alert.  [Yann Ylavic]
+
+  *) apr_atomic: Fix errors when building on Visual Studio 2013 while
+     maintaining the ability to build on Visual Studio 6 with Windows
+     Server 2003 R2 SDK. PR 57191. [Gregg Smith]
+
+  *) Switch to generic atomics for early/unpatched Solaris 10 not exporting
+     some atomic functions.  PR 55418.  [Yann Ylavic]
+
+  *) apr_file_mktemp() on HP-UX: Remove limitation of 26 temporary files
+     per process.  PR 57677.  [Jeff Trawick]
+
+  *) apr_escape: Correctly calculate the size of the returned string in
+     apr_escape_path and set the correct return value in case we actually
+     escape the string. [<aduryagin gmail.com>] PR 57230.
+
+  *) pollcb on Windows: Handle calls with no file/socket descriptors.
+     Follow up to PR 49882. [Jeff Trawick, Yann Ylavic]
+
+  *) apr_poll(cb): fix error paths returned values and leaks.  [Yann Ylavic]
+
+  *) apr_thread_cond_*wait() on BeOS: Fix broken logic.  PR 45800.
+     [Jochen Voss (no e-mail)]
+
+  *) apr_skiplist: Optimize the number of allocations by reusing pooled or
+     malloc()ed nodes for the lifetime of the skiplist.  [Yann Ylavic]
+
+  *) apr_skiplist: Fix possible multiple-free() on the same value in
+     apr_skiplist_remove_all().  [Yann Ylavic]
+
+  *) apr_pollset: On z/OS, threadsafe apr_pollset_poll() may return
+     "EDC8102I Operation would block" under load.
+     [Pat Odonnell <patod us.ibm.com>]
+
+  *) On z/OS, apr_sockaddr_info_get() with family == APR_UNSPEC was not 
+     returning IPv4 addresses if any IPv6 addresses were returned. 
+     [Eric Covener]
+
+  *) Windows cmake build: Fix an incompatibility with cmake 2.8.12 and
+     later.  [Jeff Trawick]
+
+  *) apr_global_mutex/apr_proc_mutex: Resolve failures with the 
+     POSIX sem implementation in environments which receive signals.
+     [Jeff Trawick]
+
+  *) apr_skiplist: Fix potential corruption of skiplists leading to 
+     results or crashes. [Takashi Sato <takashi tks st>, Eric Covener]
+     PR 56654.
+
+  *) Improve platform detection by updating config.guess and config.sub.
+     [Rainer Jung]
+
 Changes for APR 1.5.1
 
   *) apr_os_proc_mutex_get() on Unix:  Avoid segfault for cross-
@@ -37,8 +96,8 @@ Changes for APR 1.5.1
   *) Correct a regression in 1.5.0 which affected out-of-tree
      builds on Unix.  [Rainer Jung]
 
-  *) Improve platform detection for bundled expat by updating
-     config.guess and config.sub. [Rainer Jung]
+  *) Improve platform detection by updating config.guess and config.sub.
+     [Rainer Jung]
 
 Changes for APR 1.5.0
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04903f9..75f35c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -234,6 +234,7 @@ SET(APR_TEST_SOURCES
   test/testprocmutex.c
   test/testrand.c
   test/testshm.c
+  test/testskiplist.c
   test/testsleep.c
   test/testsock.c
   test/testsockets.c
@@ -252,7 +253,6 @@ SET(APR_TEST_SOURCES
 
 SET(install_targets)
 SET(install_bin_pdb)
-SET(install_lib_pdb)
 
 # libapr-1 is shared, apr-1 is static
 ADD_LIBRARY(libapr-1 SHARED ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED} libapr.rc)
@@ -264,7 +264,6 @@ ADD_DEPENDENCIES(libapr-1 test_char_header)
 
 ADD_LIBRARY(apr-1 STATIC ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED})
 SET(install_targets ${install_targets} apr-1)
-SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/apr-1.pdb)
 TARGET_LINK_LIBRARIES(apr-1 ${APR_SYSTEM_LIBS})
 SET_TARGET_PROPERTIES(apr-1 PROPERTIES COMPILE_DEFINITIONS "APR_DECLARE_STATIC;WINNT")
 ADD_DEPENDENCIES(apr-1 test_char_header)
@@ -272,12 +271,10 @@ ADD_DEPENDENCIES(apr-1 test_char_header)
 # libaprapp-1 and aprapp-1 are static
 ADD_LIBRARY(libaprapp-1 STATIC misc/win32/apr_app.c misc/win32/internal.c ${APR_PUBLIC_HEADERS_GENERATED})
 SET(install_targets ${install_targets} libaprapp-1)
-SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/libaprapp-1.pdb)
 SET_TARGET_PROPERTIES(libaprapp-1 PROPERTIES COMPILE_DEFINITIONS "APR_APP;WINNT")
 
 ADD_LIBRARY(aprapp-1 STATIC misc/win32/apr_app.c misc/win32/internal.c ${APR_PUBLIC_HEADERS_GENERATED})
 SET(install_targets ${install_targets} aprapp-1)
-SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/aprapp-1.pdb)
 SET_TARGET_PROPERTIES(aprapp-1 PROPERTIES COMPILE_DEFINITIONS "APR_DECLARE_STATIC;APR_APP;WINNT")
 
 IF(APR_BUILD_TESTAPR)
@@ -394,10 +391,6 @@ IF(INSTALL_PDB)
   INSTALL(FILES ${install_bin_pdb}
           DESTINATION bin
           CONFIGURATIONS RelWithDebInfo Debug)
-
-  INSTALL(FILES ${install_lib_pdb}
-          DESTINATION lib
-          CONFIGURATIONS RelWithDebInfo Debug)
 ENDIF()
 
 INSTALL(FILES ${APR_PUBLIC_HEADERS_STATIC} ${APR_PUBLIC_HEADERS_GENERATED} DESTINATION include)
diff --git a/Makefile.in b/Makefile.in
index 6f99733..a2a5194 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -129,11 +129,11 @@ check: $(TARGET_LIB)
 etags:
 	etags `find . -name '*.[ch]'`
 
-make_tools_dir:
+OBJECTS_gen_test_char = tools/gen_test_char.lo $(LOCAL_LIBS)
+tools/gen_test_char.lo: tools/gen_test_char.c
 	$(APR_MKDIR) tools
+	$(LT_COMPILE)
 
-OBJECTS_gen_test_char = tools/gen_test_char.lo $(LOCAL_LIBS)
-tools/gen_test_char.lo: make_tools_dir
 tools/gen_test_char at EXEEXT@: $(OBJECTS_gen_test_char)
 	$(LINK_PROG) $(OBJECTS_gen_test_char) $(ALL_LIBS)
 
diff --git a/NOTICE b/NOTICE
index b16965b..cd3576d 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Portable Runtime
-Copyright (c) 2000-2014 The Apache Software Foundation.
+Copyright (c) 2000-2015 The Apache Software Foundation.
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/NWGNUmakefile b/NWGNUmakefile
index 3f789eb..db15c0d 100644
--- a/NWGNUmakefile
+++ b/NWGNUmakefile
@@ -50,6 +50,7 @@ include $(APR_WORK)/build/NWGNUhead.inc
 #
 XINCDIRS	+= \
 			$(APR)/include \
+			$(APR)/include/private \
 			$(APR)/include/arch/NetWare \
 			$(APR)/include/arch/unix \
 			$(APR)/memory/unix \
@@ -293,11 +294,13 @@ FILES_nlm_exports = \
 FILES_lib_objs = \
 	$(OBJDIR)/apr_atomic.o \
 	$(OBJDIR)/apr_cpystrn.o \
+	$(OBJDIR)/apr_escape.o \
 	$(OBJDIR)/apr_fnmatch.o \
 	$(OBJDIR)/apr_getpass.o \
 	$(OBJDIR)/apr_hash.o \
 	$(OBJDIR)/apr_pools.o \
 	$(OBJDIR)/apr_random.o \
+	$(OBJDIR)/apr_skiplist.o \
 	$(OBJDIR)/apr_snprintf.o \
 	$(OBJDIR)/apr_strings.o \
 	$(OBJDIR)/apr_strnatcmp.o \
@@ -407,7 +410,7 @@ endif
 vpath %.c atomic/netware:strings:tables:passwd:lib:time/unix
 vpath %.c file_io/unix:locks/netware:misc/netware:misc/unix:threadproc/netware
 vpath %.c poll/unix:shmem/unix:support/unix:random/unix
-vpath %.c dso/netware:memory/unix:mmap/unix:user/netware
+vpath %.c dso/netware:memory/unix:mmap/unix:user/netware:encoding
 
 # Use the win32 network_io if Winsock is being used
 ifndef USE_STDSOCKETS
diff --git a/apr.dsp b/apr.dsp
index bbba926..6e25437 100644
--- a/apr.dsp
+++ b/apr.dsp
@@ -907,69 +907,6 @@ SOURCE=.\include\apr_version.h
 # Begin Source File
 
 SOURCE=.\include\apr_want.h
-
-!IF  "$(CFG)" == "apr - Win32 Release"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "apr - Win32 Debug"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "apr - Win32 Release9x"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\9x\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "apr - Win32 Debug9x"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\9x\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "apr - x64 Release"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\x64\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "apr - x64 Debug"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\x64\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ENDIF 
-
 # End Source File
 # End Group
 # End Target
diff --git a/apr.spec b/apr.spec
index b3db167..9761158 100644
--- a/apr.spec
+++ b/apr.spec
@@ -3,7 +3,7 @@
 
 Summary: Apache Portable Runtime library
 Name: apr
-Version: 1.5.1
+Version: 1.5.2
 Release: 1
 License: Apache Software License
 Group: System Environment/Libraries
@@ -76,7 +76,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %doc docs/APRDesign.html docs/canonical_filenames.html
 %doc docs/incomplete_types docs/non_apr_programs
-%doc --parents html
+%doc html
 %{_bindir}/apr*config
 %{_libdir}/libapr-%{aprver}.*a
 %{_libdir}/libapr-%{aprver}.so
diff --git a/atomic/win32/apr_atomic.c b/atomic/win32/apr_atomic.c
index 1ed7df8..e1bc18e 100644
--- a/atomic/win32/apr_atomic.c
+++ b/atomic/win32/apr_atomic.c
@@ -23,33 +23,12 @@ APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p)
     return APR_SUCCESS;
 }
 
-/* 
- * Remapping function pointer type to accept apr_uint32_t's type-safely
- * as the arguments for as our apr_atomic_foo32 Functions
- */
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_fn)
-    (apr_uint32_t volatile *);
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_fn)
-    (apr_uint32_t volatile *, 
-     apr_uint32_t);
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_val_fn)
-    (apr_uint32_t volatile *, 
-     apr_uint32_t, apr_uint32_t);
-typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_ptr_fn)
-    (volatile void **, 
-     void *, const void *);
-typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_fn)
-    (volatile void **,
-     void *);
-
 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);
-#elif defined(__MINGW32__)
-    return InterlockedExchangeAdd((long *)mem, val);
 #else
-    return ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val);
+    return InterlockedExchangeAdd((long *)mem, val);
 #endif
 }
 
@@ -62,10 +41,8 @@ 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);
-#elif defined(__MINGW32__)
-    InterlockedExchangeAdd((long *)mem, -val);
 #else
-    ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, -val);
+    InterlockedExchangeAdd((long *)mem, -val);
 #endif
 }
 
@@ -74,10 +51,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem)
     /* we return old value, win32 returns new value :( */
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     return InterlockedIncrement(mem) - 1;
-#elif defined(__MINGW32__)
-    return InterlockedIncrement((long *)mem) - 1;
 #else
-    return ((apr_atomic_win32_ptr_fn)InterlockedIncrement)(mem) - 1;
+    return InterlockedIncrement((long *)mem) - 1;
 #endif
 }
 
@@ -85,10 +60,8 @@ APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
 {
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     return InterlockedDecrement(mem);
-#elif defined(__MINGW32__)
-    return InterlockedDecrement((long *)mem);
 #else
-    return ((apr_atomic_win32_ptr_fn)InterlockedDecrement)(mem);
+    return InterlockedDecrement((long *)mem);
 #endif
 }
 
@@ -96,10 +69,8 @@ APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
 {
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     InterlockedExchange(mem, val);
-#elif defined(__MINGW32__)
-    InterlockedExchange((long*)mem, val);
 #else
-    ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val);
+    InterlockedExchange((long*)mem, val);
 #endif
 }
 
@@ -113,10 +84,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint3
 {
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     return InterlockedCompareExchange(mem, with, cmp);
-#elif defined(__MINGW32__)
-    return InterlockedCompareExchange((long*)mem, with, cmp);
 #else
-    return ((apr_atomic_win32_ptr_val_val_fn)InterlockedCompareExchange)(mem, with, cmp);
+    return InterlockedCompareExchange((long*)mem, with, cmp);
 #endif
 }
 
@@ -124,11 +93,8 @@ APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const voi
 {
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     return InterlockedCompareExchangePointer((void* volatile*)mem, with, (void*)cmp);
-#elif defined(__MINGW32__)
-    return InterlockedCompareExchangePointer((void**)mem, with, (void*)cmp);
 #else
-    /* Too many VC6 users have stale win32 API files, stub this */
-    return ((apr_atomic_win32_ptr_ptr_ptr_fn)InterlockedCompareExchange)(mem, with, cmp);
+    return InterlockedCompareExchangePointer((void**)mem, with, (void*)cmp);
 #endif
 }
 
@@ -136,19 +102,12 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint
 {
 #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED)
     return InterlockedExchange(mem, val);
-#elif defined(__MINGW32__)
-    return InterlockedExchange((long *)mem, val);
 #else
-    return ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val);
+    return InterlockedExchange((long *)mem, val);
 #endif
 }
 
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
-#if (defined(_M_IA64) || defined(_M_AMD64) || defined(__MINGW32__)) && !defined(RC_INVOKED)
     return InterlockedExchangePointer((void**)mem, with);
-#else
-    /* Too many VC6 users have stale win32 API files, stub this */
-    return ((apr_atomic_win32_ptr_ptr_fn)InterlockedExchange)(mem, with);
-#endif
 }
diff --git a/build-outputs.mk b/build-outputs.mk
index 526f179..275e3ec 100644
--- a/build-outputs.mk
+++ b/build-outputs.mk
@@ -251,7 +251,7 @@ file_io/win32/filestat.lo: file_io/win32/filestat.c .make.dirs include/apr_alloc
 file_io/win32/filesys.lo: file_io/win32/filesys.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_general.h include/apr_pools.h include/apr_strings.h include/apr_thread_mutex.h include/apr_want.h
 file_io/win32/flock.lo: file_io/win32/flock.c .make.dirs 
 file_io/win32/open.lo: file_io/win32/open.c .make.dirs include/apr_allocator.h include/apr_dso.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_global_mutex.h include/apr_inherit.h include/apr_network_io.h include/apr_pools.h include/apr_portable.h include/apr_proc_mutex.h include/apr_shm.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_thread_proc.h include/apr_time.h include/apr_user.h include/apr_want.h
-file_io/win32/pipe.lo: file_io/win32/pipe.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
+file_io/win32/pipe.lo: file_io/win32/pipe.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_escape.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
 file_io/win32/readwrite.lo: file_io/win32/readwrite.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_lib.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
 file_io/win32/seek.lo: file_io/win32/seek.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
 
diff --git a/build/NWGNUenvironment.inc b/build/NWGNUenvironment.inc
index bb58a3a..6f65a16 100644
--- a/build/NWGNUenvironment.inc
+++ b/build/NWGNUenvironment.inc
@@ -141,6 +141,7 @@ CC	= mwccnlm
 CPP	= mwccnlm
 LINK	= mwldnlm
 LIB	= mwldnlm -type library -w nocmdline
+WIN_CC	= mwcc
 
 # Setup build tools
 AWK	= awk
@@ -206,6 +207,20 @@ CLIB3S	= $(METROWERKS)/Novell Support/Metrowerks Support/Libraries/Runtime/mwcrt
 MATH3S	=
 PLIB3S	= $(METROWERKS)/Novell Support/Metrowerks Support/Libraries/MSL C++/MWCPP.lib
 
+ifeq "$(OS)" "Windows_NT"
+# MetroWerks Win32 build flags to create build tools
+MWCW_MSL         = "$(METROWERKS)/MSL"
+MWCW_W32         = "$(METROWERKS)/Win32-x86 Support"
+CC_FOR_BUILD     = $(WIN_CC)
+CFLAGS_FOR_BUILD =  -O2 -gccinc -nodefaults -proc 586 -w off
+CFLAGS_FOR_BUILD += -ir $(MWCW_MSL) -ir $(MWCW_W32) -lr $(MWCW_MSL) -lr $(MWCW_W32)
+CFLAGS_FOR_BUILD += -lMSL_All_x86.lib -lkernel32.lib -luser32.lib
+else
+# GNUC build flags to create build tools
+CC_FOR_BUILD     = gcc
+CFLAGS_FOR_BUILD = -Wall -O2
+endif
+
 # Base compile flags
 # and prefix or precompiled header added here.
 
@@ -222,6 +237,12 @@ PLIB3S	= $(METROWERKS)/Novell Support/Metrowerks Support/Libraries/MSL C++/MWCPP
 
 CFLAGS = -c -w nocmdline -gccinc -Cpp_exceptions off -RTTI off -align 4 -proc PII
 
+ifdef CC_MAX_ERRORS
+CFLAGS += -maxerrors $(CC_MAX_ERRORS)
+else
+CFLAGS += -maxerrors 1
+endif
+
 ifeq "$(REQUIRE_PROTOTYPES)" "1"
 CFLAGS += -r
 endif
@@ -237,7 +258,7 @@ ifeq "$(RELEASE)" "release"
 CFLAGS += -O4,p
 endif
 
-# -prefix apr_arch_pre_nw.h      #include pre_nw.h for all files
+# -prefix apr_arch_pre_nw.h      #include apr_arch_pre_nw.h for all files
 CFLAGS += -prefix apr_arch_pre_nw.h
 
 
diff --git a/build/NWGNUmakefile b/build/NWGNUmakefile
index 579186a..2421ff8 100644
--- a/build/NWGNUmakefile
+++ b/build/NWGNUmakefile
@@ -23,6 +23,7 @@ FILES_prebuild_headers = \
 	$(APU)/include/private/apu_config.h \
 	$(APU)/include/private/apu_select_dbm.h \
 	$(APUXML)/expat/lib/expat_config.h \
+	$(APR)/include/private/apr_escape_test_char.h \
 	$(EOLIST) 
     
 nlms :: $(APR)/aprlib.imp
@@ -69,6 +70,14 @@ $(APU)/include/apr_ldap.h: $(APR)/build/nw_make_header.awk $(APU)/include/apr_ld
 	@echo $(DL)Creating $@$(DL)
 	$(call COPY,$<,$@)
 
+$(APR)/include/private/apr_escape_test_char.h: gen_test_char.exe $(APR)/tools/gen_test_char.c
+	@echo $(DL)GEN  $@$(DL)
+	$< > $@
+
+%.exe: $(APR)/tools/%.c
+	@echo $(DL)Creating Build Helper $@$(DL)
+	$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) -DCROSS_COMPILE $< -o $@
+
 #
 # You can use this target if all that is needed is to copy files to the
 # installation area
@@ -81,6 +90,7 @@ clean ::
 	$(call DEL,NWGNUversion.inc)
 	$(call DEL,$(APR)/aprlib.imp)
 	$(foreach file,$(FILES_prebuild_headers),$(call DEL,$(file)))
+	$(call DEL,gen_test_char.exe)
 
 #
 # Include the 'tail' makefile that has targets that depend on variables defined
diff --git a/build/apr_hints.m4 b/build/apr_hints.m4
index 7453b98..549a2db 100644
--- a/build/apr_hints.m4
+++ b/build/apr_hints.m4
@@ -183,7 +183,7 @@ dnl	       # Not a problem in 10.20.  Otherwise, who knows?
 	APR_ADDTO(CPPFLAGS, [-DRHAPSODY])
 	;;
     *-apple-darwin*)
-        APR_ADDTO(CPPFLAGS, [-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp])
+        APR_ADDTO(CPPFLAGS, [-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK])
         APR_SETIFNULL(apr_posixsem_is_global, [yes])
         case $host in
             *-apple-darwin[[1-9]].*)
diff --git a/build/config.guess b/build/config.guess
index 72625d4..1f5c50c 100755
--- a/build/config.guess
+++ b/build/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2014 Free Software Foundation, Inc.
 
-timestamp='2014-02-12'
+timestamp='2014-03-23'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -826,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    i*:MSYS*:*)
+    *:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -969,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    or1k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:*)
+    or32:Linux:*:* | or1k*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
diff --git a/build/config.sub b/build/config.sub
index 092cff0..bba4efb 100755
--- a/build/config.sub
+++ b/build/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2014 Free Software Foundation, Inc.
 
-timestamp='2014-01-01'
+timestamp='2014-09-11'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -283,8 +283,10 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -296,11 +298,11 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 \
-	| or1k | or32 \
+	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
+	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
 	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@@ -402,8 +404,10 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -415,6 +419,7 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
+	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -824,6 +829,10 @@ case $basic_machine in
 		basic_machine=powerpc-unknown
 		os=-morphos
 		;;
+	moxiebox)
+		basic_machine=moxie-unknown
+		os=-moxiebox
+		;;
 	msdos)
 		basic_machine=i386-pc
 		os=-msdos
@@ -1369,14 +1378,14 @@ case $os in
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1594,9 +1603,6 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
-	or1k-*)
-		os=-elf
-		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/build/nw_export.inc b/build/nw_export.inc
index 452b401..ce9384f 100644
--- a/build/nw_export.inc
+++ b/build/nw_export.inc
@@ -15,6 +15,7 @@
 #include "apr_dso.h"
 #include "apr_env.h"
 #include "apr_errno.h"
+#include "apr_escape.h"
 #include "apr_file_info.h"
 #include "apr_file_io.h"
 #include "apr_fnmatch.h"
@@ -34,6 +35,7 @@
 #include "apr_random.h"
 #include "apr_shm.h"
 #include "apr_signal.h"
+#include "apr_skiplist.h"
 #include "apr_strings.h"
 #include "apr_support.h"
 #include "apr_tables.h"
diff --git a/build/rpm/apr.spec.in b/build/rpm/apr.spec.in
index e35e9a3..ee42398 100644
--- a/build/rpm/apr.spec.in
+++ b/build/rpm/apr.spec.in
@@ -76,7 +76,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root,-)
 %doc docs/APRDesign.html docs/canonical_filenames.html
 %doc docs/incomplete_types docs/non_apr_programs
-%doc --parents html
+%doc html
 %{_bindir}/apr*config
 %{_libdir}/libapr-%{aprver}.*a
 %{_libdir}/libapr-%{aprver}.so
diff --git a/configure b/configure
index 860c65b..449c884 100755
--- a/configure
+++ b/configure
@@ -6802,10 +6802,10 @@ if test "x$apr_preload_done" != "xyes" ; then
     *-apple-darwin*)
 
   if test "x$CPPFLAGS" = "x"; then
-    test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp\""
-    CPPFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp"
+    test "x$silent" != "xyes" && echo "  setting CPPFLAGS to \"-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK\""
+    CPPFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
   else
-    apr_addto_bugger="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp"
+    apr_addto_bugger="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
     for i in $apr_addto_bugger; do
       apr_addto_duplicate="0"
       for j in $CPPFLAGS; do
@@ -18794,7 +18794,34 @@ if test "${enable_nonportable_atomics+set}" = set; then :
 else
   case $host_cpu in
    i[456]86) force_generic_atomics=yes ;;
-   *) force_generic_atomics=no ;;
+   *) force_generic_atomics=no
+      case $host in
+         *solaris2.10*)
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <atomic.h>
+int
+main ()
+{
+void *ptr = NULL; atomic_cas_ptr(&ptr, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  force_generic_atomics=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+            if test $force_generic_atomics = yes; then
+                { $as_echo "$as_me:${as_lineno-$LINENO}: nonportable atomic support disabled, system needs Patch-ID 118884 or 118885" >&5
+$as_echo "$as_me: nonportable atomic support disabled, system needs Patch-ID 118884 or 118885" >&6;}
+            fi
+            ;;
+      esac
+      ;;
 esac
 
 fi
@@ -22292,7 +22319,7 @@ else
 fi
 done
 
-for ac_func in getpass getpassphrase gmtime_r localtime_r mkstemp
+for ac_func in getpass getpassphrase gmtime_r localtime_r
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -22304,6 +22331,23 @@ _ACEOF
 fi
 done
 
+case $host in
+    *-hp-hpux*)
+                ;;
+    *)
+        for ac_func in mkstemp
+do :
+  ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
+if test "x$ac_cv_func_mkstemp" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MKSTEMP 1
+_ACEOF
+
+fi
+done
+
+        ;;
+esac
 
 
 
@@ -23902,7 +23946,7 @@ _ACEOF
 if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
     # Enable LFS
     aprlfs=1
-    for ac_func in mmap64 sendfile64 sendfilev64 mkstemp64 readdir64_r
+    for ac_func in mmap64 sendfile64 sendfilev64 readdir64_r
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -23914,6 +23958,23 @@ _ACEOF
 fi
 done
 
+    case $host in
+        *-hp-hpux*)
+                        ;;
+        *)
+            for ac_func in mkstemp64
+do :
+  ac_fn_c_check_func "$LINENO" "mkstemp64" "ac_cv_func_mkstemp64"
+if test "x$ac_cv_func_mkstemp64" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MKSTEMP64 1
+_ACEOF
+
+fi
+done
+
+            ;;
+    esac
 elif test "${ac_cv_sizeof_off_t}" != "${ac_cv_sizeof_size_t}"; then
     # unsure of using -gt above is as portable, can can't forsee where
     # off_t can legitimately be smaller than size_t
diff --git a/configure.in b/configure.in
index 2a37a30..e01774b 100644
--- a/configure.in
+++ b/configure.in
@@ -640,7 +640,20 @@ AC_ARG_ENABLE(nonportable-atomics,
 ],
 [case $host_cpu in
    i[[456]]86) force_generic_atomics=yes ;;
-   *) force_generic_atomics=no ;;
+   *) force_generic_atomics=no
+      case $host in
+         *solaris2.10*)
+            AC_TRY_COMPILE(
+                [#include <atomic.h>],
+                [void *ptr = NULL; atomic_cas_ptr(&ptr, NULL, NULL);],,
+                [force_generic_atomics=yes]
+            )
+            if test $force_generic_atomics = yes; then
+                AC_MSG_NOTICE([nonportable atomic support disabled, system needs Patch-ID 118884 or 118885])
+            fi
+            ;;
+      esac
+      ;;
 esac
 ])
 
@@ -1400,7 +1413,15 @@ if test "$native_mmap_emul" = "1"; then
     mmap="1"
 fi
 AC_CHECK_FUNCS(memmove, [ have_memmove="1" ], [have_memmove="0" ])
-AC_CHECK_FUNCS([getpass getpassphrase gmtime_r localtime_r mkstemp])
+AC_CHECK_FUNCS([getpass getpassphrase gmtime_r localtime_r])
+case $host in
+    *-hp-hpux*)
+        dnl mkstemp is limited to 26 temporary files (a-z); use APR replacement
+        ;;
+    *)
+        AC_CHECK_FUNCS(mkstemp)
+        ;;
+esac
 
 AC_SUBST(fork)
 AC_SUBST(have_inet_addr)
@@ -1801,7 +1822,15 @@ APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], off_t, 8)
 if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
     # Enable LFS
     aprlfs=1
-    AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 mkstemp64 readdir64_r])
+    AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 readdir64_r])
+    case $host in
+        *-hp-hpux*)
+            dnl mkstemp64 is limited to 26 temporary files (a-z); use APR replacement
+            ;;
+        *)
+            AC_CHECK_FUNCS(mkstemp64)
+            ;;
+    esac
 elif test "${ac_cv_sizeof_off_t}" != "${ac_cv_sizeof_size_t}"; then
     # unsure of using -gt above is as portable, can can't forsee where
     # off_t can legitimately be smaller than size_t
diff --git a/encoding/apr_escape.c b/encoding/apr_escape.c
index 2bcfec4..702a941 100644
--- a/encoding/apr_escape.c
+++ b/encoding/apr_escape.c
@@ -436,6 +436,8 @@ APR_DECLARE(apr_status_t) apr_escape_path(char *escaped, const char *path,
         while ((c = *s) && slen) {
             if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) {
                 d = c2x(c, '%', d);
+                size += 2;
+                found = 1;
             }
             else {
                 *d++ = c;
diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c
index f240eba..c7ea8bc 100644
--- a/file_io/win32/pipe.c
+++ b/file_io/win32/pipe.c
@@ -18,6 +18,7 @@
 #include "apr_file_io.h"
 #include "apr_general.h"
 #include "apr_strings.h"
+#include "apr_escape.h"
 #if APR_HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -46,7 +47,8 @@ APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe,
         return APR_ENOTIMPL;
     }
     if (timeout && !(thepipe->pOverlapped)) {
-        /* Cannot be nonzero if a pipe was opened blocking */
+        /* Cannot be nonzero if a pipe was opened blocking
+         */
         return APR_EINVAL;
     }
     thepipe->timeout = timeout;
@@ -81,7 +83,6 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
     static unsigned long id = 0;
     DWORD dwPipeMode;
     DWORD dwOpenMode;
-    char name[50];
 
     sa.nLength = sizeof(sa);
 
@@ -126,8 +127,26 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
     (void) apr_pollset_create(&(*out)->pollset, 1, p, 0);
 #endif
     if (apr_os_level >= APR_WIN_NT) {
+        char rand[8];
+        int pid = getpid();
+#define FMT_PIPE_NAME "\\\\.\\pipe\\apr-pipe-%x.%lx."
+        /*                                    ^   ^ ^
+         *                                  pid   | |
+         *                                        | |
+         *                                       id |
+         *                                          |
+         *                        hex-escaped rand[8] (16 bytes)
+         */
+        char name[sizeof FMT_PIPE_NAME + 2 * sizeof(pid)
+                                       + 2 * sizeof(id)
+                                       + 2 * sizeof(rand)];
+        apr_size_t pos;
+
         /* Create the read end of the pipe */
         dwOpenMode = PIPE_ACCESS_INBOUND;
+#ifdef FILE_FLAG_FIRST_PIPE_INSTANCE
+        dwOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
+#endif
         if (blocking == APR_WRITE_BLOCK /* READ_NONBLOCK */
                || blocking == APR_FULL_NONBLOCK) {
             dwOpenMode |= FILE_FLAG_OVERLAPPED;
@@ -135,10 +154,11 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
             (*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
             (*in)->timeout = 0;
         }
-
         dwPipeMode = 0;
 
-        sprintf(name, "\\\\.\\pipe\\apr-pipe-%u.%lu", getpid(), id++);
+        apr_generate_random_bytes(rand, sizeof rand);
+        pos = apr_snprintf(name, sizeof name, FMT_PIPE_NAME, pid, id++);
+        apr_escape_hex(name + pos, rand, sizeof rand, 0, NULL);
 
         (*in)->filehand = CreateNamedPipe(name,
                                           dwOpenMode,
@@ -148,6 +168,11 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
                                           65536,        /* nInBufferSize,   */
                                           1,            /* nDefaultTimeOut, */
                                           &sa);
+        if ((*in)->filehand == INVALID_HANDLE_VALUE) {
+            apr_status_t rv = apr_get_os_error();
+            file_cleanup(*in);
+            return rv;
+        }
 
         /* Create the write end of the pipe */
         dwOpenMode = FILE_ATTRIBUTE_NORMAL;
@@ -160,12 +185,18 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_ex(apr_file_t **in,
         }
 
         (*out)->filehand = CreateFile(name,
-                                      GENERIC_WRITE, /* access mode             */
-                                      0,             /* share mode              */
-                                      &sa,           /* Security attributes     */
-                                      OPEN_EXISTING, /* dwCreationDisposition   */
-                                      dwOpenMode,    /* Pipe attributes         */
-                                      NULL);         /* handle to template file */
+                                      GENERIC_WRITE,   /* access mode             */
+                                      0,               /* share mode              */
+                                      &sa,             /* Security attributes     */
+                                      OPEN_EXISTING,   /* dwCreationDisposition   */
+                                      dwOpenMode,      /* Pipe attributes         */
+                                      NULL);           /* handle to template file */
+        if ((*out)->filehand == INVALID_HANDLE_VALUE) {
+            apr_status_t rv = apr_get_os_error();
+            file_cleanup(*out);
+            file_cleanup(*in);
+            return rv;
+        }
     }
     else {
         /* Pipes on Win9* are blocking. Live with it. */
diff --git a/include/apr_skiplist.h b/include/apr_skiplist.h
index bc17efd..f56ff22 100644
--- a/include/apr_skiplist.h
+++ b/include/apr_skiplist.h
@@ -40,7 +40,9 @@ extern "C" {
 /**
  * apr_skiplist_compare is the function type that must be implemented 
  * per object type that is used in a skip list for comparisons to maintain
- * order
+ * order. A value <0 indicates placement after this node; a value of 0
+ * indicates collision with this exact node; a value >0 indicates placement
+ * before this node.
  * */
 typedef int (*apr_skiplist_compare) (void *, void *);
 
@@ -171,7 +173,8 @@ APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter)
 APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter);
 
 /**
- * Insert an element into the skip list using the specified comparison function.
+ * Insert an element into the skip list using the specified comparison function
+ * if it does not already exist.
  * @param sl The skip list
  * @param data The element to insert
  * @param comp The comparison function to use for placement into the skip list
@@ -180,7 +183,8 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl,
                                           void *data, apr_skiplist_compare comp);
 
 /**
- * Insert an element into the skip list using the existing comparison function.
+ * Insert an element into the skip list using the existing comparison function
+ * if it does not already exist (as determined by the comparison function)
  * @param sl The skip list
  * @param data The element to insert
  * @remark If no comparison function has been set for the skip list, the element
@@ -190,7 +194,7 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist* sl, void *data
 
 /**
  * Remove an element from the skip list using the specified comparison function for
- * locating the element.
+ * locating the element. In the case of duplicates, the 1st entry will be removed.
  * @param sl The skip list
  * @param data The element to remove
  * @param myfree A function to be called for each removed element
@@ -203,7 +207,7 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sl, void *data,
 
 /**
  * Remove an element from the skip list using the existing comparison function for
- * locating the element.
+ * locating the element. In the case of duplicates, the 1st entry will be removed.
  * @param sl The skip list
  * @param data The element to remove
  * @param myfree A function to be called for each removed element
@@ -229,7 +233,7 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefun
 APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree);
 
 /**
- * Return the first element in the skip list, leaving the element in the skip list.
+ * Return the first element in the skip list, removing the element from the skip list.
  * @param sl The skip list
  * @param myfree A function to be called for the removed element
  * @remark NULL will be returned if there are no elements
diff --git a/include/apr_version.h b/include/apr_version.h
index 2111053..c7cbb8f 100644
--- a/include/apr_version.h
+++ b/include/apr_version.h
@@ -38,7 +38,7 @@
  */
 
 
-#define APR_COPYRIGHT "Copyright (c) 2000-2014 The Apache Software " \
+#define APR_COPYRIGHT "Copyright (c) 2000-2015 The Apache Software " \
                       "Foundation or its licensors, as applicable."
 
 /* The numeric compile-time version constants. These constants are the
@@ -62,7 +62,7 @@
  * The Patch Level never includes API changes, simply bug fixes.
  * Reset to 0 when upgrading APR_MINOR_VERSION
  */
-#define APR_PATCH_VERSION       1
+#define APR_PATCH_VERSION       2
 
 /** 
  * The symbol APR_IS_DEV_VERSION is only defined for internal,
diff --git a/libapr.dsp b/libapr.dsp
index f121ef9..2678832 100644
--- a/libapr.dsp
+++ b/libapr.dsp
@@ -765,7 +765,7 @@ SOURCE=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\Release\gen_test_char /Fe.\Release\gen_test_char.exe .\tools\gen_test_char.c 
 	.\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -776,7 +776,7 @@ InputPath=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\Debug\gen_test_char /Fe.\Debug\gen_test_char.exe .\tools\gen_test_char.c  
 	.\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -787,7 +787,7 @@ InputPath=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\9x\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\9x\Release\gen_test_char /Fe.\9x\Release\gen_test_char.exe .\tools\gen_test_char.c 
 	.\9x\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -798,7 +798,7 @@ InputPath=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\9x\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\9x\Debug\gen_test_char /Fe.\9x\Debug\gen_test_char.exe .\tools\gen_test_char.c  
 	.\9x\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -809,7 +809,7 @@ InputPath=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\x64\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\x64\Release\gen_test_char /Fe.\x64\Release\gen_test_char.exe .\tools\gen_test_char.c 
 	.\x64\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -820,7 +820,7 @@ InputPath=.\include\apr_escape.h
 # Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
 InputPath=.\include\apr_escape.h
 
-".\x64\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
 	cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\x64\Debug\gen_test_char /Fe.\x64\Debug\gen_test_char.exe .\tools\gen_test_char.c 
 	.\x64\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
 
@@ -952,69 +952,6 @@ SOURCE=.\include\apr_version.h
 # Begin Source File
 
 SOURCE=.\include\apr_want.h
-
-!IF  "$(CFG)" == "libapr - Win32 Release"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "libapr - Win32 Debug"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "libapr - Win32 Release9x"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "libapr - Win32 Debug9x"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "libapr - x64 Release"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "libapr - x64 Debug"
-
-# Begin Custom Build
-InputPath=.\include\apr_want.h
-
-".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\include\apr.hw > .\include\apr.h
-
-# End Custom Build
-
-!ENDIF 
-
 # End Source File
 # End Group
 # Begin Source File
diff --git a/locks/beos/thread_cond.c b/locks/beos/thread_cond.c
index e3ea460..44189d9 100644
--- a/locks/beos/thread_cond.c
+++ b/locks/beos/thread_cond.c
@@ -113,10 +113,11 @@ static apr_status_t do_wait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex,
 
     apr_thread_mutex_lock(cond->condlock);
     
-    if (rv != B_OK)
+    if (rv != B_OK) {
         if (rv == B_TIMED_OUT)
             return APR_TIMEUP;
         return rv;       
+    }
 
     acquire_sem(cond->lock);
     APR_RING_REMOVE(wait, link);
diff --git a/locks/unix/proc_mutex.c b/locks/unix/proc_mutex.c
index fa8a872..32012a7 100644
--- a/locks/unix/proc_mutex.c
+++ b/locks/unix/proc_mutex.c
@@ -114,7 +114,9 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
         usec = apr_time_usec(now);
         apr_snprintf(semname, sizeof(semname), "/ApR.%lxZ%lx", sec, usec);
     }
-    psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
+    do {
+        psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
+    } while (psem == (sem_t *)SEM_FAILED && errno == EINTR);
     if (psem == (sem_t *)SEM_FAILED) {
         if (errno == ENAMETOOLONG) {
             /* Oh well, good try */
@@ -122,7 +124,9 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
         } else {
             return errno;
         }
-        psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
+        do {
+            psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
+        } while (psem == (sem_t *)SEM_FAILED && errno == EINTR);
     }
 
     if (psem == (sem_t *)SEM_FAILED) {
@@ -140,7 +144,12 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
 
 static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
 {
-    if (sem_wait(mutex->psem_interproc) < 0) {
+    int rc;
+
+    do {
+        rc = sem_wait(mutex->psem_interproc);
+    } while (rc < 0 && errno == EINTR);
+    if (rc < 0) {
         return errno;
     }
     mutex->curr_locked = 1;
@@ -149,7 +158,12 @@ static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
 
 static apr_status_t proc_mutex_posix_tryacquire(apr_proc_mutex_t *mutex)
 {
-    if (sem_trywait(mutex->psem_interproc) < 0) {
+    int rc;
+
+    do {
+        rc = sem_trywait(mutex->psem_interproc);
+    } while (rc < 0 && errno == EINTR);
+    if (rc < 0) {
         if (errno == EAGAIN) {
             return APR_EBUSY;
         }
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c
index 5c1a1ff..20e4254 100644
--- a/memory/unix/apr_pools.c
+++ b/memory/unix/apr_pools.c
@@ -1135,21 +1135,12 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
      * room to hold the NUL terminator.
      */
     if (ps.node->first_avail == ps.node->endp) {
-        if (psprintf_flush(&ps.vbuff) == -1) {
-            if (pool->abort_fn) {
-                pool->abort_fn(APR_ENOMEM);
-            }
-
-            return NULL;
-        }
+        if (psprintf_flush(&ps.vbuff) == -1)
+           goto error;
     }
 
-    if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1) {
-        if (pool->abort_fn)
-            pool->abort_fn(APR_ENOMEM);
-
-        return NULL;
-    }
+    if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1)
+        goto error;
 
     strp = ps.vbuff.curpos;
     *strp++ = '\0';
@@ -1195,6 +1186,15 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
     list_insert(active, node);
 
     return strp;
+
+error:
+    if (pool->abort_fn)
+        pool->abort_fn(APR_ENOMEM);
+    if (ps.got_a_new_node) {
+        ps.node->next = ps.free;
+        allocator_free(pool->allocator, ps.node);
+    }
+    return NULL;
 }
 
 
diff --git a/misc/unix/errorcodes.c b/misc/unix/errorcodes.c
index 75567c2..f553a37 100644
--- a/misc/unix/errorcodes.c
+++ b/misc/unix/errorcodes.c
@@ -39,6 +39,8 @@ static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s)
 static char *apr_error_string(apr_status_t statcode)
 {
     switch (statcode) {
+    case APR_ENOSTAT:
+        return "Could not perform a stat on the file.";
     case APR_ENOPOOL:
         return "A new pool could not be created.";
     case APR_EBADDATE:
@@ -73,7 +75,10 @@ static char *apr_error_string(apr_status_t statcode)
         return "The specified IP address is invalid.";
     case APR_EBADMASK:
         return "The specified network mask is invalid.";
-
+    case APR_ESYMNOTFOUND:
+        return "Could not find the requested symbol.";
+    case APR_ENOTENOUGHENTROPY:
+        return "Not enough entropy to continue.";
     case APR_INCHILD:
         return
 	    "Your code just forked, and you are currently executing in the "
@@ -128,10 +133,12 @@ static char *apr_error_string(apr_status_t statcode)
         return "The given path is misformatted or contained invalid characters";
     case APR_EPATHWILD:
         return "The given path contained wildcard characters";
+    case APR_EBUSY:
+        return "The given lock was busy.";
     case APR_EPROC_UNKNOWN:
         return "The process is not recognized.";
     case APR_EGENERAL:
-        return "Internal error";
+        return "Internal error (specific information not available)";
     default:
         return "Error string not specified yet";
     }
diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c
index 0dd1a2d..e6d7e0b 100644
--- a/network_io/unix/sockaddr.c
+++ b/network_io/unix/sockaddr.c
@@ -325,6 +325,16 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa,
         hints.ai_flags = AI_ADDRCONFIG;
     }
 #endif
+
+#ifdef __MVS__
+    /* z/OS will not return IPv4 address under AF_UNSPEC if any IPv6 results 
+     * are returned, w/o AI_ALL. 
+     */
+    if (family == APR_UNSPEC) { 
+       hints.ai_flags |= AI_ALL;
+    }
+#endif
+
     if(hostname == NULL) {
 #ifdef AI_PASSIVE 
         /* If hostname is NULL, assume we are trying to bind to all
diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c
index 514edb1..b95794f 100644
--- a/network_io/unix/sockets.c
+++ b/network_io/unix/sockets.c
@@ -145,13 +145,22 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
 #ifndef HAVE_SOCK_CLOEXEC
     {
         int flags;
+        apr_status_t rv;
 
-        if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1) {
+            rv = errno;
+            close((*new)->socketdes);
+            (*new)->socketdes = -1;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl((*new)->socketdes, F_SETFD, flags) == -1) {
+            rv = errno;
+            close((*new)->socketdes);
+            (*new)->socketdes = -1;
+            return rv;
+        }
     }
 #endif
 
@@ -306,13 +315,22 @@ apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock,
 #ifndef HAVE_ACCEPT4
     {
         int flags;
+        apr_status_t rv;
 
-        if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1) {
+            rv = errno;
+            close((*new)->socketdes);
+            (*new)->socketdes = -1;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl((*new)->socketdes, F_SETFD, flags) == -1) {
+            rv = errno;
+            close((*new)->socketdes);
+            (*new)->socketdes = -1;
+            return rv;
+        }
     }
 #endif
 
diff --git a/poll/unix/epoll.c b/poll/unix/epoll.c
index 326dac7..fe006db 100644
--- a/poll/unix/epoll.c
+++ b/poll/unix/epoll.c
@@ -104,14 +104,22 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
 
 #ifndef HAVE_EPOLL_CREATE1
     {
-        int flags;
+        int fd_flags;
 
-        if ((flags = fcntl(fd, F_GETFD)) == -1)
-            return errno;
+        if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(fd);
+            pollset->p = NULL;
+            return rv;
+        }
 
-        flags |= FD_CLOEXEC;
-        if (fcntl(fd, F_SETFD, flags) == -1)
-            return errno;
+        fd_flags |= FD_CLOEXEC;
+        if (fcntl(fd, F_SETFD, fd_flags) == -1) {
+            rv = errno;
+            close(fd);
+            pollset->p = NULL;
+            return rv;
+        }
     }
 #endif
 
@@ -122,11 +130,13 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
         ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                        APR_THREAD_MUTEX_DEFAULT,
                                        p)) != APR_SUCCESS)) {
+        close(fd);
         pollset->p = NULL;
         return rv;
     }
 #else
     if (flags & APR_POLLSET_THREADSAFE) {
+        close(fd);
         pollset->p = NULL;
         return APR_ENOTIMPL;
     }
@@ -345,14 +355,23 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
 
 #ifndef HAVE_EPOLL_CREATE1
     {
-        int flags;
-
-        if ((flags = fcntl(fd, F_GETFD)) == -1)
-            return errno;
+        int fd_flags;
+        apr_status_t rv;
+
+        if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(fd);
+            pollcb->fd = -1;
+            return rv;
+        }
 
-        flags |= FD_CLOEXEC;
-        if (fcntl(fd, F_SETFD, flags) == -1)
-            return errno;
+        fd_flags |= FD_CLOEXEC;
+        if (fcntl(fd, F_SETFD, fd_flags) == -1) {
+            rv = errno;
+            close(fd);
+            pollcb->fd = -1;
+            return rv;
+        }
     }
 #endif
     
diff --git a/poll/unix/kqueue.c b/poll/unix/kqueue.c
index dbe785a..efc5898 100644
--- a/poll/unix/kqueue.c
+++ b/poll/unix/kqueue.c
@@ -115,12 +115,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
     {
         int flags;
 
-        if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(pollset->p->kqueue_fd);
+            pollset->p = NULL;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1) {
+            rv = errno;
+            close(pollset->p->kqueue_fd);
+            pollset->p = NULL;
+            return rv;
+        }
     }
 
     pollset->p->result_set = apr_palloc(p, pollset->p->setsize * sizeof(apr_pollfd_t));
@@ -338,13 +346,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
 
     {
         int flags;
+        apr_status_t rv;
 
-        if ((flags = fcntl(fd, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl(fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(fd);
+            pollcb->fd = -1;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl(fd, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl(fd, F_SETFD, flags) == -1) {
+            rv = errno;
+            close(fd);
+            pollcb->fd = -1;
+            return rv;
+        }
     }
  
     pollcb->fd = fd;
diff --git a/poll/unix/poll.c b/poll/unix/poll.c
index 7d15736..d7a436f 100644
--- a/poll/unix/poll.c
+++ b/poll/unix/poll.c
@@ -240,26 +240,25 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
 {
     int ret;
     apr_status_t rv = APR_SUCCESS;
-#ifdef WIN32
-    apr_interval_time_t orig_timeout = timeout;
-#endif
 
-    if (timeout > 0) {
-        timeout /= 1000;
-    }
 #ifdef WIN32
     /* WSAPoll() requires at least one socket. */
     if (pollset->nelts == 0) {
         *num = 0;
-        if (orig_timeout > 0) {
-            apr_sleep(orig_timeout);
+        if (timeout > 0) {
+            apr_sleep(timeout);
             return APR_TIMEUP;
         }
         return APR_SUCCESS;
     }
-
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
     ret = WSAPoll(pollset->p->pollset, pollset->nelts, (int)timeout);
 #else
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
     ret = poll(pollset->p->pollset, pollset->nelts, timeout);
 #endif
     (*num) = ret;
@@ -398,12 +397,23 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
     apr_status_t rv = APR_SUCCESS;
     apr_uint32_t i;
 
+#ifdef WIN32
+    /* WSAPoll() requires at least one socket. */
+    if (pollcb->nelts == 0) {
+        if (timeout > 0) {
+            apr_sleep(timeout);
+            return APR_TIMEUP;
+        }
+        return APR_SUCCESS;
+    }
     if (timeout > 0) {
         timeout /= 1000;
     }
-#ifdef WIN32
     ret = WSAPoll(pollcb->pollset.ps, pollcb->nelts, (int)timeout);
 #else
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
     ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout);
 #endif
     if (ret < 0) {
diff --git a/poll/unix/pollcb.c b/poll/unix/pollcb.c
index 24f8010..da12f01 100644
--- a/poll/unix/pollcb.c
+++ b/poll/unix/pollcb.c
@@ -136,6 +136,9 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
         }
         pollcb->provider = provider;
     }
+    else if (rv != APR_SUCCESS) {
+        return rv;
+    }
 
     *ret_pollcb = pollcb;
     return APR_SUCCESS;
diff --git a/poll/unix/port.c b/poll/unix/port.c
index 7a31c46..5002dfd 100644
--- a/poll/unix/port.c
+++ b/poll/unix/port.c
@@ -188,12 +188,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
     {
         int flags;
 
-        if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(pollset->p->port_fd);
+            pollset->p = NULL;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1) {
+            rv = errno;
+            close(pollset->p->port_fd);
+            pollset->p = NULL;
+            return rv;
+        }
     }
 
     pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
@@ -478,13 +486,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
 
     {
         int flags;
+        apr_status_t rv;
 
-        if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1)
-            return errno;
+        if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1) {
+            rv = errno;
+            close(pollcb->fd);
+            pollcb->fd = -1;
+            return rv;
+        }
 
         flags |= FD_CLOEXEC;
-        if (fcntl(pollcb->fd, F_SETFD, flags) == -1)
-            return errno;
+        if (fcntl(pollcb->fd, F_SETFD, flags) == -1) {
+            rv = errno;
+            close(pollcb->fd);
+            pollcb->fd = -1;
+            return rv;
+        }
     }
 
     pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));
diff --git a/poll/unix/z_asio.c b/poll/unix/z_asio.c
index ce158d3..7e0fd89 100644
--- a/poll/unix/z_asio.c
+++ b/poll/unix/z_asio.c
@@ -272,7 +272,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
                                            APR_THREAD_MUTEX_DEFAULT,
                                            p) != APR_SUCCESS) {
             DBG1(1, "apr_thread_mutex_create returned %d\n", rv);
-            pollset = NULL;
+            pollset->p = NULL;
             return rv;
         }
         rv = msgget(IPC_PRIVATE, S_IWUSR+S_IRUSR); /* user r/w perms */
@@ -280,7 +280,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
 #if DEBUG
             perror(__FUNCTION__ " msgget returned < 0 ");
 #endif
-            pollset = NULL;
+            pollset->p = NULL;
             return rv;
         }
 
@@ -292,7 +292,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
         APR_RING_INIT(&priv->prior_ready_ring, asio_elem_t, link);
 
 #else  /* APR doesn't have threads but caller wants a threadsafe pollset */
-        pollset = NULL;
+        pollset->p = NULL;
         return APR_ENOTIMPL;
 #endif
 
@@ -304,6 +304,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
         priv->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
 
         if ((!priv->pollset) || (!priv->query_set)) {
+            pollset->p = NULL;
             return APR_ENOMEM;
         }
     }
@@ -314,6 +315,10 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
     priv->size    = size;
     priv->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
     if (!priv->result_set) {
+        if (flags & APR_POLLSET_THREADSAFE) {
+            msgctl(priv->msg_q, IPC_RMID, NULL);
+        }
+        pollset->p = NULL;
         return APR_ENOMEM;
     }
 
@@ -379,6 +384,7 @@ static apr_status_t asio_pollset_add(apr_pollset_t *pollset,
             APR_RING_REMOVE(elem, link);
             DBG1(3, "used recycled memory at %08p\n", elem);
             elem->state = ASIO_INIT;
+            elem->a.aio_cflags = 0;
         }
         else {
             elem = (asio_elem_t *) apr_pcalloc(pollset->pool, sizeof(asio_elem_t));
@@ -659,6 +665,7 @@ static apr_status_t asio_pollset_poll(apr_pollset_t *pollset,
             if (ret == 1) {
                 DBG(4, "asyncio() completed inline\n");
                 /* it's ready now */
+                elem->state = ASIO_COMPLETE;
                 APR_RING_INSERT_TAIL(&(priv->ready_ring), elem, asio_elem_t,
                                      link);
             }
diff --git a/tables/apr_skiplist.c b/tables/apr_skiplist.c
index effcf60..b4696bd 100644
--- a/tables/apr_skiplist.c
+++ b/tables/apr_skiplist.c
@@ -25,12 +25,18 @@
 
 #include "apr_skiplist.h"
 
+typedef struct {
+    apr_skiplistnode **data;
+    size_t size, pos;
+    apr_pool_t *p;
+} apr_skiplist_q; 
+
 struct apr_skiplist {
     apr_skiplist_compare compare;
     apr_skiplist_compare comparek;
     int height;
     int preheight;
-    int size;
+    size_t size;
     apr_skiplistnode *top;
     apr_skiplistnode *bottom;
     /* These two are needed for appending */
@@ -38,6 +44,8 @@ struct apr_skiplist {
     apr_skiplistnode *bottomend;
     apr_skiplist *index;
     apr_array_header_t *memlist;
+    apr_skiplist_q nodes_q,
+                   stack_q;
     apr_pool_t *pool;
 };
 
@@ -52,20 +60,15 @@ struct apr_skiplistnode {
     apr_skiplist *sl;
 };
 
-#ifndef MIN
-#define MIN(a,b) ((a<b)?(a):(b))
-#endif
-
 static int get_b_rand(void)
 {
     static int ph = 32;         /* More bits than we will ever use */
-    static apr_uint32_t randseq;
+    static int randseq;
     if (ph > 31) {              /* Num bits in return of rand() */
         ph = 0;
-        randseq = (apr_uint32_t) rand();
+        randseq = rand();
     }
-    ph++;
-    return ((randseq & (1 << (ph - 1))) >> (ph - 1));
+    return randseq & (1 << ph++);
 }
 
 typedef struct {
@@ -103,7 +106,7 @@ APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size)
             memlist++;
         }
         /* no free chunks */
-        ptr = apr_pcalloc(sl->pool, size);
+        ptr = apr_palloc(sl->pool, size);
         if (!ptr) {
             return ptr;
         }
@@ -122,7 +125,7 @@ APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size)
         return ptr;
     }
     else {
-        return calloc(1, size);
+        return malloc(size);
     }
 }
 
@@ -149,27 +152,73 @@ APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem)
     }
 }
 
+static apr_status_t skiplist_qpush(apr_skiplist_q *q, apr_skiplistnode *m)
+{
+    if (q->pos >= q->size) {
+        apr_skiplistnode **data;
+        size_t size = (q->pos) ? q->pos * 2 : 32;
+        if (q->p) {
+            data = apr_palloc(q->p, size * sizeof(*data));
+            if (data) {
+                memcpy(data, q->data, q->pos * sizeof(*data));
+            }
+        }
+        else {
+            data = realloc(q->data, size * sizeof(*data));
+        }
+        if (!data) {
+            return APR_ENOMEM;
+        }
+        q->data = data;
+        q->size = size;
+    }
+    q->data[q->pos++] = m;
+    return APR_SUCCESS;
+}
+
+static APR_INLINE apr_skiplistnode *skiplist_qpop(apr_skiplist_q *q)
+{
+    return (q->pos > 0) ? q->data[--q->pos] : NULL;
+}
+
+static APR_INLINE void skiplist_qclear(apr_skiplist_q *q)
+{
+    q->pos = 0;
+}
+
+static apr_skiplistnode *skiplist_new_node(apr_skiplist *sl)
+{
+    apr_skiplistnode *m = skiplist_qpop(&sl->nodes_q);
+    if (!m) {
+        if (sl->pool) {
+            m = apr_palloc(sl->pool, sizeof *m);
+        }
+        else {
+            m = malloc(sizeof *m);
+        }
+    }
+    return m;
+}
+
+static apr_status_t skiplist_free_node(apr_skiplist *sl, apr_skiplistnode *m)
+{
+    return skiplist_qpush(&sl->nodes_q, m);
+}
+
 static apr_status_t skiplisti_init(apr_skiplist **s, apr_pool_t *p)
 {
     apr_skiplist *sl;
     if (p) {
         sl = apr_pcalloc(p, sizeof(apr_skiplist));
         sl->memlist = apr_array_make(p, 20, sizeof(memlist_t));
+        sl->pool = sl->nodes_q.p = sl->stack_q.p = p;
     }
     else {
         sl = calloc(1, sizeof(apr_skiplist));
+        if (!sl) {
+            return APR_ENOMEM;
+        }
     }
-#if 0
-    sl->compare = (apr_skiplist_compare) NULL;
-    sl->comparek = (apr_skiplist_compare) NULL;
-    sl->height = 0;
-    sl->preheight = 0;
-    sl->size = 0;
-    sl->top = NULL;
-    sl->bottom = NULL;
-    sl->index = NULL;
-#endif
-    sl->pool = p;
     *s = sl;
     return APR_SUCCESS;
 }
@@ -248,56 +297,32 @@ APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl,
     }
 }
 
-APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl)
-{
-    if (!sl->bottom) {
-        return NULL;
-    }
-    return sl->bottom->next;
-}
-
-APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter)
-{
-    void *ret;
-    apr_skiplistnode *aiter;
-    if (!sl->compare) {
-        return 0;
-    }
-    if (iter) {
-        ret = apr_skiplist_find_compare(sl, data, iter, sl->compare);
-    }
-    else {
-        ret = apr_skiplist_find_compare(sl, data, &aiter, sl->compare);
-    }
-    return ret;
-}
-
 static int skiplisti_find_compare(apr_skiplist *sl, void *data,
                            apr_skiplistnode **ret,
                            apr_skiplist_compare comp)
 {
-    apr_skiplistnode *m = NULL;
     int count = 0;
+    apr_skiplistnode *m;
     m = sl->top;
     while (m) {
-        int compared;
-        compared = (m->next) ? comp(data, m->next->data) : -1;
-        if (compared == 0) {
-            m = m->next;
-            while (m->down) {
-                m = m->down;
+        if (m->next) {
+            int compared = comp(data, m->next->data);
+            if (compared == 0) {
+                m = m->next;
+                while (m->down) {
+                    m = m->down;
+                }
+                *ret = m;
+                return count;
+            }
+            if (compared > 0) {
+                m = m->next;
+                count++;
+                continue;
             }
-            *ret = m;
-            return count;
-        }
-        if ((m->next == NULL) || (compared < 0)) {
-            m = m->down;
-            count++;
-        }
-        else {
-            m = m->next;
-            count++;
         }
+        m = m->down;
+        count++;
     }
     *ret = NULL;
     return count;
@@ -307,19 +332,47 @@ APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sli, void *data,
                                apr_skiplistnode **iter,
                                apr_skiplist_compare comp)
 {
-    apr_skiplistnode *m = NULL;
+    apr_skiplistnode *m;
     apr_skiplist *sl;
+    if (!comp) {
+        if (iter) {
+            *iter = NULL;
+        }
+        return NULL;
+    }
     if (comp == sli->compare || !sli->index) {
         sl = sli;
     }
     else {
         apr_skiplist_find(sli->index, (void *)comp, &m);
+        if (!m) {
+            if (iter) {
+                *iter = NULL;
+            }
+            return NULL;
+        }
         sl = (apr_skiplist *) m->data;
     }
-    skiplisti_find_compare(sl, data, iter, sl->comparek);
-    return (iter && *iter) ? ((*iter)->data) : NULL;
+    skiplisti_find_compare(sl, data, &m, sl->comparek);
+    if (iter) {
+        *iter = m;
+    }
+    return (m) ? m->data : NULL;
 }
 
+APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter)
+{
+    return apr_skiplist_find_compare(sl, data, iter, sl->compare);
+}
+
+
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl)
+{
+    if (!sl->bottom) {
+        return NULL;
+    }
+    return sl->bottom->next;
+}
 
 APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter)
 {
@@ -339,98 +392,74 @@ APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **i
     return (*iter) ? ((*iter)->data) : NULL;
 }
 
-APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist *sl, void *data)
+static APR_INLINE int skiplist_height(const apr_skiplist *sl)
 {
-    if (!sl->compare) {
-        return 0;
-    }
-    return apr_skiplist_insert_compare(sl, data, sl->compare);
+    /* Skiplists (even empty) always have a top node, although this
+     * implementation defers its creation until the first insert, or
+     * deletes it with the last remove. We want the real height here.
+     */
+    return sl->height ? sl->height : 1;
 }
 
 APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, void *data,
                                       apr_skiplist_compare comp)
 {
-    apr_skiplistnode *m, *p, *tmp, *ret = NULL, **stack;
-    int nh = 1, ch, stacki;
-    if (!sl->top) {
-        sl->height = 1;
-        sl->topend = sl->bottomend = sl->top = sl->bottom =
-            (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
-#if 0
-        sl->top->next = (apr_skiplistnode *)NULL;
-        sl->top->data = (apr_skiplistnode *)NULL;
-        sl->top->prev = (apr_skiplistnode *)NULL;
-        sl->top->up = (apr_skiplistnode *)NULL;
-        sl->top->down = (apr_skiplistnode *)NULL;
-        sl->top->nextindex = (apr_skiplistnode *)NULL;
-        sl->top->previndex = (apr_skiplistnode *)NULL;
-#endif
-        sl->top->sl = sl;
+    apr_skiplistnode *m, *p, *tmp, *ret = NULL;
+    int ch, nh = 1;
+
+    if (!comp) {
+        return NULL;
     }
+
+    ch = skiplist_height(sl);
     if (sl->preheight) {
         while (nh < sl->preheight && get_b_rand()) {
             nh++;
         }
     }
     else {
-        while (nh <= sl->height && get_b_rand()) {
+        while (nh <= ch && get_b_rand()) {
             nh++;
         }
     }
-    /* Now we have the new height at which we wish to insert our new node */
-    /*
-     * Let us make sure that our tree is a least that tall (grow if
-     * necessary)
+
+    /* Now we have in nh the height at which we wish to insert our new node,
+     * and in ch the current height: don't create skip paths to the inserted
+     * element until the walk down through the tree (which decrements ch)
+     * reaches nh. From there, any walk down pushes the current node on a
+     * stack (the node(s) after which we would insert) to pop back through
+     * for insertion later.
      */
-    for (; sl->height < nh; sl->height++) {
-        sl->top->up =
-            (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
-        sl->top->up->down = sl->top;
-        sl->top = sl->topend = sl->top->up;
-#if 0
-        sl->top->prev = sl->top->next = sl->top->nextindex =
-            sl->top->previndex = sl->top->up = NULL;
-        sl->top->data = NULL;
-#endif
-        sl->top->sl = sl;
-    }
-    ch = sl->height;
-    /* Find the node (or node after which we would insert) */
-    /* Keep a stack to pop back through for insertion */
-    /* malloc() is OK since we free the temp stack */
     m = sl->top;
-    stack = (apr_skiplistnode **)malloc(sizeof(apr_skiplistnode *) * (nh));
-    stacki = 0;
     while (m) {
-        int compared = -1;
         if (m->next) {
-            compared = comp(data, m->next->data);
-        }
-        if (compared == 0) {
-            free(stack);    /* OK. was malloc'ed */
-            return 0;
-        }
-        if ((m->next == NULL) || (compared < 0)) {
-            if (ch <= nh) {
-                /* push on stack */
-                stack[stacki++] = m;
+            int compared = comp(data, m->next->data);
+            if (compared == 0) {
+                /* Keep the existing element(s) */
+                skiplist_qclear(&sl->stack_q);
+                return NULL;
+            }
+            if (compared > 0) {
+                m = m->next;
+                continue;
             }
-            m = m->down;
-            ch--;
         }
-        else {
-            m = m->next;
+        if (ch <= nh) {
+            /* push on stack */
+            skiplist_qpush(&sl->stack_q, m);
         }
+        m = m->down;
+        ch--;
     }
     /* Pop the stack and insert nodes */
     p = NULL;
-    for (; stacki > 0; stacki--) {
-        m = stack[stacki - 1];
-        tmp = (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
+    while ((m = skiplist_qpop(&sl->stack_q))) {
+        tmp = skiplist_new_node(sl);
         tmp->next = m->next;
         if (m->next) {
             m->next->prev = tmp;
         }
+        m->next = tmp;
         tmp->prev = m;
         tmp->up = NULL;
         tmp->nextindex = tmp->previndex = NULL;
@@ -438,17 +467,44 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, vo
         if (p) {
             p->up = tmp;
         }
+        else {
+            /* This sets ret to the bottom-most node we are inserting */
+            ret = tmp;
+        }
         tmp->data = data;
         tmp->sl = sl;
+        p = tmp;
+    }
+
+    /* Now we are sure the node is inserted, grow our tree to 'nh' tall */
+    for (; sl->height < nh; sl->height++) {
+        m = skiplist_new_node(sl);
+        tmp = skiplist_new_node(sl);
+        m->up = m->prev = m->nextindex = m->previndex = NULL;
         m->next = tmp;
-        /* This sets ret to the bottom-most node we are inserting */
-        if (!p) {
+        m->down = sl->top;
+        m->data = NULL;
+        m->sl = sl;
+        if (sl->top) {
+            sl->top->up = m;
+        }
+        else {
+            sl->bottom = sl->bottomend = m;
+        }
+        sl->top = sl->topend = tmp->prev = m;
+        tmp->up = tmp->next = tmp->nextindex = tmp->previndex = NULL;
+        tmp->down = p;
+        tmp->data = data;
+        tmp->sl = sl;
+        if (p) {
+            p->up = tmp;
+        }
+        else {
+            /* This sets ret to the bottom-most node we are inserting */
             ret = tmp;
-            sl->size++; /* this seems to go here got each element to be counted */
         }
         p = tmp;
     }
-    free(stack); /* OK. was malloc'ed */
     if (sl->index != NULL) {
         /*
          * this is a external insertion, we must insert into each index as
@@ -457,25 +513,20 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, vo
         apr_skiplistnode *ni, *li;
         li = ret;
         for (p = apr_skiplist_getlist(sl->index); p; apr_skiplist_next(sl->index, &p)) {
-            ni = apr_skiplist_insert((apr_skiplist *) p->data, ret->data);
+            apr_skiplist *sli = (apr_skiplist *)p->data;
+            ni = apr_skiplist_insert_compare(sli, ret->data, sli->compare);
             li->nextindex = ni;
             ni->previndex = li;
             li = ni;
         }
     }
-    else {
-        /* sl->size++; */
-    }
     sl->size++;
     return ret;
 }
 
-APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree)
+APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist *sl, void *data)
 {
-    if (!sl->compare) {
-        return 0;
-    }
-    return apr_skiplist_remove_compare(sl, data, myfree, sl->comparek);
+    return apr_skiplist_insert_compare(sl, data, sl->compare);
 }
 
 #if 0
@@ -520,7 +571,7 @@ static int skiplisti_remove(apr_skiplist *sl, apr_skiplistnode *m, apr_skiplist_
         if (!m && myfree && p->data) {
             myfree(p->data);
         }
-        apr_skiplist_free(sl, p);
+        skiplist_free_node(sl, p);
     }
     sl->size--;
     while (sl->top && sl->top->next == NULL) {
@@ -530,13 +581,14 @@ static int skiplisti_remove(apr_skiplist *sl, apr_skiplistnode *m, apr_skiplist_
         if (sl->top) {
             sl->top->up = NULL; /* Make it think its the top */
         }
-        apr_skiplist_free(sl, p);
+        skiplist_free_node(sl, p);
         sl->height--;
     }
     if (!sl->top) {
-        sl->bottom = NULL;
+        sl->bottom = sl->bottomend = NULL;
+        sl->topend = NULL;
     }
-    return sl->height;  /* return 1; ?? */
+    return skiplist_height(sl);
 }
 
 APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
@@ -545,11 +597,17 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
 {
     apr_skiplistnode *m;
     apr_skiplist *sl;
+    if (!comp) {
+        return 0;
+    }
     if (comp == sli->comparek || !sli->index) {
         sl = sli;
     }
     else {
         apr_skiplist_find(sli->index, (void *)comp, &m);
+        if (!m) {
+            return 0;
+        }
         sl = (apr_skiplist *) m->data;
     }
     skiplisti_find_compare(sl, data, &m, comp);
@@ -562,6 +620,11 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
     return skiplisti_remove(sl, m, myfree);
 }
 
+APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree)
+{
+    return apr_skiplist_remove_compare(sl, data, myfree, sl->comparek);
+}
+
 APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree)
 {
     /*
@@ -573,16 +636,18 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefun
     m = sl->bottom;
     while (m) {
         p = m->next;
-        if (p && myfree && p->data)
+        if (myfree && p && p->data) {
             myfree(p->data);
-        while (m) {
+        }
+        do {
             u = m->up;
-            apr_skiplist_free(sl, p);
+            skiplist_free_node(sl, m);
             m = u;
-        }
+        } while (m);
         m = p;
     }
     sl->top = sl->bottom = NULL;
+    sl->topend = sl->bottomend = NULL;
     sl->height = 0;
     sl->size = 0;
 }
@@ -611,8 +676,7 @@ APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *a)
 
 static void skiplisti_destroy(void *vsl)
 {
-    apr_skiplist_destroy((apr_skiplist *) vsl, NULL);
-    apr_skiplist_free((apr_skiplist *) vsl, vsl);
+    apr_skiplist_destroy(vsl, NULL);
 }
 
 APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree)
@@ -620,6 +684,13 @@ APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc m
     while (apr_skiplist_pop(sl->index, skiplisti_destroy) != NULL)
         ;
     apr_skiplist_remove_all(sl, myfree);
+    if (!sl->pool) {
+        while (sl->nodes_q.pos)
+            free(sl->nodes_q.data[--sl->nodes_q.pos]);
+        free(sl->nodes_q.data);
+        free(sl->stack_q.data);
+        free(sl);
+    }
 }
 
 APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2)
diff --git a/test/Makefile.in b/test/Makefile.in
index 8883e31..7289851 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -29,7 +29,7 @@ TESTS = testtime.lo teststr.lo testvsn.lo testipsub.lo testshm.lo \
 	testhash.lo testargs.lo testnames.lo testuser.lo testpath.lo \
 	testenv.lo testprocmutex.lo testfnmatch.lo testatomic.lo testflock.lo \
 	testsock.lo testglobalmutex.lo teststrnatcmp.lo testfilecopy.lo \
-	testtemp.lo testlfs.lo testcond.lo testescape.lo
+	testtemp.lo testlfs.lo testcond.lo testescape.lo testskiplist.lo
 
 OTHER_PROGRAMS = \
 	echod at EXEEXT@ \
diff --git a/test/Makefile.win b/test/Makefile.win
index 95ead5c..e86b29b 100644
--- a/test/Makefile.win
+++ b/test/Makefile.win
@@ -98,7 +98,8 @@ ALL_TESTS = $(INTDIR)\testutil.obj $(INTDIR)\testtime.obj \
 	$(INTDIR)\testsock.obj $(INTDIR)\testglobalmutex.obj \
 	$(INTDIR)\teststrnatcmp.obj $(INTDIR)\testfilecopy.obj \
 	$(INTDIR)\testtemp.obj $(INTDIR)\testlfs.obj \
-	$(INTDIR)\testcond.obj $(INTDIR)\testescape.obj
+	$(INTDIR)\testcond.obj $(INTDIR)\testescape.obj \
+	$(INTDIR)\testskiplist.obj
 
 CLEAN_DATA = testfile.tmp lfstests\large.bin \
 	data\testputs.txt data\testbigfprintf.dat \
diff --git a/test/NWGNUaprtest b/test/NWGNUaprtest
index b142796..6aaeafd 100644
--- a/test/NWGNUaprtest
+++ b/test/NWGNUaprtest
@@ -176,6 +176,7 @@ FILES_nlm_objs = \
 	$(OBJDIR)/testdup.o \
 	$(OBJDIR)/testdso.o \
 	$(OBJDIR)/testenv.o \
+	$(OBJDIR)/testescape.o \
 	$(OBJDIR)/testfilecopy.o \
 	$(OBJDIR)/testfileinfo.o \
 	$(OBJDIR)/testfile.o \
@@ -199,6 +200,7 @@ FILES_nlm_objs = \
 	$(OBJDIR)/testprocmutex.o \
 	$(OBJDIR)/testrand.o \
 	$(OBJDIR)/testshm.o \
+	$(OBJDIR)/testskiplist.o \
 	$(OBJDIR)/testsleep.o \
 	$(OBJDIR)/testsock.o \
 	$(OBJDIR)/testsockets.o \
diff --git a/test/abts_tests.h b/test/abts_tests.h
index 4d94925..90ddc4f 100644
--- a/test/abts_tests.h
+++ b/test/abts_tests.h
@@ -67,7 +67,8 @@ const struct testlist {
     {testtime},
     {testud},
     {testuser},
-    {testvsn}
+    {testvsn},
+    {testskiplist}
 };
 
 #endif /* APR_TEST_INCLUDES */
diff --git a/test/testatomic.c b/test/testatomic.c
index ca0398a..b3862a8 100644
--- a/test/testatomic.c
+++ b/test/testatomic.c
@@ -205,7 +205,7 @@ static void test_wrap_zero(abts_case *tc, void *data)
 {
     apr_uint32_t y32;
     apr_uint32_t rv;
-    apr_uint32_t minus1 = -1;
+    apr_uint32_t minus1 = (apr_uint32_t)-1;
     char *str;
 
     apr_atomic_set32(&y32, 0);
@@ -218,8 +218,8 @@ static void test_wrap_zero(abts_case *tc, void *data)
 
 static void test_inc_neg1(abts_case *tc, void *data)
 {
-    apr_uint32_t y32 = -1;
-    apr_uint32_t minus1 = -1;
+    apr_uint32_t y32 = (apr_uint32_t)-1;
+    apr_uint32_t minus1 = (apr_uint32_t)-1;
     apr_uint32_t rv;
     char *str;
 
diff --git a/test/testdll.dsp b/test/testdll.dsp
index 9736fc9..a5e3975 100644
--- a/test/testdll.dsp
+++ b/test/testdll.dsp
@@ -311,6 +311,10 @@ SOURCE=.\testshm.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\testskiplist.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\testsleep.c
 # End Source File
 # Begin Source File
diff --git a/test/testlib.dsp b/test/testlib.dsp
index d3ab7aa..7dcff44 100644
--- a/test/testlib.dsp
+++ b/test/testlib.dsp
@@ -311,6 +311,10 @@ SOURCE=.\testshm.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\testskiplist.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\testsleep.c
 # End Source File
 # Begin Source File
diff --git a/test/testpoll.c b/test/testpoll.c
index dc20949..8409584 100644
--- a/test/testpoll.c
+++ b/test/testpoll.c
@@ -42,6 +42,11 @@ static apr_pollfd_t *pollarray;
 static apr_pollfd_t *pollarray_large;
 #endif
 
+/* default_pollset_impl can be overridden temporarily to control
+ * testcases which don't specify an implementation explicitly
+ */
+static int default_pollset_impl = APR_POLLSET_DEFAULT;
+
 static void make_socket(apr_socket_t **sock, apr_sockaddr_t **sa, 
                         apr_port_t port, apr_pool_t *p, abts_case *tc)
 {
@@ -287,7 +292,8 @@ static void recv_large_pollarray(abts_case *tc, void *data)
 static void setup_pollset(abts_case *tc, void *data)
 {
     apr_status_t rv;
-    rv = apr_pollset_create(&pollset, LARGE_NUM_SOCKETS, p, 0);
+    rv = apr_pollset_create_ex(&pollset, LARGE_NUM_SOCKETS, p, 0,
+                               default_pollset_impl);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 }
 
@@ -492,7 +498,8 @@ static void pollset_remove(abts_case *tc, void *data)
     apr_pollfd_t pfd;
     apr_int32_t num;
 
-    rv = apr_pollset_create(&pollset, 5, p, 0);
+    rv = apr_pollset_create_ex(&pollset, 5, p, 0,
+                               default_pollset_impl);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
     pfd.p = p;
@@ -769,6 +776,47 @@ static void pollcb_default(abts_case *tc, void *data)
     }
 }
 
+static void pollset_wakeup(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+    apr_pollfd_t socket_pollfd;
+    apr_pollset_t *pollset;
+    apr_int32_t num;
+    const apr_pollfd_t *descriptors;
+
+    rv = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_WAKEABLE,
+                               default_pollset_impl);
+    if (rv == APR_ENOTIMPL) {
+        ABTS_NOT_IMPL(tc, "apr_pollset_wakeup() not supported");
+        return;
+    }
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+    /* send wakeup but no data; apr_pollset_poll() should return APR_EINTR */
+    rv = apr_pollset_wakeup(pollset);
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+    rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
+    ABTS_INT_EQUAL(tc, APR_EINTR, rv);
+
+    /* send wakeup and data; apr_pollset_poll() should return APR_SUCCESS */
+    socket_pollfd.desc_type = APR_POLL_SOCKET;
+    socket_pollfd.reqevents = APR_POLLIN;
+    socket_pollfd.desc.s = s[0];
+    socket_pollfd.client_data = s[0];
+    rv = apr_pollset_add(pollset, &socket_pollfd);
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+    send_msg(s, sa, 0, tc);
+
+    rv = apr_pollset_wakeup(pollset);
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+    rv = apr_pollset_poll(pollset, -1, &num, &descriptors);
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+    ABTS_INT_EQUAL(tc, 1, num);
+}
+
 static void justsleep(abts_case *tc, void *data)
 {
     apr_int32_t nsds;
@@ -868,6 +916,7 @@ abts_suite *testpoll(abts_suite *suite)
     abts_run_test(suite, trigger_pollcb, NULL);
     abts_run_test(suite, timeout_pollcb, NULL);
     abts_run_test(suite, timeout_pollin_pollcb, NULL);
+    abts_run_test(suite, pollset_wakeup, NULL);
     abts_run_test(suite, close_all_sockets, NULL);
     abts_run_test(suite, pollset_default, NULL);
     abts_run_test(suite, pollcb_default, NULL);
diff --git a/test/testskiplist.c b/test/testskiplist.c
new file mode 100644
index 0000000..b841561
--- /dev/null
+++ b/test/testskiplist.c
@@ -0,0 +1,448 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 "testutil.h"
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_general.h"
+#include "apr_pools.h"
+#include "apr_skiplist.h"
+#if APR_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+
+static apr_pool_t *ptmp = NULL;
+static apr_skiplist *skiplist = NULL;
+
+/* apr_skiplist_add[_compare]() are missing in 1.5.x,
+ * so emulate them (not thread-safe!)...
+ */
+static apr_skiplist_compare current_comp;
+static int add_comp(void *a, void *b)
+{
+    return current_comp(a, b) < 0 ? -1 : +1;
+}
+static apr_skiplistnode *apr_skiplist_add_compare(apr_skiplist *sl, void *data,
+                                                  apr_skiplist_compare comp)
+{
+    current_comp = comp;
+    return apr_skiplist_insert_compare(sl, data, add_comp);
+}
+static apr_skiplistnode *apr_skiplist_add(apr_skiplist *sl, void *data)
+{
+    /* Ugly, really, but should work *as long as* the compare function is the
+     * first field of the (opaque) skiplist struct, this is the case for now :p
+     */
+    return apr_skiplist_add_compare(sl, data, *(apr_skiplist_compare*)sl);
+}
+
+static int skiplist_get_size(abts_case *tc, apr_skiplist *sl)
+{
+    size_t size = 0;
+    apr_skiplistnode *n;
+    for (n = apr_skiplist_getlist(sl); n; apr_skiplist_next(sl, &n)) {
+        ++size;
+    }
+    return size;
+}
+
+static void skiplist_init(abts_case *tc, void *data)
+{
+    apr_time_t now = apr_time_now();
+    srand((unsigned int)(((now >> 32) ^ now) & 0xffffffff));
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, apr_skiplist_init(&skiplist, p));
+    ABTS_PTR_NOTNULL(tc, skiplist);
+    apr_skiplist_set_compare(skiplist, (apr_skiplist_compare)strcmp,
+                                       (apr_skiplist_compare)strcmp);
+}
+
+static void skiplist_find(abts_case *tc, void *data)
+{
+    const char *val;
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "baton"));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "baton", val);
+}
+
+static void skiplist_dontfind(abts_case *tc, void *data)
+{
+    const char *val;
+
+    val = apr_skiplist_find(skiplist, "keynotthere", NULL);
+    ABTS_PTR_EQUAL(tc, NULL, (void *)val);
+}
+
+static void skiplist_insert(abts_case *tc, void *data)
+{
+    const char *val;
+    int i;
+
+    for (i = 0; i < 10; ++i) {
+        ABTS_PTR_EQUAL(tc, NULL, apr_skiplist_insert(skiplist, "baton"));
+        ABTS_TRUE(tc, 1 == skiplist_get_size(tc, skiplist));
+        val = apr_skiplist_find(skiplist, "baton", NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, "baton", val);
+    }
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "foo"));
+    ABTS_TRUE(tc, 2 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "foo", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "foo", val);
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "atfirst"));
+    ABTS_TRUE(tc, 3 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "atfirst", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "atfirst", val);
+}
+
+static void skiplist_add(abts_case *tc, void *data)
+{
+    const char *val;
+    size_t i, n = skiplist_get_size(tc, skiplist);
+
+    for (i = 0; i < 100; ++i) {
+        n++;
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "daton"));
+        ABTS_TRUE(tc, n == skiplist_get_size(tc, skiplist));
+        val = apr_skiplist_find(skiplist, "daton", NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, "daton", val);
+
+        n++;
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "baton"));
+        ABTS_TRUE(tc, n == skiplist_get_size(tc, skiplist));
+        val = apr_skiplist_find(skiplist, "baton", NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, "baton", val);
+
+        n++;
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "caton"));
+        ABTS_TRUE(tc, n == skiplist_get_size(tc, skiplist));
+        val = apr_skiplist_find(skiplist, "caton", NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, "caton", val);
+
+        n++;
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "aaton"));
+        ABTS_TRUE(tc, n == skiplist_get_size(tc, skiplist));
+        val = apr_skiplist_find(skiplist, "aaton", NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, "aaton", val);
+    }
+}
+
+static void skiplist_destroy(abts_case *tc, void *data)
+{
+    apr_skiplist_destroy(skiplist, NULL);
+    ABTS_TRUE(tc, 0 == skiplist_get_size(tc, skiplist));
+}
+
+static void skiplist_size(abts_case *tc, void *data)
+{
+    const char *val;
+
+    ABTS_TRUE(tc, 0 == skiplist_get_size(tc, skiplist));
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "abc"));
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "ghi"));
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(skiplist, "def"));
+    val = apr_skiplist_find(skiplist, "abc", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "abc", val);
+    val = apr_skiplist_find(skiplist, "ghi", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "ghi", val);
+    val = apr_skiplist_find(skiplist, "def", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "def", val);
+
+    ABTS_TRUE(tc, 3 == skiplist_get_size(tc, skiplist));
+    apr_skiplist_destroy(skiplist, NULL);
+}
+
+static void skiplist_remove(abts_case *tc, void *data)
+{
+    const char *val;
+
+    ABTS_TRUE(tc, 0 == skiplist_get_size(tc, skiplist));
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "baton"));
+    ABTS_TRUE(tc, 1 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "baton", val);
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "baton"));
+    ABTS_TRUE(tc, 2 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "baton", val);
+
+    ABTS_TRUE(tc, apr_skiplist_remove(skiplist, "baton", NULL) != 0);
+    ABTS_TRUE(tc, 1 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "baton", val);
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_add(skiplist, "baton"));
+    ABTS_TRUE(tc, 2 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_NOTNULL(tc, val);
+    ABTS_STR_EQUAL(tc, "baton", val);
+
+    /* remove all "baton"s */
+    while (apr_skiplist_remove(skiplist, "baton", NULL))
+        ;
+    ABTS_TRUE(tc, 0 == skiplist_get_size(tc, skiplist));
+    val = apr_skiplist_find(skiplist, "baton", NULL);
+    ABTS_PTR_EQUAL(tc, NULL, val);
+}
+
+#define NUM_RAND (100)
+#define NUM_FIND (3 * NUM_RAND)
+static void skiplist_random_loop(abts_case *tc, void *data)
+{
+    char **batons;
+    apr_skiplist *sl;
+    const char *val;
+    int i;
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, apr_skiplist_init(&sl, ptmp));
+    apr_skiplist_set_compare(sl, (apr_skiplist_compare)strcmp,
+                                 (apr_skiplist_compare)strcmp);
+
+    batons = apr_palloc(ptmp, NUM_FIND * sizeof(char*));
+
+    for (i = 0; i < NUM_FIND; ++i) {
+        if (i < NUM_RAND) {
+            batons[i] = apr_psprintf(ptmp, "%.6u", rand() % 1000000);
+        }
+        else {
+            batons[i] = apr_pstrdup(ptmp, batons[i % NUM_RAND]);
+        }
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_add(sl, batons[i]));
+        val = apr_skiplist_find(sl, batons[i], NULL);
+        ABTS_PTR_NOTNULL(tc, val);
+        ABTS_STR_EQUAL(tc, batons[i], val);
+    }
+
+    apr_pool_clear(ptmp);
+}
+
+typedef struct elem {
+    int b;
+    int a;
+} elem;
+
+
+static void add_int_to_skiplist(abts_case *tc, apr_skiplist *list, int n){
+    int* a = apr_skiplist_alloc(list, sizeof(int));
+    *a = n;
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(list, a));
+}
+
+static void add_elem_to_skiplist(abts_case *tc, apr_skiplist *list, elem n){
+    elem* a = apr_skiplist_alloc(list, sizeof(elem));
+    *a = n;
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(list, a));
+}
+
+static int comp(void *a, void *b){
+    return (*((int*) a) < *((int*) b)) ? -1 : 1;
+}
+
+static int scomp(void *a, void *b){
+    return (((elem*) a)->a < ((elem*) b)->a) ? -1 : 1;
+}
+
+static int ecomp(void *a, void *b)
+{
+    elem const * const e1 = a;
+    elem const * const e2 = b;
+    if (e1->a < e2->a) {
+        return -1;
+    }
+    else if (e1->a > e2->a) {
+        return +1;
+    }
+    else if (e1->b < e2->b) {
+        return -1;
+    }
+    else if (e1->b > e2->b) {
+        return +1;
+    }
+    else {
+        return 0;
+    }
+}
+
+static void skiplist_test(abts_case *tc, void *data) {
+    int test_elems = 10;
+    int i = 0, j = 0;
+    int *val = NULL;
+    elem *val2 = NULL;
+    apr_skiplist * list = NULL;
+    apr_skiplist * list2 = NULL;
+    apr_skiplist * list3 = NULL;
+    int first_forty_two = 42,
+        second_forty_two = 42;
+    apr_array_header_t *array;
+    elem t1, t2, t3, t4, t5;
+    t1.a = 1; t1.b = 1;
+    t2.a = 42; t2.b = 1;
+    t3.a = 42; t3.b = 2;
+    t4.a = 42; t4.b = 3;
+    t5.a = 142; t5.b = 1;
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, apr_skiplist_init(&list, ptmp));
+    apr_skiplist_set_compare(list, comp, comp);
+    
+    /* insert 10 objects */
+    for (i = 0; i < test_elems; ++i){
+        add_int_to_skiplist(tc, list, i);
+    }
+
+    /* remove all objects */
+    while ((val = apr_skiplist_pop(list, NULL))){
+        ABTS_INT_EQUAL(tc, *val, j++);
+    }
+
+    /* insert 10 objects again */
+    for (i = test_elems; i < test_elems+test_elems; ++i){
+        add_int_to_skiplist(tc, list, i);
+    }
+
+    j = test_elems;
+    while ((val = apr_skiplist_pop(list, NULL))){
+        ABTS_INT_EQUAL(tc, *val, j++);
+    }
+
+    /* empty */
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_PTR_EQUAL(tc, val, NULL);
+
+    add_int_to_skiplist(tc, list, 42);
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_INT_EQUAL(tc, *val, 42); 
+
+    /* empty */
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_PTR_EQUAL(tc, val, NULL);
+
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_add(list, &first_forty_two));
+    add_int_to_skiplist(tc, list, 1);
+    add_int_to_skiplist(tc, list, 142);
+    ABTS_PTR_NOTNULL(tc, apr_skiplist_add(list, &second_forty_two));
+    val = apr_skiplist_peek(list);
+    ABTS_INT_EQUAL(tc, *val, 1);
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_INT_EQUAL(tc, *val, 1);
+    val = apr_skiplist_peek(list);
+    ABTS_PTR_EQUAL(tc, val, &first_forty_two);
+    ABTS_INT_EQUAL(tc, *val, 42);
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_PTR_EQUAL(tc, val, &first_forty_two);
+    ABTS_INT_EQUAL(tc, *val, 42);
+    val = apr_skiplist_pop(list, NULL);
+    ABTS_PTR_EQUAL(tc, val, &second_forty_two);
+    ABTS_INT_EQUAL(tc, *val, 42);
+    val = apr_skiplist_peek(list);
+    ABTS_INT_EQUAL(tc, *val, 142);
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, apr_skiplist_init(&list2, ptmp));
+    apr_skiplist_set_compare(list2, scomp, scomp);
+    add_elem_to_skiplist(tc, list2, t2);
+    add_elem_to_skiplist(tc, list2, t1);
+    add_elem_to_skiplist(tc, list2, t3);
+    add_elem_to_skiplist(tc, list2, t5);
+    add_elem_to_skiplist(tc, list2, t4);
+    val2 = apr_skiplist_pop(list2, NULL);
+    ABTS_INT_EQUAL(tc, val2->a, 1);
+    val2 = apr_skiplist_pop(list2, NULL);
+    ABTS_INT_EQUAL(tc, val2->a, 42);
+    ABTS_INT_EQUAL(tc, val2->b, 1);
+    val2 = apr_skiplist_pop(list2, NULL);
+    ABTS_INT_EQUAL(tc, val2->a, 42);
+    ABTS_INT_EQUAL(tc, val2->b, 2);
+    val2 = apr_skiplist_pop(list2, NULL);
+    ABTS_INT_EQUAL(tc, val2->a, 42);
+    ABTS_INT_EQUAL(tc, val2->b, 3);
+    val2 = apr_skiplist_pop(list2, NULL);
+    ABTS_INT_EQUAL(tc, val2->a, 142);
+    ABTS_INT_EQUAL(tc, val2->b, 1);
+
+    ABTS_INT_EQUAL(tc, APR_SUCCESS, apr_skiplist_init(&list3, ptmp));
+    apr_skiplist_set_compare(list3, ecomp, ecomp);
+    array = apr_array_make(ptmp, 10, sizeof(elem *));
+    for (i = 0; i < 10; ++i) {
+        elem *e = apr_palloc(ptmp, sizeof *e);
+        e->a = 4224;
+        e->b = i;
+        APR_ARRAY_PUSH(array, elem *) = e;
+        ABTS_PTR_NOTNULL(tc, apr_skiplist_insert(list3, e));
+    }
+    for (i = 0; i < 5; ++i) {
+        elem *e = APR_ARRAY_IDX(array, i, elem *);
+        val2 = apr_skiplist_find(list3, e, NULL);
+        ABTS_PTR_EQUAL(tc, e, val2);
+        ABTS_TRUE(tc, apr_skiplist_remove(list3, e, NULL) != 0);
+    }
+    for (i = 0; i < 5; ++i) {
+        elem *e = APR_ARRAY_IDX(array, 9 - i, elem *);
+        val2 = apr_skiplist_find(list3, e, NULL);
+        ABTS_PTR_EQUAL(tc, e, val2);
+        ABTS_TRUE(tc, apr_skiplist_remove(list3, e, NULL) != 0);
+    }
+
+    apr_pool_clear(ptmp);
+}
+
+
+abts_suite *testskiplist(abts_suite *suite)
+{
+    suite = ADD_SUITE(suite)
+
+    apr_pool_create(&ptmp, p);
+
+    abts_run_test(suite, skiplist_init, NULL);
+    abts_run_test(suite, skiplist_find, NULL);
+    abts_run_test(suite, skiplist_dontfind, NULL);
+    abts_run_test(suite, skiplist_insert, NULL);
+    abts_run_test(suite, skiplist_add, NULL);
+    abts_run_test(suite, skiplist_destroy, NULL);
+    abts_run_test(suite, skiplist_size, NULL);
+    abts_run_test(suite, skiplist_remove, NULL);
+    abts_run_test(suite, skiplist_random_loop, NULL);
+
+    abts_run_test(suite, skiplist_test, NULL);
+
+    apr_pool_destroy(ptmp);
+
+    return suite;
+}
+
diff --git a/test/testutil.h b/test/testutil.h
index 08907c9..4b10ed3 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -103,5 +103,6 @@ abts_suite *testtime(abts_suite *suite);
 abts_suite *testud(abts_suite *suite);
 abts_suite *testuser(abts_suite *suite);
 abts_suite *testvsn(abts_suite *suite);
+abts_suite *testskiplist(abts_suite *suite);
 
 #endif /* APR_TEST_INCLUDES */
diff --git a/threadproc/netware/thread.c b/threadproc/netware/thread.c
index e1a46e6..f983668 100644
--- a/threadproc/netware/thread.c
+++ b/threadproc/netware/thread.c
@@ -77,7 +77,7 @@ apr_status_t apr_thread_create(apr_thread_t **new,
                                apr_pool_t *pool)
 {
     apr_status_t stat;
-    long flags = NX_THR_BIND_CONTEXT;
+    unsigned long flags = NX_THR_BIND_CONTEXT;
     char threadName[NX_MAX_OBJECT_NAME_LEN+1];
     size_t stack_size = APR_DEFAULT_STACK_SIZE;
 
@@ -120,8 +120,8 @@ apr_status_t apr_thread_create(apr_thread_t **new,
         /* void(*start_routine)(void *arg) */ (void (*)(void *)) dummy_worker,
         /* void *arg */                       (*new),
         /* int priority */                    NX_PRIO_MED,
-        /* NXSize_t stackSize */              stack_size,
-        /* long flags */                      NX_CTX_NORMAL,
+        /* size_t stackSize */                stack_size,
+        /* unsigned long flags */             NX_CTX_NORMAL,
         /* int *error */                      &stat);
 
     stat = NXContextSetName(
@@ -130,7 +130,7 @@ apr_status_t apr_thread_create(apr_thread_t **new,
 
     stat = NXThreadCreate(
         /* NXContext_t context */     (*new)->ctx,
-        /* long flags */              flags,
+        /* unsigned long flags */     flags,
         /* NXThreadId_t *thread_id */ &(*new)->td);
 
     if (stat == 0)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-apache/apr.git



More information about the Pkg-apache-commits mailing list