View | Details | Raw Unified | Return to bug 51392
Collapse All | Expand All

(-)apr-1.4.5/include/apr_pools.h (+61 lines)
Lines 199-204 Link Here
199
                                             apr_allocator_t *allocator);
199
                                             apr_allocator_t *allocator);
200
200
201
/**
201
/**
202
 * Create a new thread-safe pool.
203
 *
204
 * This function differs from apr_pool_create_ex in that a thread-safe
205
 * pool is created - in other words you can call apr_pool_palloc from
206
 * multiple threads safely on the pool created from this function.
207
 *
208
 * @param newpool The pool we have just created.
209
 * @param parent The parent pool.  If this is NULL, the new pool is a root
210
 *        pool.  If it is non-NULL, the new pool will inherit all
211
 *        of its parent pool's attributes, except the apr_pool_t will
212
 *        be a sub-pool.
213
 * @param abort_fn A function to use if the pool cannot allocate more memory.
214
 * @param allocator The allocator to use with the new pool.  If NULL the
215
 *        allocator of the parent pool will be used.
216
 * @remark This function is thread-safe, in the sense that multiple threads
217
 *         can safely create subpools of the same parent pool concurrently.
218
 *         Similarly, a subpool can be created by one thread at the same
219
 *         time that another thread accesses the parent pool.
220
 */
221
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool,
222
                                             apr_pool_t *parent,
223
                                             apr_abortfunc_t abort_fn,
224
                                             apr_allocator_t *allocator);
225
226
/**
202
 * Create a new pool.
227
 * Create a new pool.
203
 * @deprecated @see apr_pool_create_unmanaged_ex.
228
 * @deprecated @see apr_pool_create_unmanaged_ex.
204
 */
229
 */
Lines 243-248 Link Here
243
                                                   apr_abortfunc_t abort_fn,
268
                                                   apr_abortfunc_t abort_fn,
244
                                                   apr_allocator_t *allocator,
269
                                                   apr_allocator_t *allocator,
245
                                                   const char *file_line);
270
                                                   const char *file_line);
271
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex_debug(apr_pool_t **newpool,
272
                                                   apr_pool_t *parent,
273
                                                   apr_abortfunc_t abort_fn,
274
                                                   apr_allocator_t *allocator,
275
                                                   const char *file_line);
246
276
247
#if APR_POOL_DEBUG
277
#if APR_POOL_DEBUG
248
#define apr_pool_create_ex(newpool, parent, abort_fn, allocator)  \
278
#define apr_pool_create_ex(newpool, parent, abort_fn, allocator)  \
Lines 317-322 Link Here
317
#endif
347
#endif
318
348
319
/**
349
/**
350
 * Create a new thread-safe pool.
351
 *
352
 * This function differs from apr_pool_create in that a thread-safe
353
 * pool is created - in other words you can call apr_pool_palloc from
354
 * multiple threads safely on the pool created from this function.
355
 *
356
 * @param newpool The pool we have just created.
357
 * @param parent The parent pool.  If this is NULL, the new pool is a root
358
 *        pool.  If it is non-NULL, the new pool will inherit all
359
 *        of its parent pool's attributes, except the apr_pool_t will
360
 *        be a sub-pool.
361
 * @remark This function is thread-safe, in the sense that multiple threads
362
 *         can safely create subpools of the same parent pool concurrently.
363
 *         Similarly, a subpool can be created by one thread at the same
364
 *         time that another thread accesses the parent pool.
365
 */
366
#if defined(DOXYGEN)
367
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe(apr_pool_t **newpool,
368
                                          apr_pool_t *parent);
369
#else
370
#if APR_POOL_DEBUG
371
#define apr_pool_create_threadsafe(newpool, parent) \
372
    apr_pool_create_threadsafe_ex_debug(newpool, parent, NULL, NULL, \
373
                             APR_POOL__FILE_LINE__)
374
#else
375
#define apr_pool_create_threadsafe(newpool, parent) \
376
    apr_pool_create_threadsafe_ex(newpool, parent, NULL, NULL)
