8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 06:03:02 +01:00

Before I put the "explicit" modifier on AtomicCounter's constructor, the compiler was generating a temporary AtomicCounter on the fly and later assigning it to the target AtomicCounter instance to satisfy an assignment of an integer to an AtomicCounter. I'm not sure we want to allow (and worse, foster) the copying of AtomicCounter instances or temporaries created by the compiler, hence I implemented a new method and fixed the code, but I don't know how to write the best code for one group of platforms in fb_atomic.h, hence I wrote the method with a syntax problem to be caught by someone who knows better.

This commit is contained in:
robocop 2008-12-13 09:19:22 +00:00
parent 355d4e9942
commit f140cbb7d2
3 changed files with 69 additions and 29 deletions

View File

@ -41,31 +41,41 @@ class AtomicCounter
public:
typedef LONG counter_type;
AtomicCounter(counter_type val = 0) : counter(val) {}
explicit AtomicCounter(counter_type val = 0) : counter(val) {}
~AtomicCounter() {}
counter_type exchangeAdd(counter_type val) {
counter_type exchangeAdd(counter_type val)
{
return InterlockedExchangeAdd(&counter, val);
}
counter_type operator +=(counter_type val) {
counter_type operator +=(counter_type val)
{
return exchangeAdd(val) + val;
}
counter_type operator -=(counter_type val) {
counter_type operator -=(counter_type val)
{
return exchangeAdd(-val) - val;
}
counter_type operator ++() {
counter_type operator ++()
{
return InterlockedIncrement(&counter);
}
counter_type operator --() {
counter_type operator --()
{
return InterlockedDecrement(&counter);
}
counter_type value() const { return counter; }
counter_type setValue(counter_type val)
{
return InterlockedExchange(&counter, val);
}
private:
# if defined(MINGW)
counter_type counter;
@ -86,10 +96,11 @@ class AtomicCounter
public:
typedef int counter_type;
AtomicCounter(counter_type value = 0) : counter(value) {}
explicit AtomicCounter(counter_type value = 0) : counter(value) {}
~AtomicCounter() {}
counter_type exchangeAdd(counter_type value) {
counter_type exchangeAdd(counter_type value)
{
register counter_type result;
__asm __volatile (
"lock; xaddl %0, %1"
@ -98,24 +109,33 @@ public:
return result;
}
counter_type operator +=(counter_type value) {
counter_type operator +=(counter_type value)
{
return exchangeAdd(value) + value;
}
counter_type operator -=(counter_type value) {
counter_type operator -=(counter_type value)
{
return exchangeAdd(-value) - value;
}
counter_type operator ++() {
counter_type operator ++()
{
return exchangeAdd(1) + 1;
}
counter_type operator --() {
counter_type operator --()
{
return exchangeAdd(-1) - 1;
}
counter_type value() const { return counter; }
counter_type setValue(counter_type val)
{
return ...
}
private:
volatile counter_type counter;
};
@ -138,10 +158,11 @@ class AtomicCounter
public:
typedef int counter_type;
AtomicCounter(counter_type value = 0) : counter(value) {}
explicit AtomicCounter(counter_type value = 0) : counter(value) {}
~AtomicCounter() {}
counter_type exchangeAdd(counter_type value) {
counter_type exchangeAdd(counter_type value)
{
lock.enter();
counter_type temp = counter;
counter += value;
@ -149,28 +170,32 @@ public:
return temp;
}
counter_type operator +=(counter_type value) {
counter_type operator +=(counter_type value)
{
lock.enter();
counter_type temp = counter += value;
lock.leave();
return temp;
}
counter_type operator -=(counter_type value) {
counter_type operator -=(counter_type value)
{
lock.enter();
counter_type temp = counter -= value;
lock.leave();
return temp;
}
counter_type operator ++() {
counter_type operator ++()
{
lock.enter();
counter_type temp = counter++;
lock.leave();
return temp;
}
counter_type operator --() {
counter_type operator --()
{
lock.enter();
counter_type temp = counter--;
lock.leave();
@ -179,6 +204,15 @@ public:
counter_type value() const { return counter; }
counter_type setValue(counter_type val)
{
lock.enter();
const counter_type temp = counter;
counter = val;
lock.leave();
return temp;
}
private:
volatile counter_type counter;
Mutex lock;

View File

@ -59,11 +59,10 @@ private:
void init()
{
lock = 0;
lock.setValue(0);
blockedReaders = 0;
blockedWriters = 0;
readers_semaphore = CreateSemaphore(NULL, 0 /*initial count*/,
INT_MAX, NULL);
blockedWriters.setValue(0);
readers_semaphore = CreateSemaphore(NULL, 0 /*initial count*/, INT_MAX, NULL);
if (readers_semaphore == NULL)
system_call_failed::raise("CreateSemaphore");
writers_event = CreateEvent(NULL, FALSE/*auto-reset*/, FALSE, NULL);
@ -98,8 +97,7 @@ public:
}
else if (blockedReaders) {
MutexLockGuard guard(blockedReadersLock);
if (blockedReaders &&
!ReleaseSemaphore(readers_semaphore, blockedReaders, NULL))
if (blockedReaders && !ReleaseSemaphore(readers_semaphore, blockedReaders, NULL))
{
system_call_failed::raise("ReleaseSemaphore");
}
@ -348,7 +346,11 @@ namespace Firebird {
class ReadLockGuard
{
public:
ReadLockGuard(RWLock &alock) : lock(&alock) { lock->beginRead(); }
ReadLockGuard(RWLock &alock)
: lock(&alock)
{
lock->beginRead();
}
~ReadLockGuard() { release(); }
void release()
@ -370,7 +372,11 @@ private:
class WriteLockGuard
{
public:
WriteLockGuard(RWLock &alock) : lock(&alock) { lock->beginWrite(); }
WriteLockGuard(RWLock &alock)
: lock(&alock)
{
lock->beginWrite();
}
~WriteLockGuard() { release(); }
void release()

View File

@ -37,7 +37,7 @@
#include "../common/classes/init.h"
#ifdef DEV_BUILD
Firebird::AtomicCounter rem_port::portCounter = 0;
Firebird::AtomicCounter rem_port::portCounter(0);
#endif
#ifdef REMOTE_DEBUG
@ -734,7 +734,7 @@ void PortsCleanup::registerPort(rem_port* port)
Firebird::MemoryPool& pool = *getDefaultMemoryPool();
m_ports = FB_NEW (pool) PortsArray(pool);
}
m_ports->add(port);
}
@ -755,7 +755,7 @@ void PortsCleanup::unRegisterPort(rem_port* port)
void PortsCleanup::closePorts()
{
Firebird::MutexLockGuard guard(m_mutex);
if (m_ports)
{
rem_port* const* ptr = m_ports->begin();