Author: stefan2 Date: Sun Dec 18 17:28:10 2011 New Revision: 1220463 URL: http://svn.apache.org/viewvc?rev=1220463&view=rev Log: On file_handle_cache branch: Limit the number of open file handles on a per-process basis instead of per-cache.
* subversion/libsvn_subr/svn_file_handle_cache.c clarify global commentary (global_handle_count): new global, shared variable (internal_file_open, internal_close_file): update the global counter as well (auto_close_oldest): limit handle count against the _global_ counter (close_all_handles): new "destructor" to unsure update of the global counter (svn_file_handle_cache__create_cache): register destructor Modified: subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c Modified: subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c?rev=1220463&r1=1220462&r2=1220463&view=diff ============================================================================== --- subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c (original) +++ subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c Sun Dec 18 17:28:10 2011 @@ -25,6 +25,7 @@ #include "private/svn_file_handle_cache.h" #include "private/svn_mutex.h" +#include "private/svn_atomic.h" #include "svn_private_config.h" #include "svn_pools.h" #include "svn_io.h" @@ -64,9 +65,9 @@ * without the application being aware of it, no distinction is being made * between read-after-write, write-after-read or others. * - * For similar reasons, an application may want to close all idle handles - * explicitly, i.e. without opening new ones. svn_file_handle_cache__flush - * is the function to call in that case. + * It is the application's task to inform the cache that some write has + * occured and the respective file handles shall be removed from the cache. + * svn_file_handle_cache__flush is the function to call in that case. */ /* Size of the APR per-file data buffer. We don't rely on this value to @@ -76,6 +77,9 @@ */ #define FILE_BUFFER_SIZE 0x1000 +/* Aggregated open file handle count over all cache instances. */ +static volatile svn_atomic_t global_handle_count = 0; + /* forward-declarations */ typedef struct cache_entry_t cache_entry_t; typedef struct entry_link_t entry_link_t; @@ -402,6 +406,7 @@ internal_file_open(cache_entry_t **resul */ append_to_list(&cache->used_entries, &entry->global_link); append_to_list(&cache->idle_entries, &entry->idle_link); + svn_atomic_inc(&global_handle_count); /* link with other entries for the same file in the index, or add it * to the index if no entry for this file name exists so far */ @@ -464,6 +469,7 @@ internal_close_file(svn_file_handle_cach /* remove entry from the idle and global list */ remove_from_list(&cache->idle_entries, &entry->idle_link); remove_from_list(&cache->used_entries, &entry->global_link); + svn_atomic_dec(&global_handle_count); /* actually close the file handle. */ if (entry->file) @@ -559,7 +565,7 @@ close_oldest_idle(svn_file_handle_cache_ static svn_error_t * auto_close_oldest(svn_file_handle_cache_t *cache) { - return cache->used_entries.count > cache->max_used_count + return svn_atomic_read(&global_handle_count) > cache->max_used_count ? close_oldest_idle(cache) : SVN_NO_ERROR; } @@ -887,6 +893,23 @@ svn_file_handle_cache__flush(svn_file_ha return SVN_NO_ERROR; } +/* Close all remaining cached file handles. + */ +static apr_status_t +close_all_handles(void *cache_void) +{ + svn_file_handle_cache_t *cache = cache_void; + + /* There is no apr_atomic_sub and *_add requires an unsigned value. + * Thus, we can't use apr_atomic_add portably to mimic *_sub. + */ + size_t i; + for (i = cache->used_entries.count; i > 0; --i) + svn_atomic_dec(&global_handle_count); + + return APR_SUCCESS; +} + /* Creates a new file handle cache in CACHE. Up to MAX_HANDLES file handles * will be kept open. All cache-internal memory allocations during the caches' * lifetime will be done from POOL. @@ -918,6 +941,12 @@ svn_file_handle_cache__create_cache(svn_ svn_mutex__init(&new_cache->mutex, thread_safe, pool); + /* ensure we update global_handle_count correctly. */ + apr_pool_cleanup_register(pool, + new_cache, + close_all_handles, + apr_pool_cleanup_null); + /* done */ *cache = new_cache; return SVN_NO_ERROR;