377
#endif
378
#endif
379
380
/**
320
 * Create a new pool.
381
 * Create a new pool.
321
 * @param newpool The pool we have just created.
382
 * @param newpool The pool we have just created.
322
 */
383
 */
(-)apr-1.4.5/memory/unix/apr_pools.c (-6 / +118 lines)
Lines 522-527 Link Here
522
#if APR_HAS_THREADS
522
#if APR_HAS_THREADS
523
    apr_os_thread_t       owner;
523
    apr_os_thread_t       owner;
524
    apr_thread_mutex_t   *mutex;
524
    apr_thread_mutex_t   *mutex;
525
    int                   thread_safe; /* boolean */
525
#endif /* APR_HAS_THREADS */
526
#endif /* APR_HAS_THREADS */
526
#endif /* APR_POOL_DEBUG */
527
#endif /* APR_POOL_DEBUG */
527
#ifdef NETWARE
528
#ifdef NETWARE
Lines 673-678 Link Here
673
674
674
        return NULL;
675
        return NULL;
675
    }
676
    }
677
678
#if APR_HAS_THREADS
679
    if ( pool->thread_safe && pool->mutex )
680
        apr_thread_mutex_lock( pool->mutex );
681
#endif
676
    active = pool->active;
682
    active = pool->active;
677
683
678
    /* If the active node has enough bytes left, use it. */
684
    /* If the active node has enough bytes left, use it. */
Lines 680-685 Link Here
680
        mem = active->first_avail;
686
        mem = active->first_avail;
681
        active->first_avail += size;
687
        active->first_avail += size;
682
688
689
#if APR_HAS_THREADS
690
        if ( pool->thread_safe && pool->mutex )
691
            apr_thread_mutex_unlock( pool->mutex );
692
#endif
693
683
        return mem;
694
        return mem;
684
    }
695
    }
685
696
Lines 689-694 Link Here
689
    }
700
    }
690
    else {
701
    else {
691
        if ((node = allocator_alloc(pool->allocator, size)) == NULL) {
702
        if ((node = allocator_alloc(pool->allocator, size)) == NULL) {
703
#if APR_HAS_THREADS
704
            if ( pool->thread_safe && pool->mutex )
705
                apr_thread_mutex_unlock( pool->mutex );
706
#endif
707
692
            if (pool->abort_fn)
708
            if (pool->abort_fn)
693
                pool->abort_fn(APR_ENOMEM);
709
                pool->abort_fn(APR_ENOMEM);
694
710
Lines 710-717 Link Here
710
726
711
    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
727
    active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
712
    node = active->next;
728
    node = active->next;
713
    if (free_index >= node->free_index)
729
    if (free_index >= node->free_index) {
730
#if APR_HAS_THREADS
731
        if ( pool->thread_safe && pool->mutex )
732
            apr_thread_mutex_unlock( pool->mutex );
733
#endif
734
714
        return mem;
735
        return mem;
736
    }
715
737
716
    do {
738
    do {
717
        node = node->next;
739
        node = node->next;
Lines 721-726 Link Here
721
    list_remove(active);
743
    list_remove(active);
722
    list_insert(active, node);
744
    list_insert(active, node);
723
745
746
#if APR_HAS_THREADS
747
    if ( pool->thread_safe && pool->mutex )
748
        apr_thread_mutex_unlock( pool->mutex );
749
#endif
750
724
    return mem;
751
    return mem;
725
}
752
}
726
753
Lines 860-865 Link Here
860
    }
887
    }
861
}
888
}
862
889
890
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool,
891
                                             apr_pool_t *parent,
892
                                             apr_abortfunc_t abort_fn,
893
                                             apr_allocator_t *allocator)
