#include <pthread.h>
enum locktype{
READER =0,
WRITER
};
typedef struct QNode {
locktype _type;
struct QNode* pNext;
} QNode;
tyepdef struct Queue {
QNode* _pHead;
} Queue;
typdef struct RWLock {
Queue* _pQueue;
ptread_mutex_t _lock;
pthread_cond_t _condv;
uint32_t _currentReaderCount;
bool _writeLocked;
} RWLock;
void
int
rw_lock_init(RWLock* pLock)
{
if (pLock == NULL) {
return ENULL;
}
pLock->pQueue = (Queue*) malloc(sizeof(queue));
if (pLock->pQueue == NULL) {
return ENULL;
}
initQueue(pLock->pQueue);
if (pthread_mutex_init(&pLock->_lock)) {
return EMUTEX_INIT;
}
if (pthread_cond_init(&pLock0>conv)) {
return ECOND_INIT;
}
_readCount = 0;
_writerLocked = false;
}
int
reader_rw_lock(RWlock* pRWLock)
{
if (pRWLock == NULL) {
return ENULL;
}
if (pthread_mutex_lock(&pRWLock->_lock)) {
return EMUTEX_LOCK;
}
while((pQueue->pHead) || pQueue->_writerLocked)) {
pQueue->insert(READER);
if (pthread_cond_wait(&pRWLock->_lock, &pRWLock->condv)) {
pthread_mutex_unlock(&pRWLock->lock));
return ECONDWAIT;
}
}
pRWLock->readCount++;
pthread_mutex_unlock(&pRWlock->_lock);
return 0;
}
int.
reader_rw_destroy(RWLock* pRWLock)
{
if (pRWLock == NULL) {
return ENULL;
}
pthread_mutex_lock(&pRWlock->_lock);
if (pRWLock->_readerCount || pRWLock->_writeLock || pRWLock->_pHead) {
pthread_mutex_unlock(&pRWlock->_lock);
return EBUSY;
}
pthread_cond_destroy(pRWLock->_condv);
pthread_mutex_unlock(&pRWlock->_lock);
pthread_mutex_destory(&pRwlock->lock);
return 0;
}
int
writer_rw_lock(RWLock* pRWlock)
{
if (pRWlock == NULL) {
return ENULL;
}
if (pthread_mutex_lock(&pRWlock->_lock) {
return EMUTEX_LOCK;
}
while ((pQueue->pHead) || (pQueue->_writeLocked) || pQueue->_readCount)) {
pQueue->insert(WRITER);
if (pthread_cond_wait(&pRWLock->_lock, &pRWLock->condv)) {
pthread_mutex_unlock(&pRWLock->lock));
return ECONDWAIT;
}
}
pRWLock->writerLocked = true;
pthread_mutext_unlock(&pRWlock->_lock);
return 0;
}
int
rw_unlock(RWLock* pRWlock)
{
if (pRWLock == NULL) {
return ENULL;
}
if (pthread_mutex_lock(&pRWlock->_lock) {
return EMUTEX_LOCK;
}
if (pRWLock->_readcount) {
pRWLock->_readcount -= 1;
}
if (pRWLock->_writelocked) {
pRWLock->_writeLock = false;
}
if ((pRWLock->_readCount == 0)&& (pRWLock->_writeLocked == false)) {
if (pRWLock->_pHead) {
if (pRWlock->_pHeade->_type == READER) {
while (pRWLock->pHeader && (pRWLock->pHeader->_ptype == WRITER) {
pthread_cond_signal(pRWLock->pCondv);
removeHead(pRWLock->pQueue);
}
} else {
pthread_cond_signal(pRWLock->pCondv);
removeHead(pRWLock->pQueue);
}
}
}
return 0;
}