⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prwlock.cxx

📁 使用stl技术,(还没看,是听说的)
💻 CXX
字号:
/*
 *
 *  C++ Portable Types Library (PTypes)
 *  Version 1.8.3  Released 25-Aug-2003
 *
 *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan
 *
 *  http://www.melikyan.com/ptypes/
 *  http://ptypes.sourceforge.net/
 *
 */

#ifdef WIN32
#  include <windows.h>
#else
#  include <pthread.h>
#endif

#include "pasync.h"


PTYPES_BEGIN


static void rwlock_fail()
{
    fatal(CRIT_FIRST + 41, "rwlock failed");
}


inline void syscheck(int r)
{
    if (r != 0)
        rwlock_fail();
}


#ifdef __PTYPES_RWLOCK__


#  ifdef WIN32

//
// this implementation of the read/write lock is derived
// from Apache Portable Runtime (APR) source, which 
// in turn was originally based on an erroneous (or just
// incomplete?) example in one of the MSDN technical articles.
// 

rwlock::rwlock()
    : mutex(), readcnt(-1), writecnt(0)
{
    reading = CreateEvent(0, true, false, 0);
    finished = CreateEvent(0, false, true, 0);
    if (reading == 0 || finished == 0)
        rwlock_fail();
}


rwlock::~rwlock()
{
    CloseHandle(reading);
    CloseHandle(finished);
}


void rwlock::rdlock()
{
    if (pincrement(&readcnt) == 0) 
    {
        WaitForSingleObject(finished, INFINITE);
        SetEvent(reading);
    }
    WaitForSingleObject(reading, INFINITE);
}


void rwlock::wrlock()
{
    mutex::enter();
    WaitForSingleObject(finished, INFINITE);
    writecnt++;
}


void rwlock::unlock()
{
    if (writecnt != 0) 
    {
        writecnt--;
        SetEvent(finished);
        mutex::leave();
    } 
    else if (pdecrement(&readcnt) < 0) 
    {
        ResetEvent(reading);
        SetEvent(finished);
    } 
}


#  else	  // !defined(WIN32)

//
// for other platforms that lack POSIX rwlock we implement
// the rwlock object using POSIX condvar. the code below
// is based on Sean Burke's algorithm posted in 
// comp.programming.threads.
//


rwlock::rwlock()
    : locks(0), writers(0), readers(0)
{
    syscheck(pthread_mutex_init(&mtx, 0));
    syscheck(pthread_cond_init(&readcond, 0));
    syscheck(pthread_cond_init(&writecond, 0));
}


rwlock::~rwlock()
{
    pthread_cond_destroy(&writecond);
    pthread_cond_destroy(&readcond);
    pthread_mutex_destroy(&mtx);
}


void rwlock::rdlock()
{
    pthread_mutex_lock(&mtx);
    readers++;
    while (locks < 0)
	pthread_cond_wait(&readcond, &mtx);
    readers--;
    locks++;
    pthread_mutex_unlock(&mtx);
}


void rwlock::wrlock()
{
    pthread_mutex_lock(&mtx);
    writers++;
    while (locks != 0)
	pthread_cond_wait(&writecond, &mtx);
    locks = -1;
    writers--;
    pthread_mutex_unlock(&mtx);
}


void rwlock::unlock()
{
    pthread_mutex_lock(&mtx);
    if (locks > 0)
    {
	locks--;
	if (locks == 0)
	    pthread_cond_signal(&writecond);
    }
    else
    {
	locks = 0;
        if (readers != 0)
	    pthread_cond_broadcast(&readcond);
        else
	    pthread_cond_signal(&writecond);
    }
    pthread_mutex_unlock(&mtx);
}


#  endif


#else	// !defined(__PTYPES_RWLOCK__)

//
// for other systems we declare a fully-inlined rwlock
// object in pasync.h
//

rwlock::rwlock()
{
    syscheck(pthread_rwlock_init(&rw, 0));
}


#endif



PTYPES_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -