forked from enlightenment/efl
eina: add Eina_LockRW. more refactoring code comming.
SVN revision: 60628
This commit is contained in:
parent
c83256416a
commit
a5fe2772c7
|
@ -110,3 +110,7 @@
|
||||||
|
|
||||||
* Add eina_hash_free_cb_set to change the free callback during the
|
* Add eina_hash_free_cb_set to change the free callback during the
|
||||||
life of an Eina_Hash.
|
life of an Eina_Hash.
|
||||||
|
|
||||||
|
2011-06-23 Cedric Bail
|
||||||
|
|
||||||
|
* Add Eina_LockRW.
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef void (*Eina_Lock_Bt_Func) ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct _Eina_Lock Eina_Lock;
|
typedef struct _Eina_Lock Eina_Lock;
|
||||||
|
typedef struct _Eina_RWLock Eina_RWLock;
|
||||||
typedef struct _Eina_Condition Eina_Condition;
|
typedef struct _Eina_Condition Eina_Condition;
|
||||||
|
|
||||||
struct _Eina_Lock
|
struct _Eina_Lock
|
||||||
|
@ -62,6 +63,14 @@ struct _Eina_Condition
|
||||||
pthread_cond_t condition;
|
pthread_cond_t condition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _Eina_RWLock
|
||||||
|
{
|
||||||
|
pthread_rwlock_t mutex;
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
pthread_t lock_thread_wid;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
EAPI extern Eina_Bool _eina_threads_activated;
|
EAPI extern Eina_Bool _eina_threads_activated;
|
||||||
|
|
||||||
#ifdef EINA_HAVE_DEBUG_THREADS
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
@ -353,5 +362,80 @@ eina_condition_signal(Eina_Condition *cond)
|
||||||
return pthread_cond_signal(&(cond->condition)) == 0 ? EINA_TRUE : EINA_FALSE;
|
return pthread_cond_signal(&(cond->condition)) == 0 ? EINA_TRUE : EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rwlock_new(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
assert(pthread_equal(_eina_main_loop, pthread_self()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pthread_rwlock_init(&(mutex->mutex), NULL) != 0)
|
||||||
|
return EINA_FALSE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
eina_rwlock_free(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
assert(pthread_equal(_eina_main_loop, pthread_self()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pthread_rwlock_destroy(&(mutex->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_read(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_ON_OFF_THREADS
|
||||||
|
if (!_eina_threads_activated)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
assert(pthread_equal(_eina_main_loop, pthread_self()));
|
||||||
|
#endif
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pthread_rwlock_rdlock(&(mutex->mutex)) != 0)
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_write(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_ON_OFF_THREADS
|
||||||
|
if (!_eina_threads_activated)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
assert(pthread_equal(_eina_main_loop, pthread_self()));
|
||||||
|
#endif
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pthread_rwlock_wrlock(&(mutex->mutex)) != 0)
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_release(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_ON_OFF_THREADS
|
||||||
|
if (!_eina_threads_activated)
|
||||||
|
{
|
||||||
|
#ifdef EINA_HAVE_DEBUG_THREADS
|
||||||
|
assert(pthread_equal(_eina_main_loop, pthread_self()));
|
||||||
|
#endif
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pthread_rwlock_unlock(&(mutex->mutex)) != 0)
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
return EINA_LOCK_SUCCEED;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
* Abtract type for a mutual exclusive object.
|
* Abtract type for a mutual exclusive object.
|
||||||
*/
|
*/
|
||||||
typedef void *Eina_Lock;
|
typedef void *Eina_Lock;
|
||||||
|
typedef void *Eina_RWLock;
|
||||||
typedef void *Eina_Condition;
|
typedef void *Eina_Condition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,6 +174,35 @@ eina_condition_signal(Eina_Condition *cond EINA_UNUSED)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rwlock_new(Eina_RWLock *mutex EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
eina_rwlock_free(Eina_RWLock *mutex EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_read_take(Eina_RWLock *mutex EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_write_take(Eina_RWLock *mutex EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_release(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return EINA_LOCK_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,6 +42,19 @@ struct _Eina_Condition
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct _Eina_Win32_RWLock Eina_RWLock;
|
||||||
|
|
||||||
|
struct _Eina_Win32_RWLock
|
||||||
|
{
|
||||||
|
LONG readers_count;
|
||||||
|
LONG writers_count;
|
||||||
|
int readers;
|
||||||
|
int writers;
|
||||||
|
|
||||||
|
Eina_Lock mutex;
|
||||||
|
Eina_Condition cond_read;
|
||||||
|
Eina_Condition cond_write;
|
||||||
|
};
|
||||||
|
|
||||||
EAPI extern Eina_Bool _eina_threads_activated;
|
EAPI extern Eina_Bool _eina_threads_activated;
|
||||||
|
|
||||||
|
@ -297,4 +310,116 @@ eina_condition_signal(Eina_Condition *cond)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rwlock_new(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
if (!eina_lock_new(&(mutex->mutex))) return EINA_FALSE;
|
||||||
|
if (!eina_condition_new(&(mutex->cond_read), &(mutex->mutex)))
|
||||||
|
goto on_error1;
|
||||||
|
if (!eina_condition_new(&(mutex->cond_write), &(mutex->mutex)))
|
||||||
|
goto on_error2;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
on_error2:
|
||||||
|
eina_condition_free(&(mutex->cond_read));
|
||||||
|
on_error1:
|
||||||
|
eina_lock_free(&(mutex->mutex));
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
eina_rwlock_free(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
eina_condition_free(&(mutex->cond_read));
|
||||||
|
eina_condition_free(&(mutex->cond_write));
|
||||||
|
eina_lock_free(&(mutex->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_read(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
DWORD res;
|
||||||
|
|
||||||
|
eina_lock_take(&(x->mutex));
|
||||||
|
if (mutex->writers)
|
||||||
|
{
|
||||||
|
mutex->readers_count++;
|
||||||
|
while (mutex->writers)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&mutex->cond_write->waiters_count_lock);
|
||||||
|
mutex->cond_read->waiters_count++;
|
||||||
|
LeaveCriticalSection(&mutex->cond_write->waiters_count_lock);
|
||||||
|
res = WaitForSingleObject(mutex->cond_write->semaphore, INFINITE);
|
||||||
|
if (res != WAIT_OBJECT_0) break;
|
||||||
|
}
|
||||||
|
mutex->readers_count--;
|
||||||
|
}
|
||||||
|
if (res == 0)
|
||||||
|
mutex->readers++;
|
||||||
|
eina_lock_release(&(mutex->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_write(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
DWORD res;
|
||||||
|
|
||||||
|
eina_lock_take(&(mutex->mutex));
|
||||||
|
if (mutex->writers || mutex->readers > 0)
|
||||||
|
{
|
||||||
|
mutex->writers_count++;
|
||||||
|
while (mutex->writers || mutex->readers > 0)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&mutex->cond_write->waiters_count_lock);
|
||||||
|
mutex->cond_read->waiters_count++;
|
||||||
|
LeaveCriticalSection(&mutex->cond_write->waiters_count_lock);
|
||||||
|
res = WaitForSingleObject(mutex->cond_write->semaphore, INFINITE);
|
||||||
|
if (res != WAIT_OBJECT_0) break;
|
||||||
|
}
|
||||||
|
mutex->writers_count--;
|
||||||
|
}
|
||||||
|
if (res == 0) x->writers_count = 1;
|
||||||
|
eina_lock_release(&(mutex->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_release(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
eina_lock_take(&(mutex->mutex));
|
||||||
|
|
||||||
|
if (mutex->writers)
|
||||||
|
{
|
||||||
|
mutex->writers = 0;
|
||||||
|
if (mutex->readers_count == 1)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&mutex->cond_read->waiters_count_lock);
|
||||||
|
if (mutex->cond_read->waiters_count > 0)
|
||||||
|
ReleaseSemaphore(x->cond_read->semaphore, 1, 0);
|
||||||
|
LeaveCriticalSection(&mutex->cond_read->threads_count_lock);
|
||||||
|
}
|
||||||
|
else if (mutex->readers_count > 0)
|
||||||
|
eina_condition_broadast(&(mutex->cond_read));
|
||||||
|
else if (mutex->writers_count > 0)
|
||||||
|
{
|
||||||
|
EnterCriticalSection (&mutex->cond_write->waiters_count_lock);
|
||||||
|
if (mutex->cond_write->waiters_count > 0)
|
||||||
|
ReleaseSemaphore(mutex->cond_write->semaphore, 1, 0);
|
||||||
|
LeaveCriticalSection (&mutex->cond_write->waiters_count_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mutex->readers > 0)
|
||||||
|
{
|
||||||
|
mutex->readers--;
|
||||||
|
if (mutex->readers == 0 && mutex->writers_count > 0)
|
||||||
|
{
|
||||||
|
EnterCriticalSection (&mutex->cond_write->waiters_count_lock);
|
||||||
|
if (mutex->cond_write->waiters_count > 0)
|
||||||
|
ReleaseSemaphore(mutex->cond_write->semaphore, 1, 0);
|
||||||
|
LeaveCriticalSection (&mutex->cond_write->waiters_count_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eina_lock_release(&(mutex->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
EAPI extern Eina_Bool _threads_activated;
|
EAPI extern Eina_Bool _threads_activated;
|
||||||
|
|
||||||
typedef HANDLE Eina_Lock;
|
typedef HANDLE Eina_Lock;
|
||||||
|
typedef Eina_Lock Eina_RWLock;
|
||||||
|
|
||||||
static inline Eina_Bool
|
static inline Eina_Bool
|
||||||
eina_lock_new(Eina_Lock *mutex)
|
eina_lock_new(Eina_Lock *mutex)
|
||||||
|
@ -113,5 +114,34 @@ eina_condition_signal(Eina_Condition *cond)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rwlock_new(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return eina_lock_new(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
eina_rwlock_free(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return eina_lock_free(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_read(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return eina_lock_take(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_take_write(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return eina_lock_take(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Lock_Result
|
||||||
|
eina_rwlock_release(Eina_RWLock *mutex)
|
||||||
|
{
|
||||||
|
return eina_lock_release(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -67,6 +67,12 @@ static inline Eina_Bool eina_condition_timedwait(Eina_Condition *cond, double t)
|
||||||
static inline Eina_Bool eina_condition_broadcast(Eina_Condition *cond);
|
static inline Eina_Bool eina_condition_broadcast(Eina_Condition *cond);
|
||||||
static inline Eina_Bool eina_condition_signal(Eina_Condition *cond);
|
static inline Eina_Bool eina_condition_signal(Eina_Condition *cond);
|
||||||
|
|
||||||
|
static inline Eina_Bool eina_rwlock_new(Eina_RWLock *mutex);
|
||||||
|
static inline void eina_rwlock_free(Eina_RWLock *mutex);
|
||||||
|
static inline Eina_Lock_Result eina_rwlock_take_read(Eina_RWLock *mutex);
|
||||||
|
static inline Eina_Lock_Result eina_rwlock_take_write(Eina_RWLock *mutex);
|
||||||
|
static inline Eina_Lock_Result eina_rwlock_release(Eina_RWLock *mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue