X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsymbian%2Fsilcsymbianthread.cpp;h=d4d788dc81824f279bd001b94752968c00650561;hb=0f95f4926c8579fe3cc36c9e68f36b67170a0c8e;hp=7e134e527d13281ec9880ca8fd69b7595f36e9be;hpb=66b9316f5d654e08655def94f56cfe2898754361;p=silc.git diff --git a/lib/silcutil/symbian/silcsymbianthread.cpp b/lib/silcutil/symbian/silcsymbianthread.cpp index 7e134e52..d4d788dc 100644 --- a/lib/silcutil/symbian/silcsymbianthread.cpp +++ b/lib/silcutil/symbian/silcsymbianthread.cpp @@ -214,6 +214,92 @@ void silc_mutex_assert_locked(SilcMutex mutex) #endif /* SILC_THREADS */ } +/***************************** SILC Rwlock API *****************************/ + +/* SILC read/write lock structure */ +struct SilcRwLockStruct { +#ifdef SILC_THREADS + SilcMutex mutex; + SilcCond cond; +#endif /* SILC_THREADS */ + unsigned int readers : 31; + unsigned int locked : 1; +}; + +SilcBool silc_rwlock_alloc(SilcRwLock *rwlock) +{ +#ifdef SILC_THREADS + *rwlock = (SilcRwLock)silc_calloc(1, sizeof(**rwlock)); + if (!(*rwlock)) + return FALSE; + if (!silc_mutex_alloc(&(*rwlock)->mutex)) { + silc_free(*rwlock); + return FALSE; + } + if (!silc_cond_alloc(&(*rwlock)->cond)) { + silc_mutex_free((*rwlock)->mutex); + silc_free(*rwlock); + return FALSE; + } + return TRUE; +#else + return FALSE; +#endif /* SILC_THREADS */ +} + +void silc_rwlock_free(SilcRwLock rwlock) +{ +#ifdef SILC_THREADS + if (mutex) { + silc_mutex_free(rwlock->mutex); + silc_cond_free(rwlock->cond); + silc_free(rwlock); + } +#endif /* SILC_THREADS */ +} + +void silc_rwlock_rdlock(SilcRwLock rwlock) +{ +#ifdef SILC_THREADS + if (rwlock) { + silc_mutex_lock(rwlock->mutex); + rwlock->readers++; + silc_mutex_unlock(rwlock->mutex); + } +#endif /* SILC_THREADS */ +} + +void silc_rwlock_wrlock(SilcRwLock rwlock) +{ +#ifdef SILC_THREADS + if (rwlock) { + silc_mutex_lock(rwlock->mutex); + while (rwlock->readers > 0) + silc_cond_wait(rwlock->cond, rwlock->mutex); + rwlock->locked = TRUE; + } +#endif /* SILC_THREADS */ +} + +void silc_rwlock_unlock(SilcRwLock rwlock) +{ +#ifdef SILC_THREADS + if (rwlock) { + if (rwlock->locked) { + /* Unlock writer */ + rwlock->locked = FALSE; + silc_mutex_unlock(rwlock->mutex); + return; + } + + /* Unlock reader */ + silc_mutex_lock(rwlock->mutex); + rwlock->readers--; + silc_cond_broadcast(rwlock->cond); + silc_mutex_unlock(rwlock->mutex); + } +#endif /* SILC_THREADS */ +} /****************************** SILC Cond API *******************************/