You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by yl...@apache.org on 2022/07/21 11:12:34 UTC

svn commit: r1902908 - in /apr/apr/branches/1.8.x: ./ include/ include/arch/beos/ include/arch/netware/ include/arch/os2/ include/arch/unix/ include/arch/win32/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

Author: ylavic
Date: Thu Jul 21 11:12:34 2022
New Revision: 1902908

URL: http://svn.apache.org/viewvc?rev=1902908&view=rev
Log:
apr_thread: Provide apr_threadattr_max_free_set().

When creating a thread, this allows to specify the "max_free" of its pool
allocator (i.e. apr_allocator_max_free_set), so that one can create thread
local subpools and have their memory usage regulated on cleanup/destroy.

One could achieve that already with:
    apr_allocator_max_free_set(apr_thread_pool_get(thread), max_free);
in the thread startup function, but it's more convenient, simpler and race
free to handle that in the thread attribute itself at creation time.


Merge r1902715 from trunk.

Modified:
    apr/apr/branches/1.8.x/   (props changed)
    apr/apr/branches/1.8.x/include/apr_thread_proc.h
    apr/apr/branches/1.8.x/include/arch/beos/apr_arch_threadproc.h
    apr/apr/branches/1.8.x/include/arch/netware/apr_arch_threadproc.h
    apr/apr/branches/1.8.x/include/arch/os2/apr_arch_threadproc.h
    apr/apr/branches/1.8.x/include/arch/unix/apr_arch_threadproc.h
    apr/apr/branches/1.8.x/include/arch/win32/apr_arch_threadproc.h
    apr/apr/branches/1.8.x/threadproc/beos/thread.c
    apr/apr/branches/1.8.x/threadproc/netware/thread.c
    apr/apr/branches/1.8.x/threadproc/os2/thread.c
    apr/apr/branches/1.8.x/threadproc/unix/thread.c
    apr/apr/branches/1.8.x/threadproc/win32/thread.c

Propchange: apr/apr/branches/1.8.x/
------------------------------------------------------------------------------
  Merged /apr/apr/trunk:r1902715

Modified: apr/apr/branches/1.8.x/include/apr_thread_proc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/apr_thread_proc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/apr_thread_proc.h (original)
+++ apr/apr/branches/1.8.x/include/apr_thread_proc.h Thu Jul 21 11:12:34 2022
@@ -278,6 +278,15 @@ APR_DECLARE(apr_status_t) apr_threadattr
                                                        apr_size_t guardsize);
 
 /**
+ * Set the threshold at which the thread pool allocator should start
+ * giving blocks back to the system.
+ * @param attr The threadattr to affect 
+ * @param on Non-zero if detached threads should be created.
+ */
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size);
+
+/**
  * Create a new thread of execution
  * @param new_thread The newly created thread handle.
  * @param attr The threadattr to use to determine how to create the thread

Modified: apr/apr/branches/1.8.x/include/arch/beos/apr_arch_threadproc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/arch/beos/apr_arch_threadproc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/arch/beos/apr_arch_threadproc.h (original)
+++ apr/apr/branches/1.8.x/include/arch/beos/apr_arch_threadproc.h Thu Jul 21 11:12:34 2022
@@ -53,6 +53,7 @@ struct apr_threadattr_t {
     int32 attr;
     int detached;
     int joinable;
+    apr_size_t max_free;
 };
 
 struct apr_threadkey_t {

Modified: apr/apr/branches/1.8.x/include/arch/netware/apr_arch_threadproc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/arch/netware/apr_arch_threadproc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/arch/netware/apr_arch_threadproc.h (original)
+++ apr/apr/branches/1.8.x/include/arch/netware/apr_arch_threadproc.h Thu Jul 21 11:12:34 2022
@@ -44,6 +44,7 @@ struct apr_threadattr_t {
     apr_size_t  stack_size;
     apr_int32_t detach;
     char *thread_name;
+    apr_size_t max_free;
 };
 
 struct apr_threadkey_t {

Modified: apr/apr/branches/1.8.x/include/arch/os2/apr_arch_threadproc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/arch/os2/apr_arch_threadproc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/arch/os2/apr_arch_threadproc.h (original)
+++ apr/apr/branches/1.8.x/include/arch/os2/apr_arch_threadproc.h Thu Jul 21 11:12:34 2022
@@ -29,6 +29,7 @@ struct apr_threadattr_t {
     apr_pool_t *pool;
     unsigned long attr;
     apr_size_t stacksize;
+    apr_size_t max_free;
 };
 
 struct apr_thread_t {

Modified: apr/apr/branches/1.8.x/include/arch/unix/apr_arch_threadproc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/arch/unix/apr_arch_threadproc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/arch/unix/apr_arch_threadproc.h (original)
+++ apr/apr/branches/1.8.x/include/arch/unix/apr_arch_threadproc.h Thu Jul 21 11:12:34 2022
@@ -65,6 +65,7 @@ struct apr_thread_t {
 struct apr_threadattr_t {
     apr_pool_t *pool;
     pthread_attr_t attr;
+    apr_size_t max_free;
 };
 
 struct apr_threadkey_t {

Modified: apr/apr/branches/1.8.x/include/arch/win32/apr_arch_threadproc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/include/arch/win32/apr_arch_threadproc.h?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/include/arch/win32/apr_arch_threadproc.h (original)
+++ apr/apr/branches/1.8.x/include/arch/win32/apr_arch_threadproc.h Thu Jul 21 11:12:34 2022
@@ -38,6 +38,7 @@ struct apr_threadattr_t {
     apr_pool_t *pool;
     apr_int32_t detach;
     apr_size_t stacksize;
+    apr_size_t max_free;
 };
 
 struct apr_threadkey_t {

Modified: apr/apr/branches/1.8.x/threadproc/beos/thread.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/threadproc/beos/thread.c?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/threadproc/beos/thread.c (original)
+++ apr/apr/branches/1.8.x/threadproc/beos/thread.c Thu Jul 21 11:12:34 2022
@@ -62,6 +62,13 @@ APR_DECLARE(apr_status_t) apr_threadattr
     return APR_ENOTIMPL;
 }
 
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size)
+{
+    attr->max_free = size;
+    return APR_SUCCESS;
+}
+
 #if APR_HAS_THREAD_LOCAL
 static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL;
 #endif
@@ -90,27 +97,22 @@ static apr_status_t alloc_thread(apr_thr
 {
     apr_status_t stat;
     apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
-    apr_allocator_t *allocator;
     apr_pool_t *p;
 
     /* The thread can be detached anytime (from the creation or later with
      * apr_thread_detach), so it needs its own pool and allocator to not
      * depend on a parent pool which could be destroyed before the thread
      * exits. The allocator needs no mutex obviously since the pool should
-     * not be used nor create children pools outside the thread.
+     * not be used nor create children pools outside the thread. Passing
+     * NULL allocator will create one like that.
      */
