ASF Bugzilla – Attachment 27169 Details for
Bug 51392
apr_pool_t thread-safe pool creation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches apr_pools.c and apr_pools.h to add thread-safe pools
apr_pools.patch (text/plain), 11.15 KB, created by
bugzilla
on 2011-06-17 11:02:35 UTC
(
hide
)
Description:
Patches apr_pools.c and apr_pools.h to add thread-safe pools
Filename:
MIME Type:
Creator:
bugzilla
Created:
2011-06-17 11:02:35 UTC
Size:
11.15 KB
patch
obsolete
>--- apr-1.4.5/include/apr_pools.h 2009-09-09 19:51:09.000000000 +0100 >+++ apr-1.4.5-ts/include/apr_pools.h 2011-06-17 11:07:19.000000000 +0100 >@@ -199,6 +199,31 @@ > apr_allocator_t *allocator); > > /** >+ * Create a new thread-safe pool. >+ * >+ * This function differs from apr_pool_create_ex in that a thread-safe >+ * pool is created - in other words you can call apr_pool_palloc from >+ * multiple threads safely on the pool created from this function. >+ * >+ * @param newpool The pool we have just created. >+ * @param parent The parent pool. If this is NULL, the new pool is a root >+ * pool. If it is non-NULL, the new pool will inherit all >+ * of its parent pool's attributes, except the apr_pool_t will >+ * be a sub-pool. >+ * @param abort_fn A function to use if the pool cannot allocate more memory. >+ * @param allocator The allocator to use with the new pool. If NULL the >+ * allocator of the parent pool will be used. >+ * @remark This function is thread-safe, in the sense that multiple threads >+ * can safely create subpools of the same parent pool concurrently. >+ * Similarly, a subpool can be created by one thread at the same >+ * time that another thread accesses the parent pool. >+ */ >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator); >+ >+/** > * Create a new pool. > * @deprecated @see apr_pool_create_unmanaged_ex. > */ >@@ -243,6 +268,11 @@ > apr_abortfunc_t abort_fn, > apr_allocator_t *allocator, > const char *file_line); >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex_debug(apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator, >+ const char *file_line); > > #if APR_POOL_DEBUG > #define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \ >@@ -317,6 +347,37 @@ > #endif > > /** >+ * Create a new thread-safe pool. >+ * >+ * This function differs from apr_pool_create in that a thread-safe >+ * pool is created - in other words you can call apr_pool_palloc from >+ * multiple threads safely on the pool created from this function. >+ * >+ * @param newpool The pool we have just created. >+ * @param parent The parent pool. If this is NULL, the new pool is a root >+ * pool. If it is non-NULL, the new pool will inherit all >+ * of its parent pool's attributes, except the apr_pool_t will >+ * be a sub-pool. >+ * @remark This function is thread-safe, in the sense that multiple threads >+ * can safely create subpools of the same parent pool concurrently. >+ * Similarly, a subpool can be created by one thread at the same >+ * time that another thread accesses the parent pool. >+ */ >+#if defined(DOXYGEN) >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe(apr_pool_t **newpool, >+ apr_pool_t *parent); >+#else >+#if APR_POOL_DEBUG >+#define apr_pool_create_threadsafe(newpool, parent) \ >+ apr_pool_create_threadsafe_ex_debug(newpool, parent, NULL, NULL, \ >+ APR_POOL__FILE_LINE__) >+#else >+#define apr_pool_create_threadsafe(newpool, parent) \ >+ apr_pool_create_threadsafe_ex(newpool, parent, NULL, NULL) >+#endif >+#endif >+ >+/** > * Create a new pool. > * @param newpool The pool we have just created. > */ > > > >--- apr-1.4.5/memory/unix/apr_pools.c 2011-03-21 14:58:46.000000000 +0000 >+++ apr-1.4.5-ts/memory/unix/apr_pools.c 2011-06-17 10:58:42.000000000 +0100 >@@ -522,6 +522,7 @@ > #if APR_HAS_THREADS > apr_os_thread_t owner; > apr_thread_mutex_t *mutex; >+ int thread_safe; /* boolean */ > #endif /* APR_HAS_THREADS */ > #endif /* APR_POOL_DEBUG */ > #ifdef NETWARE >@@ -673,6 +674,11 @@ > > return NULL; > } >+ >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_lock( pool->mutex ); >+#endif > active = pool->active; > > /* If the active node has enough bytes left, use it. */ >@@ -680,6 +686,11 @@ > mem = active->first_avail; > active->first_avail += size; > >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > return mem; > } > >@@ -689,6 +700,11 @@ > } > else { > if ((node = allocator_alloc(pool->allocator, size)) == NULL) { >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > if (pool->abort_fn) > pool->abort_fn(APR_ENOMEM); > >@@ -710,8 +726,14 @@ > > active->free_index = (APR_UINT32_TRUNC_CAST)free_index; > node = active->next; >- if (free_index >= node->free_index) >+ if (free_index >= node->free_index) { >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > return mem; >+ } > > do { > node = node->next; >@@ -721,6 +743,11 @@ > list_remove(active); > list_insert(active, node); > >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > return mem; > } > >@@ -860,6 +887,34 @@ > } > } > >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator) >+{ >+ apr_status_t rv; >+ >+ rv = apr_pool_create_ex(newpool,parent,abort_fn,allocator); >+ if ( APR_SUCCESS == rv ) { >+ // create mutex for pool >+ if ( (*newpool)->mutex == NULL ) { >+ rv = apr_thread_mutex_create( >+ &((*newpool)->mutex), >+ APR_THREAD_MUTEX_NESTED, >+ *newpool >+ ); >+ if ( APR_SUCCESS != rv ) { >+ apr_pool_destroy( rv ); >+ return( rv ); >+ } >+ } >+ >+ (*newpool)->thread_safe = 1; >+ } >+ >+ return( status ); >+} >+ > APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, > apr_pool_t *parent, > apr_abortfunc_t abort_fn, >@@ -907,6 +962,8 @@ > pool->subprocesses = NULL; > pool->user_data = NULL; > pool->tag = NULL; >+ pool->mutex = NULL; >+ pool->thread_safe = 0; > > #ifdef NETWARE > pool->owner_proc = (apr_os_proc_t)getnlmhandle(); >@@ -1192,7 +1249,6 @@ > return strp; > } > >- > #else /* APR_POOL_DEBUG */ > /* > * Debug helper functions >@@ -1339,6 +1395,7 @@ > > #if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) > #if APR_HAS_THREADS >+ if (! pool->thread_safe) { > if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) { > #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) > apr_pool_log_event(pool, "THREAD", >@@ -1346,6 +1403,7 @@ > #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */ > abort(); > } >+ } > #endif /* APR_HAS_THREADS */ > #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */ > } >@@ -1462,9 +1520,19 @@ > return NULL; > } > >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_lock( pool->mutex ); >+#endif >+ > node = pool->nodes; > if (node == NULL || node->index == 64) { > if ((node = malloc(SIZEOF_DEBUG_NODE_T)) == NULL) { >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > if (pool->abort_fn) > pool->abort_fn(APR_ENOMEM); > >@@ -1485,6 +1553,11 @@ > pool->stat_alloc++; > pool->stat_total_alloc++; > >+#if APR_HAS_THREADS >+ if ( pool->thread_safe && pool->mutex ) >+ apr_thread_mutex_unlock( pool->mutex ); >+#endif >+ > return mem; > } > >@@ -1674,6 +1747,25 @@ > pool_destroy_debug(pool, file_line); > } > >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex_debug( >+ apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator, >+ const char *file_line) >+{ >+ apr_status_t status; >+ >+ status = apr_pool_create_ex_debug( >+ newpool,parent,abort_fn,allocator,file_line >+ ); >+ if ( APR_SUCCESS == status ) >+ (*newpool)->thread_safe = 1; >+ >+ return( status ); >+} >+ >+ > APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, > apr_pool_t *parent, > apr_abortfunc_t abort_fn, >@@ -1739,9 +1831,13 @@ > pool->owner_proc = (apr_os_proc_t)getnlmhandle(); > #endif /* defined(NETWARE) */ > >+#if APR_HAS_THREADS >+ /* Initialise thread_safe flag, this will be altered >+ * by creation function if a thread_safe pool is required. >+ */ >+ pool->thread_safe = 0; > > if (parent == NULL || parent->allocator != allocator) { >-#if APR_HAS_THREADS > apr_status_t rv; > > /* No matter what the creation flags say, always create >@@ -1757,14 +1853,12 @@ > free(pool); > return rv; > } >-#endif /* APR_HAS_THREADS */ > } > else { >-#if APR_HAS_THREADS > if (parent) > pool->mutex = parent->mutex; >-#endif /* APR_HAS_THREADS */ > } >+#endif /* APR_HAS_THREADS */ > > *newpool = pool; > >@@ -1842,6 +1936,8 @@ > free(pool); > return rv; > } >+ >+ pool->thread_safe = 0; > #endif /* APR_HAS_THREADS */ > } > >@@ -2620,6 +2716,22 @@ > "undefined"); > } > >+#undef apr_pool_create_threadsafe_ex >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator); >+ >+APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool, >+ apr_pool_t *parent, >+ apr_abortfunc_t abort_fn, >+ apr_allocator_t *allocator) >+{ >+ return apr_pool_create_threadsafe_ex_debug(newpool, parent, >+ abort_fn, allocator, >+ "undefined"); >+} >+ > #undef apr_pool_create_core_ex > APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool, > apr_abortfunc_t abort_fn,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 51392
: 27169