summaryrefslogtreecommitdiff
path: root/src/common/mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/mutex.c')
-rw-r--r--src/common/mutex.c158
1 files changed, 91 insertions, 67 deletions
diff --git a/src/common/mutex.c b/src/common/mutex.c
index 0f02b153f..bdc2fb4dc 100644
--- a/src/common/mutex.c
+++ b/src/common/mutex.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
+ * Copyright (C) 2012-2016 Hercules Dev Team
* Copyright (C) rAthena Project (www.rathena.org)
*
* Hercules is free software: you can redistribute it and/or modify
@@ -34,7 +34,14 @@
#include <sys/time.h>
#endif
-struct ramutex{
+/** @file
+ * Implementation of the mutex interface.
+ */
+
+struct mutex_interface mutex_s;
+struct mutex_interface *mutex;
+
+struct mutex_data {
#ifdef WIN32
CRITICAL_SECTION hMutex;
#else
@@ -42,32 +49,26 @@ struct ramutex{
#endif
};
-struct racond{
+struct cond_data {
#ifdef WIN32
HANDLE events[2];
ra_align(8) volatile LONG nWaiters;
CRITICAL_SECTION waiters_lock;
-
#define EVENT_COND_SIGNAL 0
#define EVENT_COND_BROADCAST 1
-
#else
pthread_cond_t hCond;
#endif
};
-////////////////////
-// Mutex
-//
-// Implementation:
-//
+/* Mutex */
-ramutex *ramutex_create(void) {
- struct ramutex *m;
-
- m = (struct ramutex*)aMalloc( sizeof(struct ramutex) );
+/// @copydoc mutex_interface::create()
+struct mutex_data *mutex_create(void)
+{
+ struct mutex_data *m = aMalloc(sizeof(struct mutex_data));
if (m == NULL) {
- ShowFatalError("ramutex_create: OOM while allocating %"PRIuS" bytes.\n", sizeof(struct ramutex));
+ ShowFatalError("ramutex_create: OOM while allocating %"PRIuS" bytes.\n", sizeof(struct mutex_data));
return NULL;
}
@@ -78,10 +79,11 @@ ramutex *ramutex_create(void) {
#endif
return m;
-}//end: ramutex_create()
-
-void ramutex_destroy(ramutex *m) {
+}
+/// @copydoc mutex_interface::destroy()
+void mutex_destroy(struct mutex_data *m)
+{
#ifdef WIN32
DeleteCriticalSection(&m->hMutex);
#else
@@ -89,53 +91,49 @@ void ramutex_destroy(ramutex *m) {
#endif
aFree(m);
+}
-}//end: ramutex_destroy()
-
-void ramutex_lock(ramutex *m) {
-
+/// @copydoc mutex_interface::lock()
+void mutex_lock(struct mutex_data *m)
+{
#ifdef WIN32
EnterCriticalSection(&m->hMutex);
#else
pthread_mutex_lock(&m->hMutex);
#endif
-}//end: ramutex_lock
+}
-bool ramutex_trylock(ramutex *m) {
+/// @copydoc mutex_interface::trylock()
+bool mutex_trylock(struct mutex_data *m)
+{
#ifdef WIN32
- if(TryEnterCriticalSection(&m->hMutex) != FALSE)
+ if (TryEnterCriticalSection(&m->hMutex) != FALSE)
return true;
-
- return false;
#else
- if(pthread_mutex_trylock(&m->hMutex) == 0)
+ if (pthread_mutex_trylock(&m->hMutex) == 0)
return true;
-
- return false;
#endif
-}//end: ramutex_trylock()
+ return false;
+}
-void ramutex_unlock(ramutex *m) {
+/// @copydoc mutex_interface::unlock()
+void mutex_unlock(struct mutex_data *m)
+{
#ifdef WIN32
LeaveCriticalSection(&m->hMutex);
#else
pthread_mutex_unlock(&m->hMutex);
#endif
+}
-}//end: ramutex_unlock()
-
-///////////////
-// Condition Variables
-//
-// Implementation:
-//
+/* Conditional variable */
-racond *racond_create(void) {
- struct racond *c;
-
- c = (struct racond*)aMalloc( sizeof(struct racond) );
+/// @copydoc mutex_interface::cond_create()
+struct cond_data *cond_create(void)
+{
+ struct cond_data *c = aMalloc(sizeof(struct cond_data));
if (c == NULL) {
- ShowFatalError("racond_create: OOM while allocating %"PRIuS" bytes\n", sizeof(struct racond));
+ ShowFatalError("racond_create: OOM while allocating %"PRIuS" bytes\n", sizeof(struct cond_data));
return NULL;
}
@@ -149,21 +147,25 @@ racond *racond_create(void) {
#endif
return c;
-}//end: racond_create()
+}
-void racond_destroy(racond *c) {
+/// @copydoc mutex_interface::cond_destroy()
+void cond_destroy(struct cond_data *c)
+{
#ifdef WIN32
- CloseHandle( c->events[ EVENT_COND_SIGNAL ] );
- CloseHandle( c->events[ EVENT_COND_BROADCAST ] );
- DeleteCriticalSection( &c->waiters_lock );
+ CloseHandle(c->events[EVENT_COND_SIGNAL]);
+ CloseHandle(c->events[EVENT_COND_BROADCAST]);
+ DeleteCriticalSection(&c->waiters_lock);
#else
pthread_cond_destroy(&c->hCond);
#endif
aFree(c);
-}//end: racond_destroy()
+}
-void racond_wait(racond *c, ramutex *m, sysint timeout_ticks) {
+/// @copydoc mutex_interface::cond_wait()
+void cond_wait(struct cond_data *c, struct mutex_data *m, sysint timeout_ticks)
+{
#ifdef WIN32
register DWORD ms;
int result;
@@ -173,7 +175,7 @@ void racond_wait(racond *c, ramutex *m, sysint timeout_ticks) {
c->nWaiters++;
LeaveCriticalSection(&c->waiters_lock);
- if(timeout_ticks < 0)
+ if (timeout_ticks < 0)
ms = INFINITE;
else
ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks;
@@ -181,27 +183,27 @@ void racond_wait(racond *c, ramutex *m, sysint timeout_ticks) {
// we can release the mutex (m) here, cause win's
// manual reset events maintain state when used with
// SetEvent()
- ramutex_unlock(m);
+ mutex->unlock(m);
result = WaitForMultipleObjects(2, c->events, FALSE, ms);
EnterCriticalSection(&c->waiters_lock);
c->nWaiters--;
- if( (result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0) )
+ if ((result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0))
is_last = true; // Broadcast called!
LeaveCriticalSection(&c->waiters_lock);
// we are the last waiter that has to be notified, or to stop waiting
// so we have to do a manual reset
- if(is_last == true)
+ if (is_last == true)
ResetEvent( c->events[EVENT_COND_BROADCAST] );
- ramutex_lock(m);
+ mutex->lock(m);
#else
- if(timeout_ticks < 0){
- pthread_cond_wait( &c->hCond, &m->hMutex );
- }else{
+ if (timeout_ticks < 0) {
+ pthread_cond_wait(&c->hCond, &m->hMutex);
+ } else {
struct timespec wtime;
int64 exact_timeout = timer->gettick() + timeout_ticks;
@@ -210,11 +212,12 @@ void racond_wait(racond *c, ramutex *m, sysint timeout_ticks) {
pthread_cond_timedwait( &c->hCond, &m->hMutex, &wtime);
}
-
#endif
-}//end: racond_wait()
+}
-void racond_signal(racond *c) {
+/// @copydoc mutex_interface::cond_signal()
+void cond_signal(struct cond_data *c)
+{
#ifdef WIN32
# if 0
bool has_waiters = false;
@@ -225,13 +228,15 @@ void racond_signal(racond *c) {
if(has_waiters == true)
# endif // 0
- SetEvent( c->events[ EVENT_COND_SIGNAL ] );
+ SetEvent(c->events[EVENT_COND_SIGNAL]);
#else
pthread_cond_signal(&c->hCond);
#endif
-}//end: racond_signal()
+}
-void racond_broadcast(racond *c) {
+/// @copydoc mutex_interface::cond_broadcast()
+void cond_broadcast(struct cond_data *c)
+{
#ifdef WIN32
# if 0
bool has_waiters = false;
@@ -242,8 +247,27 @@ void racond_broadcast(racond *c) {
if(has_waiters == true)
# endif // 0
- SetEvent( c->events[ EVENT_COND_BROADCAST ] );
+ SetEvent(c->events[EVENT_COND_BROADCAST]);
#else
pthread_cond_broadcast(&c->hCond);
#endif
-}//end: racond_broadcast()
+}
+
+/**
+ * Interface base initialization.
+ */
+void mutex_defaults(void)
+{
+ mutex = &mutex_s;
+ mutex->create = mutex_create;
+ mutex->destroy = mutex_destroy;
+ mutex->lock = mutex_lock;
+ mutex->trylock = mutex_trylock;
+ mutex->unlock = mutex_unlock;
+
+ mutex->cond_create = cond_create;
+ mutex->cond_destroy = cond_destroy;
+ mutex->cond_wait = cond_wait;
+ mutex->cond_signal = cond_signal;
+ mutex->cond_broadcast = cond_broadcast;
+}