894
{
895
    apr_status_t rv;
896
897
    rv = apr_pool_create_ex(newpool,parent,abort_fn,allocator);
898
    if ( APR_SUCCESS == rv ) {
899
        // create mutex for pool
900
        if ( (*newpool)->mutex == NULL ) {
901
            rv = apr_thread_mutex_create(
902
                &((*newpool)->mutex),
903
                APR_THREAD_MUTEX_NESTED,
904
                *newpool
905
            );
906
            if ( APR_SUCCESS != rv ) {
907
                apr_pool_destroy( rv );
908
                return( rv );
909
            }
910
        }
911
912
        (*newpool)->thread_safe = 1;
913
    }
914
915
    return( status );
916
}
917
863
APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,
918
APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool,
864
                                             apr_pool_t *parent,
919
                                             apr_pool_t *parent,
865
                                             apr_abortfunc_t abort_fn,
920
                                             apr_abortfunc_t abort_fn,
Lines 907-912 Link Here
907
    pool->subprocesses = NULL;
962
    pool->subprocesses = NULL;
908
    pool->user_data = NULL;
963
    pool->user_data = NULL;
909
    pool->tag = NULL;
964
    pool->tag = NULL;
965
    pool->mutex = NULL;
966
    pool->thread_safe = 0;
910
967
911
#ifdef NETWARE
968
#ifdef NETWARE
912
    pool->owner_proc = (apr_os_proc_t)getnlmhandle();
969
    pool->owner_proc = (apr_os_proc_t)getnlmhandle();
Lines 1192-1198 Link Here
1192
    return strp;
1249
    return strp;
1193
}
1250
}
1194
1251
1195
1196
#else /* APR_POOL_DEBUG */
1252
#else /* APR_POOL_DEBUG */
1197
/*
1253
/*
1198
 * Debug helper functions
1254
 * Debug helper functions
Lines 1339-1344 Link Here
1339
1395
1340
#if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER)
1396
#if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER)
1341
#if APR_HAS_THREADS
1397
#if APR_HAS_THREADS
1398
    if (! pool->thread_safe) {
1342
    if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) {
1399
    if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) {
1343
#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)
1400
#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL)
1344
        apr_pool_log_event(pool, "THREAD",
1401
        apr_pool_log_event(pool, "THREAD",
Lines 1346-1351 Link Here
1346
#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */
1403
#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) */
1347
        abort();
1404
        abort();
1348
    }
1405
    }
1406
    }
1349
#endif /* APR_HAS_THREADS */
1407
#endif /* APR_HAS_THREADS */
1350
#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */
1408
#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */
1351
}
1409
}
Lines 1462-1470 Link Here
1462
        return NULL;
1520
        return NULL;
1463
    }
1521
    }
1464
1522
1523
#if APR_HAS_THREADS
1524
    if ( pool->thread_safe && pool->mutex )
1525
        apr_thread_mutex_lock( pool->mutex );
1526
#endif
1527
1465
    node = pool->nodes;
1528
    node = pool->nodes;
1466
    if (node == NULL || node->index == 64) {
1529
    if (node == NULL || node->index == 64) {
1467
        if ((node = malloc(SIZEOF_DEBUG_NODE_T)) == NULL) {
1530
        if ((node = malloc(SIZEOF_DEBUG_NODE_T)) == NULL) {
1531
#if APR_HAS_THREADS
1532
            if ( pool->thread_safe && pool->mutex )
1533
                apr_thread_mutex_unlock( pool->mutex );
1534
#endif
1535
1468
            if (pool->abort_fn)
1536
            if (pool->abort_fn)
1469
                pool->abort_fn(APR_ENOMEM);
1537
                pool->abort_fn(APR_ENOMEM);
1470
1538
Lines 1485-1490 Link Here
1485
    pool->stat_alloc++;
1553
    pool->stat_alloc++;
1486
    pool->stat_total_alloc++;
1554
    pool->stat_total_alloc++;
1487
1555
1556
#if APR_HAS_THREADS
1557
    if ( pool->thread_safe && pool->mutex )
1558
        apr_thread_mutex_unlock( pool->mutex );
1559
#endif
1560
1488
    return mem;
1561
    return mem;
1489
}
1562
}
1490
1563
Lines 1674-1679 Link Here
1674
    pool_destroy_debug(pool, file_line);
1747
    pool_destroy_debug(pool, file_line);
1675
}
1748
}
1676
1749
1750
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex_debug(
1751
                                                   apr_pool_t **newpool,
1752
                                                   apr_pool_t *parent,
1753
                                                   apr_abortfunc_t abort_fn,
1754
                                                   apr_allocator_t *allocator,
1755
                                                   const char *file_line)
