27 #include "precompiled.h"
30 #include <boost/unordered_map.hpp>
123 const size_t idxPlusOne = idx+1;
126 Handle h = tag | idxPlusOne;
196 if(
size_t(idx) >=
size_t(hdata_cap))
208 return (uintptr_t(hd) - uintptr_t(hpool.
da.
base))/hpool.
el_size;
221 if(uintptr_t(hd) > uintptr_t(hpool.
da.
base)+hpool.
da.
pos)
285 typedef boost::unordered_multimap<uintptr_t, ssize_t>
Key2Idx;
286 typedef Key2Idx::iterator
It;
293 Key2Idx* key2idx = key2idx_wrapper.
get();
303 std::pair<It, It> range = key2idx->equal_range(key);
304 for(It it = range.first; it != range.second; ++it)
310 if(hd->
type != type || hd->
key != key)
320 key2idx_wrapper.
lock();
327 Key2Idx* key2idx = key2idx_wrapper.
get();
334 (void)key2idx->insert(std::make_pair(key, idx));
336 key2idx_wrapper.
lock();
368 for(
const u8* p = start; p < end; p++)
446 err = vtbl->
reload(hd->
user, vfs, pathname, h);
450 catch(std::bad_alloc&)
535 va_start(args, flags);
578 memset(hd, 0,
sizeof(*hd));
649 if(hd->key == 0 || hd->key != key || hd->disallow_reload)
651 hd->type->dtor(hd->user);
660 if(hd->key == 0 || hd->key != key || hd->disallow_reload)
663 Status err = hd->type->reload(hd->user, vfs, hd->pathname, hd->h);
764 debug_printf(L
"H_MGR| shutdown. any handle frees after this are leaks!\n");
768 ignoreDoubleFree =
true;
792 ignoreDoubleFree =
true;
800 if (hd->key == 0 || hd->type != type)
static OverrunProtector< Key2Idx > key2idx_wrapper
Status h_free(Handle &h, H_Type type)
static void key_remove(uintptr_t key, H_Type type)
OverrunProtector wraps an arbitrary object in isolated page(s) and can detect inadvertent writes to i...
Status(* to_string)(const void *user, wchar_t *buf)
Status h_force_free(Handle h, H_Type type)
Path VfsPath
VFS path of the form "(dir/)*file?".
static Status h_data_tag(Handle h, HDATA *&hd)
static const Status H_TAG_MISMATCH
void pool_free(Pool *p, void *el)
Make a fixed-size element available for reuse in the given Pool.
boost::unordered_multimap< uintptr_t, ssize_t > Key2Idx
void * pool_alloc(Pool *p, size_t size)
Dole out memory from the pool.
static size_t h_idx(const Handle h)
static void warn_if_invalid(HDATA *hd)
static ssize_t h_idx_from_data(HDATA *hd)
static ModuleInitState initState
static const u64 IDX_MASK
VfsPath h_filename(const Handle h)
Handle h_alloc(H_Type type, const PIVFS &vfs, const VfsPath &pathname, size_t flags,...)
static Status type_validate(H_Type type)
Status pool_create(Pool *p, size_t max_size, size_t el_size)
Ready Pool for use.
int wcscpy_s(wchar_t *dst, size_t max_dst_chars, const wchar_t *src)
intptr_t h_get_refcnt(Handle h)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
intptr_t ModuleInitState
initialization state of a module (class, source file, etc.) must be initialized to zero (e...
static Status h_data_from_idx(ssize_t idx, HDATA *&hd)
static pthread_mutex_t h_mutex
void * pthread_mutexattr_t
static Handle alloc_new_handle(H_Type type, const PIVFS &vfs, const VfsPath &pathname, uintptr_t key, size_t flags, va_list *init_args)
static bool ignoreDoubleFree
const Status INVALID_POINTER
bool debug_filter_allows(const wchar_t *text)
indicate if the given text would be printed.
static Handle key_find(uintptr_t key, H_Type type, KeyRemoveFlag remove_option=KEY_NOREMOVE)
const String & string() const
static Handle reuse_existing_handle(uintptr_t key, H_Type type, size_t flags)
static void key_add(uintptr_t key, Handle h)
int pthread_mutex_lock(pthread_mutex_t *m)
Status h_reload(const PIVFS &vfs, const VfsPath &pathname)
const Status INVALID_PARAM
Status(* reload)(void *user, const PIVFS &vfs, const VfsPath &pathname, Handle)
Handle h_find(H_Type type, uintptr_t key)
i64 Status
Error handling system.
i64 Handle
`handle' representing a reference to a resource (sound, texture, etc.)
void h_mgr_free_type(const H_Type type)
int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *)
allocator design parameters:
static Status h_data_no_tag(const Handle h, HDATA *&hd)
#define STATUS_ADD_DEFINITIONS(definitions)
add a module's array of StatusDefinition to the list.
static const Status H_IDX_INVALID
static const ssize_t hdata_cap
#define DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code.
u32 fnv_hash(const void *buf, size_t len)
rationale: this algorithm was chosen because it delivers 'good' results for string data and is relati...
void(* init)(void *user, va_list)
static const StatusDefinition hStatusDefinitions[]
static const Status H_IDX_UNUSED
Status ModuleShutdown(volatile ModuleInitState *initState, void(*shutdown)())
calls a user-defined shutdown function if initState is "initialized".
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
size_t el_size
size of elements.
static Status call_init_and_reload(Handle h, H_Type type, HDATA *hd, const PIVFS &vfs, const VfsPath &pathname, va_list *init_args)
int pthread_mutex_unlock(pthread_mutex_t *m)
void * h_user_data(const Handle h, const H_Type type)
#define WARN_RETURN(status)
static const size_t HDATA_USER_SIZE
static Handle handle(size_t idx, u64 tag)
Status pool_destroy(Pool *p)
free all memory (address space + physical) that constitutes the given Pool.
static void h_free_hd(HDATA *hd)
static const u64 TAG_MASK
Status(* validate)(const void *user)
const size_t H_STRING_LEN
static const Status H_TYPE_MISMATCH
#define cassert(expr)
Compile-time assertion.
static Tag h_tag(Handle h)
static Status h_data_tag_type(const Handle h, const H_Type type, HDATA *&hd)
static const Status H_ALREADY_FREED
Status ModuleInit(volatile ModuleInitState *initState, Status(*init)())
calls a user-defined init function if initState is zero.
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
#define RETURN_STATUS_IF_ERR(expression)
bool pool_contains(const Pool *p, void *el)
indicate whether a pointer was allocated from the given pool.
int pthread_mutexattr_init(pthread_mutexattr_t *attr)