You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by mc...@apache.org on 2004/04/02 10:48:06 UTC
cvs commit: logging-log4cxx/src objectimpl.cpp
mcatan 2004/04/02 00:48:06
Modified: src objectimpl.cpp
Log:
optimized reference counting and inter-thread synchronization
Revision Changes Path
1.12 +122 -52 logging-log4cxx/src/objectimpl.cpp
Index: objectimpl.cpp
===================================================================
RCS file: /home/cvs/logging-log4cxx/src/objectimpl.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- objectimpl.cpp 28 Feb 2004 15:07:50 -0000 1.11
+++ objectimpl.cpp 2 Apr 2004 08:48:06 -0000 1.12
@@ -21,19 +21,64 @@
#endif
#include <log4cxx/helpers/objectimpl.h>
+#include <log4cxx/helpers/criticalsection.h>
+#include <log4cxx/helpers/event.h>
+#include <log4cxx/helpers/thread.h>
using namespace log4cxx::helpers;
-#ifdef HAVE_LINUX_ATOMIC_OPERATIONS
-ObjectImpl::ObjectImpl()
+class EventList
{
- ref.counter = 0;
-}
-#else
-ObjectImpl::ObjectImpl() : ref(0)
+protected:
+ EventList(Event * event)
+ : event(event), next(0)
+ {
+ }
+
+public:
+ static void removeAll(EventList * list)
+ {
+ EventList * item = list;
+ while (item != 0)
+ {
+ item = removeHead(item);
+ }
+ }
+
+ static EventList * removeHead(EventList * list)
+ {
+ EventList * next = list->next;
+ delete list;
+ return next;
+ }
+
+ static EventList * append(EventList * list, Event * event)
+ {
+ if (list == 0)
+ {
+ return new EventList(event);
+ }
+ else
+ {
+ EventList * current = list;
+ EventList * next = list->next;
+ while (next != 0)
+ {
+ current = next;
+ next = next->next;
+ }
+ current->next = new EventList(event);
+ return list;
+ }
+ }
+
+ Event * event;
+ EventList * next;
+};
+
+ObjectImpl::ObjectImpl() : ref(0), eventList(0)
{
}
-#endif
ObjectImpl::~ObjectImpl()
{
@@ -41,73 +86,98 @@
void ObjectImpl::addRef() const
{
-#ifdef HAVE_LINUX_ATOMIC_OPERATIONS
- atomic_inc(&ref);
-#elif defined(HAVE_PTHREAD)
- refCs.lock();
- ref++;
- refCs.unlock();
-#elif defined(HAVE_MS_THREAD)
-#if _MSC_VER == 1200 // MSDEV 6
- ::InterlockedIncrement((long *)&ref);
-#else
- ::InterlockedIncrement(&ref);
-#endif
-#else
- ref++;
-#endif
+ Thread::InterlockedIncrement(&ref);
}
void ObjectImpl::releaseRef() const
{
-#ifdef HAVE_LINUX_ATOMIC_OPERATIONS
- if (atomic_dec_and_test(&ref))
- {
- delete this;
- }
-#elif defined(HAVE_PTHREAD)
- refCs.lock();
- ref--;
- if (ref <= 0)
- {
- delete this;
- }
- refCs.unlock();
-#elif defined(HAVE_MS_THREAD)
-#if _MSC_VER == 1200 // MSDEV 6
- if (::InterlockedDecrement((long *)&ref) == 0)
-#else
- if (::InterlockedDecrement(&ref) == 0)
-#endif
- {
- delete this;
- }
-#else
- ref--;
- if (ref <= 0)
+ if (Thread::InterlockedDecrement(&ref) == 0)
{
delete this;
}
-#endif
}
void ObjectImpl::lock() const
{
- mutex.lock();
+ cs.lock();
}
void ObjectImpl::unlock() const
{
- mutex.unlock();
+ cs.unlock();
}
void ObjectImpl::wait() const
{
- cond.wait(mutex);
+ if (cs.getOwningThread() != Thread::getCurrentThreadId())
+ {
+ if (cs.getOwningThread() == 0)
+ {
+ throw IllegalMonitorStateException(_T("Object not locked"));
+ }
+ else
+ {
+ throw IllegalMonitorStateException(_T("Object not locked by this thread"));
+ }
+ }
+
+ Event event(false, false);
+ eventList = EventList::append((EventList *)eventList, &event);
+ cs.unlock();
+
+ try
+ {
+ event.wait();
+ }
+ catch(Exception&)
+ {
+ cs.lock();
+ eventList = EventList::removeHead((EventList *)eventList);
+ return;
+ }
+
+ cs.lock();
}
void ObjectImpl::notify() const
{
- cond.signal();
+ if (cs.getOwningThread() != Thread::getCurrentThreadId())
+ {
+ if (cs.getOwningThread() == 0)
+ {
+ throw IllegalMonitorStateException(_T("Object not locked"));
+ }
+ else
+ {
+ throw IllegalMonitorStateException(_T("Object not locked by this thread"));
+ }
+ }
+
+ if (eventList != 0)
+ {
+ ((EventList *)eventList)->event->set();
+ eventList = EventList::removeHead((EventList *)eventList);
+ }
+}
+
+void ObjectImpl::notifyAll() const
+{
+ if (cs.getOwningThread() != Thread::getCurrentThreadId())
+ {
+ if (cs.getOwningThread() == 0)
+ {
+ throw IllegalMonitorStateException(_T("Object not locked"));
+ }
+ else
+ {
+ throw IllegalMonitorStateException(_T("Object not locked by this thread"));
+ }
+ }
+
+ while (eventList != 0)
+ {
+ ((EventList *)eventList)->event->set();
+ eventList = EventList::removeHead((EventList *)eventList);
+ }
}