1756
{
1757
    apr_status_t status;
1758
1759
    status = apr_pool_create_ex_debug(
1760
        newpool,parent,abort_fn,allocator,file_line
1761
    );
1762
    if ( APR_SUCCESS == status )
1763
        (*newpool)->thread_safe = 1;
1764
1765
    return( status );
1766
}
1767
1768
1677
APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,
1769
APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool,
1678
                                                   apr_pool_t *parent,
1770
                                                   apr_pool_t *parent,
1679
                                                   apr_abortfunc_t abort_fn,
1771
                                                   apr_abortfunc_t abort_fn,
Lines 1739-1747 Link Here
1739
    pool->owner_proc = (apr_os_proc_t)getnlmhandle();
1831
    pool->owner_proc = (apr_os_proc_t)getnlmhandle();
1740
#endif /* defined(NETWARE) */
1832
#endif /* defined(NETWARE) */
1741
1833
1834
#if APR_HAS_THREADS
1835
    /* Initialise thread_safe flag, this will be altered
1836
     * by creation function if a thread_safe pool is required.
1837
     */
1838
    pool->thread_safe = 0;
1742
1839
1743
    if (parent == NULL || parent->allocator != allocator) {
1840
    if (parent == NULL || parent->allocator != allocator) {
1744
#if APR_HAS_THREADS
1745
        apr_status_t rv;
1841
        apr_status_t rv;
1746
1842
1747
        /* No matter what the creation flags say, always create
1843
        /* No matter what the creation flags say, always create
Lines 1757-1770 Link Here
1757
            free(pool);
1853
            free(pool);
1758
            return rv;
1854
            return rv;
1759
        }
1855
        }
1760
#endif /* APR_HAS_THREADS */
1761
    }
1856
    }
1762
    else {
1857
    else {
1763
#if APR_HAS_THREADS
1764
        if (parent)
1858
        if (parent)
1765
            pool->mutex = parent->mutex;
1859
            pool->mutex = parent->mutex;
1766
#endif /* APR_HAS_THREADS */
1767
    }
1860
    }
1861
#endif /* APR_HAS_THREADS */
1768
1862
1769
    *newpool = pool;
1863
    *newpool = pool;
1770
1864
Lines 1842-1847 Link Here
1842
            free(pool);
1936
            free(pool);
1843
            return rv;
1937
            return rv;
1844
        }
1938
        }
1939
1940
        pool->thread_safe = 0;
1845
#endif /* APR_HAS_THREADS */
1941
#endif /* APR_HAS_THREADS */
1846
    }
1942
    }
1847
1943
Lines 2620-2625 Link Here
2620
                                    "undefined");
2716
                                    "undefined");
2621
}
2717
}
2622
2718
2719
#undef apr_pool_create_threadsafe_ex
2720
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool,
2721
                                             apr_pool_t *parent,
2722
                                             apr_abortfunc_t abort_fn,
2723
                                             apr_allocator_t *allocator);
2724
2725
APR_DECLARE(apr_status_t) apr_pool_create_threadsafe_ex(apr_pool_t **newpool,
2726
                                             apr_pool_t *parent,
2727
                                             apr_abortfunc_t abort_fn,
2728
                                             apr_allocator_t *allocator)
2729
{
2730
    return apr_pool_create_threadsafe_ex_debug(newpool, parent,
2731
                                    abort_fn, allocator,
2732
                                    "undefined");
2733
}
2734
2623
#undef apr_pool_create_core_ex
2735
#undef apr_pool_create_core_ex
2624
APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
2736
APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool,
2625
                                                  apr_abortfunc_t abort_fn,
2737
                                                  apr_abortfunc_t abort_fn,

Return to bug 51392