forked from 0ad/0ad
add support for recursive mutex on windows; ensure h_mgr uses them (pthread doesnt guarantee default type is recursive)
This was SVN commit r10247.
This commit is contained in:
parent
579f1acb6f
commit
80df13f47b
@ -503,22 +503,22 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static pthread_mutex_t h_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t h_mutex;
|
||||
// (the same class is defined in vfs.cpp, but it is easier to
|
||||
// just duplicate it to avoid having to specify the mutex.
|
||||
// such a class exists in ps/ThreadUtil.h, but we can't
|
||||
// take a dependency on that module here.)
|
||||
struct ScopedLock
|
||||
struct H_ScopedLock
|
||||
{
|
||||
ScopedLock() { pthread_mutex_lock(&h_mutex); }
|
||||
~ScopedLock() { pthread_mutex_unlock(&h_mutex); }
|
||||
H_ScopedLock() { pthread_mutex_lock(&h_mutex); }
|
||||
~H_ScopedLock() { pthread_mutex_unlock(&h_mutex); }
|
||||
};
|
||||
|
||||
|
||||
// any further params are passed to type's init routine
|
||||
Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t flags, ...)
|
||||
{
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
|
||||
RETURN_STATUS_IF_ERR(type_validate(type));
|
||||
|
||||
@ -582,7 +582,7 @@ static void h_free_hd(HDATA* hd)
|
||||
|
||||
Status h_free(Handle& h, H_Type type)
|
||||
{
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
|
||||
// 0-initialized or an error code; don't complain because this
|
||||
// happens often and is harmless.
|
||||
@ -636,7 +636,7 @@ VfsPath h_filename(const Handle h)
|
||||
// TODO: what if iterating through all handles is too slow?
|
||||
Status h_reload(const PIVFS& vfs, const VfsPath& pathname)
|
||||
{
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
|
||||
const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
|
||||
|
||||
@ -678,7 +678,7 @@ Status h_reload(const PIVFS& vfs, const VfsPath& pathname)
|
||||
|
||||
Handle h_find(H_Type type, uintptr_t key)
|
||||
{
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
return key_find(key, type);
|
||||
}
|
||||
|
||||
@ -692,7 +692,7 @@ Handle h_find(H_Type type, uintptr_t key)
|
||||
// at that point, all (cached) OpenAL resources must be freed.
|
||||
Status h_force_free(Handle h, H_Type type)
|
||||
{
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
|
||||
// require valid index; ignore tag; type checked below.
|
||||
HDATA* hd;
|
||||
@ -743,6 +743,18 @@ static ModuleInitState initState;
|
||||
|
||||
static Status Init()
|
||||
{
|
||||
// lock must be recursive (e.g. h_alloc calls h_find)
|
||||
pthread_mutexattr_t attr;
|
||||
int err;
|
||||
err = pthread_mutexattr_init(&attr);
|
||||
ENSURE(err == 0);
|
||||
err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
ENSURE(err == 0);
|
||||
err = pthread_mutex_init(&h_mutex, &attr);
|
||||
ENSURE(err == 0);
|
||||
err = pthread_mutexattr_destroy(&attr);
|
||||
ENSURE(err == 0);
|
||||
|
||||
RETURN_STATUS_IF_ERR(pool_create(&hpool, hdata_cap*sizeof(HDATA), sizeof(HDATA)));
|
||||
return INFO::OK;
|
||||
}
|
||||
@ -755,7 +767,7 @@ static void Shutdown()
|
||||
// raise a double-free warning unless we ignore it. (#860, #915, #920)
|
||||
ignoreDoubleFree = true;
|
||||
|
||||
ScopedLock s;
|
||||
H_ScopedLock s;
|
||||
|
||||
// forcibly close all open handles
|
||||
for(HDATA* hd = (HDATA*)hpool.da.base; hd < (HDATA*)(hpool.da.base + hpool.da.pos); hd = (HDATA*)(uintptr_t(hd)+hpool.el_size))
|
||||
|
@ -255,6 +255,29 @@ again:
|
||||
// note: we use wutil_Allocate instead of new because the (no longer extant)
|
||||
// memory manager used a pthread_mutex.
|
||||
|
||||
|
||||
int pthread_mutexattr_init(pthread_mutexattr_t* UNUSED(attr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_destroy(pthread_mutexattr_t* UNUSED(attr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t* UNUSED(attr), int* type)
|
||||
{
|
||||
*type = PTHREAD_MUTEX_RECURSIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t* UNUSED(attr), int type)
|
||||
{
|
||||
return (type == PTHREAD_MUTEX_RECURSIVE)? 0 : -ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
static CRITICAL_SECTION* CRITICAL_SECTION_from_pthread_mutex_t(pthread_mutex_t* m)
|
||||
{
|
||||
if(!m)
|
||||
|
@ -71,11 +71,17 @@ LIB_API int pthread_cancel(pthread_t thread);
|
||||
LIB_API int pthread_join(pthread_t thread, void** value_ptr);
|
||||
|
||||
// mutex
|
||||
typedef void* pthread_mutex_t; // pointer to critical section
|
||||
typedef void pthread_mutexattr_t;
|
||||
#define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer()
|
||||
|
||||
typedef void* pthread_mutexattr_t;
|
||||
LIB_API int pthread_mutexattr_init(pthread_mutexattr_t* attr);
|
||||
LIB_API int pthread_mutexattr_destroy(pthread_mutexattr_t* attr);
|
||||
enum { PTHREAD_MUTEX_RECURSIVE }; // the only one we support
|
||||
LIB_API int pthread_mutexattr_gettype(const pthread_mutexattr_t* attr, int* type);
|
||||
LIB_API int pthread_mutexattr_settype(pthread_mutexattr_t* attr, int type);
|
||||
|
||||
typedef void* pthread_mutex_t; // pointer to critical section
|
||||
LIB_API pthread_mutex_t pthread_mutex_initializer();
|
||||
#define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer()
|
||||
LIB_API int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*);
|
||||
LIB_API int pthread_mutex_destroy(pthread_mutex_t*);
|
||||
LIB_API int pthread_mutex_lock(pthread_mutex_t*);
|
||||
|
Loading…
Reference in New Issue
Block a user