You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by iv...@apache.org on 2019/05/27 17:11:23 UTC

svn commit: r1860149 - in /apr/apr/branches/xmllite: ./ file_io/win32/ include/arch/win32/ locks/win32/ misc/win32/ user/win32/

Author: ivan
Date: Mon May 27 17:11:23 2019
New Revision: 1860149

URL: http://svn.apache.org/viewvc?rev=1860149&view=rev
Log:
On 'xmllite' branch: Merge changes from trunk.

Modified:
    apr/apr/branches/xmllite/   (props changed)
    apr/apr/branches/xmllite/CHANGES
    apr/apr/branches/xmllite/file_io/win32/open.c
    apr/apr/branches/xmllite/file_io/win32/pipe.c
    apr/apr/branches/xmllite/file_io/win32/readwrite.c
    apr/apr/branches/xmllite/include/arch/win32/apr_arch_misc.h
    apr/apr/branches/xmllite/locks/win32/proc_mutex.c
    apr/apr/branches/xmllite/locks/win32/thread_cond.c
    apr/apr/branches/xmllite/locks/win32/thread_mutex.c
    apr/apr/branches/xmllite/misc/win32/misc.c
    apr/apr/branches/xmllite/user/win32/userinfo.c

Propchange: apr/apr/branches/xmllite/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon May 27 17:11:23 2019
@@ -1,4 +1,4 @@
 /apr/apr/branches/1.4.x:1101301
 /apr/apr/branches/1.5.x:1101302
-/apr/apr/trunk:1859121-1860053
+/apr/apr/trunk:1859121-1860148
 /apr/apr-util/branches/1.4.x:1211219,1211223

Modified: apr/apr/branches/xmllite/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/CHANGES?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/CHANGES [utf-8] (original)
+++ apr/apr/branches/xmllite/CHANGES [utf-8] Mon May 27 17:11:23 2019
@@ -4,6 +4,9 @@ Changes for APR 2.0.0
   *) Windows platform: Use the native XML parser implementation (XmlLite)
      by default instead of libxml2 and expat. [Ivan Zhakov]
 
+  *) Fix handle leak in the Win32 apr_uid_current implementation.
+     PR 61165. [Ivan Zhakov]
+
   *) apr_rwlock_t: Use native Slim Reader/Writer (SRW) locks on Windows.
      PR 51360. [Ivan Zhakov]
 

