Lumiera  0.pre.03
»edityourfreedom«
filehandlecache.c
Go to the documentation of this file.
1 /*
2  FileHandleCache - filehandle management and caching
3 
4  Copyright (C) Lumiera.org
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
30 #include "include/logging.h"
31 #include "lib/safeclib.h"
32 
33 #include "backend/file.h"
35 
36 
37 
38 LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available");
39 
40 
45 
46 
47 
48 void
49 lumiera_filehandlecache_new (int max_entries)
50 {
51  REQUIRE (!lumiera_fhcache, "Filehandlecache already initialised");
52 
53  lumiera_fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache));
55  lumiera_fhcache->available = max_entries;
56  lumiera_fhcache->checked_out = 0;
57  lumiera_mutex_init (&lumiera_fhcache->lock, "filehandlecache", &NOBUG_FLAG (mutex_dbg), NOBUG_CONTEXT);
58 }
59 
60 
61 void
63 {
64  if (lumiera_fhcache)
65  {
66  REQUIRE (!lumiera_fhcache->checked_out, "Filehandles in use at shutdown");
68  lumiera_mutex_destroy (&lumiera_fhcache->lock, &NOBUG_FLAG (mutex_dbg), NOBUG_CONTEXT);
71  }
72 }
73 
74 
77 {
78  TRACE (filehandlecache_dbg);
79  LumieraFilehandle ret = NULL;
80 
81  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_fhcache->lock)
82  {
83  if (lumiera_fhcache->available <= 0 && lumiera_fhcache->cache.cached)
84  {
85  /* pop a filehandle from cache */
86  ret = lumiera_mrucache_pop (&lumiera_fhcache->cache);
88  if (lumiera_fhcache->available < 0)
89  /* try to free overallocated filehandles */
90  lumiera_fhcache->available -= lumiera_fhcache->available + lumiera_mrucache_age (&lumiera_fhcache->cache, -lumiera_fhcache->available);
91  }
92  else
93  {
94  /* allocate new filehandle if we are below the limit or no cached handles are available (overallocating) */
95  NOTICE (file, "overallocating filehandle");
96  ret = lumiera_filehandle_new (desc);
97  TODO ("use resourcecollector here");
98  if (!ret)
99  LUMIERA_ERROR_SET_ALERT (file, FILEHANDLECACHE_NOHANDLE, lumiera_filedescriptor_name (desc));
100  else
101  --lumiera_fhcache->available;
102  }
103  desc->handle = ret;
104  ++lumiera_fhcache->checked_out;
105  }
106  return ret;
107 }
108 
109 
112 {
113  TRACE (filehandlecache_dbg);
114  REQUIRE (handle);
115  /* This function is called with the associated descriptor locked, nothing can modify 'handle' */
116  if (!handle->use_cnt)
117  {
118  /* lock cache and checkout */
119  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_fhcache->lock)
120  {
121  lumiera_mrucache_checkout (&lumiera_fhcache->cache, &handle->cachenode);
122  ++lumiera_fhcache->checked_out;
123  }
124  }
125  ++handle->use_cnt;
126 
127  return handle;
128 }
129 
130 
131 void
133 {
134  TRACE (filehandlecache_dbg);
135  REQUIRE (handle);
136  REQUIRE (handle->use_cnt);
137 
138  /* This function is called with the associated descriptor locked, nothing can modify the fhcache */
139  if (!--handle->use_cnt)
140  {
141  /* lock cache and checin */
142  LUMIERA_MUTEX_SECTION (mutex_sync, &lumiera_fhcache->lock)
143  {
144  --lumiera_fhcache->checked_out;
145  lumiera_mrucache_checkin (&lumiera_fhcache->cache, &handle->cachenode);
146  }
147  }
148 }
149 
Portable and safe wrappers around some C-Lib functions.
static void lumiera_mrucache_checkout(LumieraMruCache self, LList node)
Checkout an element from a cache.
Definition: mrucache.h:135
LumieraFilehandle lumiera_filehandle_init(LumieraFilehandle self, LumieraFiledescriptor desc)
Initialise filehandle structure.
Definition: filehandle.c:43
static void * lumiera_mrucache_pop(LumieraMruCache self)
Destroy the oldest element from the cache and return it.
Definition: mrucache.h:153
void lumiera_filehandlecache_delete(void)
Delete the filehandle cache.
#define LUMIERA_ERROR_SET_ALERT(flag, err, extra)
Helper macro to raise an error for the current thread.
Definition: error.h:106
LumieraFilehandle lumiera_filehandlecache_checkout(LumieraFilehandle handle)
Remove a filehandle from cache aging Filehandles which are subject of cache aging must be checked out...
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx)
Mutual exclusive section.
Definition: mutex.h:41
File management.
lumiera_filehandlecache * LumieraFilehandlecache
This header is for including and configuring NoBug.
lumiera_filehandle * LumieraFilehandle
Definition: filehandle.h:38
static void lumiera_free(void *mem)
Free previously allocated memory.
Definition: safeclib.h:82
LUMIERA_ERROR_DEFINE(FILEHANDLECACHE_NOHANDLE, "No filehandle available")
LumieraMruCache lumiera_mrucache_init(LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb)
Initialise a cache.
Definition: mrucache.c:32
void lumiera_filehandlecache_checkin(LumieraFilehandle handle)
Put a filehandle into the cache Filehandles which are checked in are subject of cache aging and might...
LumieraFilehandlecache lumiera_fhcache
the global cache for file handles.
static void lumiera_mrucache_checkin(LumieraMruCache self, LList node)
Add an element to a mrucache.
Definition: mrucache.h:85
return NULL
Definition: llist.h:596
void * lumiera_malloc(size_t size)
Allocate memory.
Definition: safeclib.c:67
lumiera_filedescriptor * LumieraFiledescriptor
int lumiera_mrucache_age(LumieraMruCache self, int nelem)
Destroy and free the nelem oldest elements.
Definition: mrucache.c:57
TRACE(test, "inserted %d", data)
void * lumiera_filehandle_destroy_node(LList node)
destroy the resources associated either a filehandle structure.
Definition: filehandle.c:66
void lumiera_filehandlecache_new(int max_entries)
Initialises the filehandle cache.
LumieraMutex lumiera_mutex_init(LumieraMutex self, const char *purpose, struct nobug_flag *flag, const struct nobug_context ctx)
Initialise a mutex variable This initialises a &#39;fast&#39; default mutex which must not be locked recursiv...
Definition: mutex.c:30
LumieraFilehandle lumiera_filehandlecache_handle_acquire(LumieraFiledescriptor desc)
Get a fresh filehandle.
LumieraMruCache lumiera_mrucache_destroy(LumieraMruCache self)
Destroy a cache.
Definition: mrucache.c:42
const char * lumiera_filedescriptor_name(LumieraFiledescriptor self)
Caching and management of filehandles.
LumieraFilehandle lumiera_filehandle_new(LumieraFiledescriptor desc)
Allocate a new filehandle structure.
Definition: filehandle.c:58
LumieraMutex lumiera_mutex_destroy(LumieraMutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a mutex variable.
Definition: mutex.c:48