-    stat = apr_allocator_create(&allocator);
+    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL);
     if (stat != APR_SUCCESS) {
-        if (abort_fn)
-            abort_fn(stat);
         return stat;
     }
-    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
-    if (stat != APR_SUCCESS) {
-        apr_allocator_destroy(allocator);
-        return stat;
+    if (attr && attr->max_free) {
+        apr_allocator_max_free_set(apr_pool_allocator_get(p), attr->max_free);
     }
-    apr_allocator_owner_set(allocator, p);
 
     (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
     if ((*new) == NULL) {

Modified: apr/apr/branches/1.8.x/threadproc/netware/thread.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/threadproc/netware/thread.c?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/threadproc/netware/thread.c (original)
+++ apr/apr/branches/1.8.x/threadproc/netware/thread.c Thu Jul 21 11:12:34 2022
@@ -64,6 +64,13 @@ APR_DECLARE(apr_status_t) apr_threadattr
     return APR_ENOTIMPL;
 }
 
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size)
+{
+    attr->max_free = size;
+    return APR_SUCCESS;
+}
+
 #if APR_HAS_THREAD_LOCAL
 static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL;
 #endif
@@ -92,27 +99,22 @@ static apr_status_t alloc_thread(apr_thr
 {
     apr_status_t stat;
     apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
-    apr_allocator_t *allocator;
     apr_pool_t *p;
 
     /* The thread can be detached anytime (from the creation or later with
      * apr_thread_detach), so it needs its own pool and allocator to not
      * depend on a parent pool which could be destroyed before the thread
      * exits. The allocator needs no mutex obviously since the pool should
-     * not be used nor create children pools outside the thread.
+     * not be used nor create children pools outside the thread. Passing
+     * NULL allocator will create one like that.
      */
-    stat = apr_allocator_create(&allocator);
+    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL);
     if (stat != APR_SUCCESS) {
-        if (abort_fn)
-            abort_fn(stat);
         return stat;
     }
-    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
-    if (stat != APR_SUCCESS) {
-        apr_allocator_destroy(allocator);
-        return stat;
+    if (attr && attr->max_free) {
+        apr_allocator_max_free_set(apr_pool_allocator_get(p), attr->max_free);
     }
-    apr_allocator_owner_set(allocator, p);
 
     (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
     if ((*new) == NULL) {

Modified: apr/apr/branches/1.8.x/threadproc/os2/thread.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/threadproc/os2/thread.c?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/threadproc/os2/thread.c (original)
+++ apr/apr/branches/1.8.x/threadproc/os2/thread.c Thu Jul 21 11:12:34 2022
@@ -68,6 +68,13 @@ APR_DECLARE(apr_status_t) apr_threadattr
     return APR_ENOTIMPL;
 }
 
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size)
+{
+    attr->max_free = size;
+    return APR_SUCCESS;
+}
+
 #if APR_HAS_THREAD_LOCAL
 static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL;
 #endif
@@ -94,27 +101,22 @@ static apr_status_t alloc_thread(apr_thr
 {
     apr_status_t stat;
     apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
-    apr_allocator_t *allocator;
     apr_pool_t *p;
 
     /* The thread can be detached anytime (from the creation or later with
      * apr_thread_detach), so it needs its own pool and allocator to not
      * depend on a parent pool which could be destroyed before the thread
      * exits. The allocator needs no mutex obviously since the pool should
-     * not be used nor create children pools outside the thread.
+     * not be used nor create children pools outside the thread. Passing
+     * NULL allocator will create one like that.
      */
-    stat = apr_allocator_create(&allocator);
+    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL);
     if (stat != APR_SUCCESS) {
-        if (abort_fn)
-            abort_fn(stat);
         return stat;
     }
-    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
-    if (stat != APR_SUCCESS) {
-        apr_allocator_destroy(allocator);
-        return stat;
+    if (attr && attr->max_free) {
+        apr_allocator_max_free_set(apr_pool_allocator_get(p), attr->max_free);
     }
-    apr_allocator_owner_set(allocator, p);
 
     (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
     if ((*new) == NULL) {

Modified: apr/apr/branches/1.8.x/threadproc/unix/thread.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/threadproc/unix/thread.c?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/threadproc/unix/thread.c (original)
+++ apr/apr/branches/1.8.x/threadproc/unix/thread.c Thu Jul 21 11:12:34 2022
@@ -136,6 +136,13 @@ APR_DECLARE(apr_status_t) apr_threadattr
 #endif
 }
 
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size)
+{
+    attr->max_free = size;
+    return APR_SUCCESS;
+}
+
 #if APR_HAS_THREAD_LOCAL
 static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL;
 #endif
@@ -164,27 +171,22 @@ static apr_status_t alloc_thread(apr_thr
 {
     apr_status_t stat;
     apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
-    apr_allocator_t *allocator;
     apr_pool_t *p;
 
     /* The thread can be detached anytime (from the creation or later with
      * apr_thread_detach), so it needs its own pool and allocator to not
      * depend on a parent pool which could be destroyed before the thread
      * exits. The allocator needs no mutex obviously since the pool should
-     * not be used nor create children pools outside the thread.
+     * not be used nor create children pools outside the thread. Passing
+     * NULL allocator will create one like that.
      */
-    stat = apr_allocator_create(&allocator);
+    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL);
     if (stat != APR_SUCCESS) {
-        if (abort_fn)
-            abort_fn(stat);
         return stat;
     }
-    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
-    if (stat != APR_SUCCESS) {
-        apr_allocator_destroy(allocator);
-        return stat;
+    if (attr && attr->max_free) {
+        apr_allocator_max_free_set(apr_pool_allocator_get(p), attr->max_free);
     }
-    apr_allocator_owner_set(allocator, p);
 
     (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
     if ((*new) == NULL) {

Modified: apr/apr/branches/1.8.x/threadproc/win32/thread.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/threadproc/win32/thread.c?rev=1902908&r1=1902907&r2=1902908&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/threadproc/win32/thread.c (original)
+++ apr/apr/branches/1.8.x/threadproc/win32/thread.c Thu Jul 21 11:12:34 2022
@@ -72,6 +72,13 @@ APR_DECLARE(apr_status_t) apr_threadattr
     return APR_ENOTIMPL;
 }
 
+APR_DECLARE(apr_status_t) apr_threadattr_max_free_set(apr_threadattr_t *attr, 
+                                                      apr_size_t size)
+{
+    attr->max_free = size;
+    return APR_SUCCESS;
+}
+
 #if APR_HAS_THREAD_LOCAL
 static APR_THREAD_LOCAL apr_thread_t *current_thread = NULL;
 #endif
@@ -101,27 +108,22 @@ static apr_status_t alloc_thread(apr_thr
 {
     apr_status_t stat;
     apr_abortfunc_t abort_fn = apr_pool_abort_get(pool);
-    apr_allocator_t *allocator;
     apr_pool_t *p;
 
     /* The thread can be detached anytime (from the creation or later with
      * apr_thread_detach), so it needs its own pool and allocator to not
      * depend on a parent pool which could be destroyed before the thread
      * exits. The allocator needs no mutex obviously since the pool should
-     * not be used nor create children pools outside the thread.
+     * not be used nor create children pools outside the thread. Passing
+     * NULL allocator will create one like that.
      */
-    stat = apr_allocator_create(&allocator);
+    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, NULL);
     if (stat != APR_SUCCESS) {
-        if (abort_fn)
-            abort_fn(stat);
         return stat;
     }
-    stat = apr_pool_create_unmanaged_ex(&p, abort_fn, allocator);
-    if (stat != APR_SUCCESS) {
-        apr_allocator_destroy(allocator);
-        return stat;
+    if (attr && attr->max_free) {
+        apr_allocator_max_free_set(apr_pool_allocator_get(p), attr->max_free);
     }
-    apr_allocator_owner_set(allocator, p);
 
     (*new) = (apr_thread_t *)apr_pcalloc(p, sizeof(apr_thread_t));
     if ((*new) == NULL) {