Modified: apr/apr/branches/xmllite/file_io/win32/open.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/file_io/win32/open.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/file_io/win32/open.c (original)
+++ apr/apr/branches/xmllite/file_io/win32/open.c Mon May 27 17:11:23 2019
@@ -252,11 +252,8 @@ static apr_status_t make_sparse_file(apr
         if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING))
         {
             do {
-                res = WaitForSingleObject(file->pOverlapped->hEvent, 
-                                          (file->timeout > 0)
-                                            ? (DWORD)(file->timeout/1000)
-                                            : ((file->timeout == -1) 
-                                                 ? INFINITE : 0));
+                res = apr_wait_for_single_object(file->pOverlapped->hEvent,
+                                                 file->timeout);
             } while (res == WAIT_ABANDONED);
 
             if (res != WAIT_OBJECT_0) {

Modified: apr/apr/branches/xmllite/file_io/win32/pipe.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/file_io/win32/pipe.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/file_io/win32/pipe.c (original)
+++ apr/apr/branches/xmllite/file_io/win32/pipe.c Mon May 27 17:11:23 2019
@@ -146,7 +146,7 @@ static apr_status_t file_pipe_create(apr
             dwOpenMode |= FILE_FLAG_OVERLAPPED;
             (*in)->pOverlapped =
                     (OVERLAPPED*) apr_pcalloc((*in)->pool, sizeof(OVERLAPPED));
-            (*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+            (*in)->pOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
             (*in)->timeout = 0;
         }
         dwPipeMode = 0;
@@ -181,7 +181,7 @@ static apr_status_t file_pipe_create(apr
             dwOpenMode |= FILE_FLAG_OVERLAPPED;
             (*out)->pOverlapped =
                     (OVERLAPPED*) apr_pcalloc((*out)->pool, sizeof(OVERLAPPED));
-            (*out)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+            (*out)->pOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
             (*out)->timeout = 0;
         }
 

Modified: apr/apr/branches/xmllite/file_io/win32/readwrite.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/file_io/win32/readwrite.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/file_io/win32/readwrite.c (original)
+++ apr/apr/branches/xmllite/file_io/win32/readwrite.c Mon May 27 17:11:23 2019
@@ -31,7 +31,6 @@
 static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
 {
     apr_status_t rv;
-    DWORD res;
     DWORD len = (DWORD)len_in;
     DWORD bytesread = 0;
 
@@ -80,19 +79,26 @@ static apr_status_t read_with_timeout(ap
     else {
         rv = apr_get_os_error();
         if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
-            /* Wait for the pending i/o, timeout converted from us to ms
-             * Note that we loop if someone gives up the event, since
-             * folks suggest that WAIT_ABANDONED isn't actually a result
-             * but an alert that ownership of the event has passed from
-             * one owner to a new proc/thread.
-             */
-            do {
-                res = WaitForSingleObject(file->pOverlapped->hEvent, 
-                                          (file->timeout > 0)
-                                            ? (DWORD)(file->timeout/1000)
-                                            : ((file->timeout == -1) 
-                                                 ? INFINITE : 0));
-            } while (res == WAIT_ABANDONED);
+            DWORD res;
+
+            /* It seems that ReadFile() return ERROR_IO_PENDING even
+             * when I/O operation completed syncronously.
+             * Use fast macro to check that overlapped I/O already
+             * completed to avoid kernel call.
+             */ 
+            if (HasOverlappedIoCompleted(file->pOverlapped)) {
+                res = WAIT_OBJECT_0;
+            }
+            else {
+                /* Wait for the pending i/o, timeout converted from us to ms
+                 * Note that we loop if someone gives up the event.
+                 *
+                 * NOTE: We do not handle WAIT_ABANDONED here because they
+                 * can be returned only when waiting for mutex.
+                 */
+                res = apr_wait_for_single_object(file->pOverlapped->hEvent,
+                                                 file->timeout);
+            }
 
             /* There is one case that represents entirely
              * successful operations, otherwise we will cancel
@@ -241,7 +247,7 @@ APR_DECLARE(apr_status_t) apr_file_read(
     if ((thefile->flags & APR_FOPEN_XTHREAD) && !thefile->pOverlapped ) {
         thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool, 
                                                          sizeof(OVERLAPPED));
-        thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        thefile->pOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
         if (!thefile->pOverlapped->hEvent) {
             rv = apr_get_os_error();
             return rv;
@@ -388,7 +394,7 @@ APR_DECLARE(apr_status_t) apr_file_write
     if ((thefile->flags & APR_FOPEN_XTHREAD) && !thefile->pOverlapped ) {
         thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool, 
                                                          sizeof(OVERLAPPED));
-        thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        thefile->pOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
         if (!thefile->pOverlapped->hEvent) {
             rv = apr_get_os_error();
             return rv;
@@ -492,20 +498,20 @@ APR_DECLARE(apr_status_t) apr_file_write
 
             if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
  
-                DWORD timeout_ms;
                 DWORD res;
 
-                if (thefile->timeout == 0) {
-                    timeout_ms = 0;
-                }
-                else if (thefile->timeout < 0) {
-                    timeout_ms = INFINITE;
+                /* It seems that WriteFile() return ERROR_IO_PENDING even
+                 * when I/O operation completed syncronously.
+                 * Use fast macro to check that overlapped I/O already
+                 * completed to avoid kernel call.
+                 */
+                if (HasOverlappedIoCompleted(thefile->pOverlapped)) {
+                    res = WAIT_OBJECT_0;
                 }
                 else {
-                    timeout_ms = (DWORD)(thefile->timeout / 1000);
+                    res = apr_wait_for_single_object(thefile->pOverlapped->hEvent,
+                                                     thefile->timeout);
                 }
-	       
-                res = WaitForSingleObject(thefile->pOverlapped->hEvent, timeout_ms);
 
                 /* There is one case that represents entirely
                  * successful operations, otherwise we will cancel
@@ -533,7 +539,7 @@ APR_DECLARE(apr_status_t) apr_file_write
                         && (res == WAIT_TIMEOUT))
                         rv = APR_TIMEUP;
 
-                    if (rv == APR_TIMEUP && timeout_ms == 0) {
+                    if (rv == APR_TIMEUP && thefile->timeout == 0) {
                         rv = APR_EAGAIN;
                     }
                 }
@@ -624,7 +630,7 @@ APR_DECLARE(apr_status_t) apr_file_gets(
     if ((thefile->flags & APR_FOPEN_XTHREAD) && !thefile->pOverlapped) {
         thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->pool,
                                                          sizeof(OVERLAPPED));
-        thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        thefile->pOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
         if (!thefile->pOverlapped->hEvent) {
             rv = apr_get_os_error();
             return rv;

Modified: apr/apr/branches/xmllite/include/arch/win32/apr_arch_misc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/include/arch/win32/apr_arch_misc.h?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/include/arch/win32/apr_arch_misc.h (original)
+++ apr/apr/branches/xmllite/include/arch/win32/apr_arch_misc.h Mon May 27 17:11:23 2019
@@ -172,6 +172,11 @@ static APR_INLINE void* apr_realloc_dbg(
 
 #endif  /* ! _MSC_VER */
 
+/* Wrapper around WaitForSingleObject() that accepts apr_interval_time_t
+ * in microseconds instead of milliseconds. Values < 0 mean wait 
+ * forever, 0 means do not wait at all. */
+DWORD apr_wait_for_single_object(HANDLE handle, apr_interval_time_t timeout);
+
 typedef enum {
     DLL_WINBASEAPI = 0,    /* kernel32 From WinBase.h       */
     DLL_WINADVAPI = 1,     /* advapi32 From WinBase.h       */

Modified: apr/apr/branches/xmllite/locks/win32/proc_mutex.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/locks/win32/proc_mutex.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/locks/win32/proc_mutex.c (original)
+++ apr/apr/branches/xmllite/locks/win32/proc_mutex.c Mon May 27 17:11:23 2019
@@ -167,26 +167,9 @@ APR_DECLARE(apr_status_t) apr_proc_mutex
 APR_DECLARE(apr_status_t) apr_proc_mutex_timedlock(apr_proc_mutex_t *mutex,
                                                apr_interval_time_t timeout)
 {
-    DWORD rv, timeout_ms = 0;
-    apr_interval_time_t t = timeout;
+    DWORD rv;
 
-    do {
-        if (t > 0) {
-            /* Given timeout is 64bit usecs whereas Windows timeouts are
-             * 32bit msecs and below INFINITE (2^32 - 1), so we may need
-             * multiple timed out waits...
-             */
-            if (t > apr_time_from_msec(INFINITE - 1)) {
-                timeout_ms = INFINITE - 1;
-                t -= apr_time_from_msec(INFINITE - 1);
-            }
-            else {
-                timeout_ms = (DWORD)apr_time_as_msec(t);
-                t = 0;
-            }
-        }
-        rv = WaitForSingleObject(mutex->handle, timeout_ms);
-    } while (rv == WAIT_TIMEOUT && t > 0);
+    rv = apr_wait_for_single_object(mutex->handle, timeout);
 
     if (rv == WAIT_TIMEOUT) {
         return APR_TIMEUP;

Modified: apr/apr/branches/xmllite/locks/win32/thread_cond.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/locks/win32/thread_cond.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/locks/win32/thread_cond.c (original)
+++ apr/apr/branches/xmllite/locks/win32/thread_cond.c Mon May 27 17:11:23 2019
@@ -20,6 +20,7 @@
 #include "apr_strings.h"
 #include "apr_arch_thread_mutex.h"
 #include "apr_arch_thread_cond.h"
+#include "apr_arch_misc.h"
 #include "apr_portable.h"
 
 #include <limits.h>
@@ -79,28 +80,7 @@ static APR_INLINE apr_status_t thread_co
     apr_thread_mutex_unlock(mutex);
 
     do {
-        apr_interval_time_t t = timeout;
-
-        do {
-            if (t < 0) {
-                timeout_ms = INFINITE;
-            }
-            else if (t > 0) {
-                /* Given timeout is 64bit usecs whereas Windows timeouts are
-                 * 32bit msecs and below INFINITE (2^32 - 1), so we may need
-                 * multiple timed out waits...
-                 */
-                if (t > apr_time_from_msec(INFINITE - 1)) {
-                    timeout_ms = INFINITE - 1;
-                    t -= apr_time_from_msec(INFINITE - 1);
-                }
-                else {
-                    timeout_ms = (DWORD)apr_time_as_msec(t);
-                    t = 0;
-                }
-            }
-            res = WaitForSingleObject(cond->semaphore, timeout_ms);
-        } while (res == WAIT_TIMEOUT && t > 0);
+        res = apr_wait_for_single_object(cond->semaphore, timeout);
 
         EnterCriticalSection(&cond->csection);
 

Modified: apr/apr/branches/xmllite/locks/win32/thread_mutex.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/locks/win32/thread_mutex.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/locks/win32/thread_mutex.c (original)
+++ apr/apr/branches/xmllite/locks/win32/thread_mutex.c Mon May 27 17:11:23 2019
@@ -118,26 +118,9 @@ APR_DECLARE(apr_status_t) apr_thread_mut
                                                  apr_interval_time_t timeout)
 {
     if (mutex->type != thread_mutex_critical_section) {
-        DWORD rv, timeout_ms = 0;
-        apr_interval_time_t t = timeout;
+        DWORD rv;
 
-        do {
-            if (t > 0) {
-                /* Given timeout is 64bit usecs whereas Windows timeouts are
-                 * 32bit msecs and below INFINITE (2^32 - 1), so we may need
-                 * multiple timed out waits...
-                 */
-                if (t > apr_time_from_msec(INFINITE - 1)) {
-                    timeout_ms = INFINITE - 1;
-                    t -= apr_time_from_msec(INFINITE - 1);
-                }
-                else {
-                    timeout_ms = (DWORD)apr_time_as_msec(t);
-                    t = 0;
-                }
-            }
-            rv = WaitForSingleObject(mutex->handle, timeout_ms);
-        } while (rv == WAIT_TIMEOUT && t > 0);
+        rv = apr_wait_for_single_object(mutex->handle, timeout);
 
         if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) {
             return (rv == WAIT_TIMEOUT) ? APR_TIMEUP : apr_get_os_error();

Modified: apr/apr/branches/xmllite/misc/win32/misc.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/misc/win32/misc.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/misc/win32/misc.c (original)
+++ apr/apr/branches/xmllite/misc/win32/misc.c Mon May 27 17:11:23 2019
@@ -188,6 +188,36 @@ FARPROC apr_load_dll_func(apr_dlltoken_e
 #endif
 }
 
+DWORD apr_wait_for_single_object(HANDLE handle, apr_interval_time_t timeout)
+{
+    apr_interval_time_t t = timeout;
+    DWORD res;
+    DWORD timeout_ms = 0;
+
+    do {
+        if (t < 0) {
+            timeout_ms = INFINITE;
+        }
+        else if (t > 0) {
+            /* Given timeout is 64bit usecs whereas Windows timeouts are
+             * 32bit msecs and below INFINITE (2^32 - 1), so we may need
+             * multiple timed out waits...
+             */
+            if (t > apr_time_from_msec(INFINITE - 1)) {
+                timeout_ms = INFINITE - 1;
+                t -= apr_time_from_msec(INFINITE - 1);
+            }
+            else {
+                timeout_ms = (DWORD)apr_time_as_msec(t);
+                t = 0;
+            }
+        }
+        res = WaitForSingleObject(handle, timeout_ms);
+    } while (res == WAIT_TIMEOUT && t > 0);
+
+    return res;
+}
+
 /* Declared in include/arch/win32/apr_dbg_win32_handles.h
  */
 APR_DECLARE_NONSTD(HANDLE) apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln, 

Modified: apr/apr/branches/xmllite/user/win32/userinfo.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/xmllite/user/win32/userinfo.c?rev=1860149&r1=1860148&r2=1860149&view=diff
==============================================================================
--- apr/apr/branches/xmllite/user/win32/userinfo.c (original)
+++ apr/apr/branches/xmllite/user/win32/userinfo.c Mon May 27 17:11:23 2019
@@ -171,27 +171,38 @@ APR_DECLARE(apr_status_t) apr_uid_curren
     DWORD needed;
     TOKEN_USER *usr;
     TOKEN_PRIMARY_GROUP *grp;
-    
+    apr_status_t rv;
+
     if(!OpenProcessToken(GetCurrentProcess(), STANDARD_RIGHTS_READ | READ_CONTROL | TOKEN_QUERY, &threadtok)) {
         return apr_get_os_error();
     }
 
     *uid = NULL;
     if (!GetTokenInformation(threadtok, TokenUser, NULL, 0, &needed)
-        && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
+        && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         && (usr = apr_palloc(p, needed))
-        && GetTokenInformation(threadtok, TokenUser, usr, needed, &needed))
+        && GetTokenInformation(threadtok, TokenUser, usr, needed, &needed)) {
         *uid = usr->User.Sid;
-    else
-        return apr_get_os_error();
+    }
+    else {
+        rv = apr_get_os_error();
+        CloseHandle(threadtok);
+        return rv;
+    }
 
     if (!GetTokenInformation(threadtok, TokenPrimaryGroup, NULL, 0, &needed)
         && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
         && (grp = apr_palloc(p, needed))
-        && GetTokenInformation(threadtok, TokenPrimaryGroup, grp, needed, &needed))
+        && GetTokenInformation(threadtok, TokenPrimaryGroup, grp, needed, &needed)) {
         *gid = grp->PrimaryGroup;
-    else
-        return apr_get_os_error();
+    }
+    else {
+        rv = apr_get_os_error();
+        CloseHandle(threadtok);
+        return rv;
+    }
+
+    CloseHandle(threadtok);
 
     return APR_SUCCESS;
 #endif