mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 01:16:55 +02:00
added NullMutex, extended Events so that mutex is a template param, minor performance optimzation for strategies
This commit is contained in:
parent
ce17ae2c66
commit
358797c89e
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="8,00"
|
||||
Name="Foundation"
|
||||
ProjectGUID="{8164D41D-B053-405B-826C-CF37AC0EF176}"
|
||||
RootNamespace="Foundation"
|
||||
|
@ -51,7 +51,7 @@
|
||||
namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs, class TStrategy, class TDelegate>
|
||||
template <class TArgs, class TStrategy, class TDelegate, class TMutex = FastMutex>
|
||||
class AbstractEvent
|
||||
/// An AbstractEvent is the super-class of all events.
|
||||
/// It works similar to the way C# handles notifications (aka events in C#).
|
||||
@ -183,7 +183,7 @@ public:
|
||||
/// (DefaultStrategy, FIFOStrategy) follow that guideline but future ones
|
||||
/// can deviate.
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
_strategy.add(aDelegate);
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ public:
|
||||
/// already existing one is determined by the < operator.
|
||||
/// If the observer is not found, the unregister will be ignored
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
_strategy.remove(aDelegate);
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ public:
|
||||
bool enabled = false;
|
||||
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
enabled = _enabled;
|
||||
if (_enabled)
|
||||
{
|
||||
@ -243,7 +243,7 @@ public:
|
||||
NotifyAsyncParams params(pSender, args);
|
||||
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
|
||||
// thread-safeness:
|
||||
// copy should be faster and safer than blocking until
|
||||
@ -262,7 +262,7 @@ public:
|
||||
void enable()
|
||||
/// Enables the event
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
@ -270,22 +270,29 @@ public:
|
||||
/// Disables the event. notify and notifyAsnyc will be ignored,
|
||||
/// but adding/removing delegates is still allowed.
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void clear()
|
||||
/// Removes all delegates.
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
_strategy.clear();
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
/// Checks if any delegates are registered at the delegate
|
||||
{
|
||||
typename TMutex::ScopedLock lock(_mutex);
|
||||
return _strategy.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
struct NotifyAsyncParams
|
||||
@ -319,7 +326,7 @@ protected:
|
||||
TStrategy _strategy; /// The strategy used to notify observers.
|
||||
bool _enabled; /// Stores if an event is enabled. Notfies on disabled events have no effect
|
||||
/// but it is possible to change the observers.
|
||||
mutable FastMutex _mutex;
|
||||
mutable TMutex _mutex;
|
||||
|
||||
private:
|
||||
AbstractEvent(const AbstractEvent& other);
|
||||
|
@ -49,10 +49,11 @@
|
||||
namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs>
|
||||
template <class TArgs, class TMutex = FastMutex>
|
||||
class BasicEvent: public AbstractEvent <
|
||||
TArgs, DefaultStrategy<TArgs, AbstractDelegate<TArgs>, p_less<AbstractDelegate<TArgs> > >,
|
||||
AbstractDelegate<TArgs>
|
||||
AbstractDelegate<TArgs>,
|
||||
TMutex
|
||||
>
|
||||
/// A BasicEvent uses internally a DefaultStrategy which
|
||||
/// invokes delegates in an arbitrary manner.
|
||||
|
@ -50,7 +50,7 @@ namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs, class TDelegate, class TCompare>
|
||||
class DefaultStrategy: public NotificationStrategy<TArgs, TDelegate>
|
||||
class DefaultStrategy//: public NotificationStrategy<TArgs, TDelegate>
|
||||
/// Default notification strategy. Allows one observer
|
||||
/// to register exactly once. The observer must provide an
|
||||
/// < (less-than) operator.
|
||||
|
@ -49,11 +49,12 @@
|
||||
namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs>
|
||||
template <class TArgs, class TMutex = FastMutex>
|
||||
class FIFOEvent: public AbstractEvent <
|
||||
TArgs,
|
||||
FIFOStrategy<TArgs, AbstractDelegate<TArgs>, p_less<AbstractDelegate< TArgs> > >,
|
||||
AbstractDelegate<TArgs>
|
||||
AbstractDelegate<TArgs>,
|
||||
TMutex
|
||||
>
|
||||
/// A FIFOEvent uses internally a FIFOStrategy which guarantees
|
||||
/// that delegates are invoked in the order they were added to
|
||||
|
@ -49,7 +49,7 @@ namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs, class TDelegate, class TCompare>
|
||||
class FIFOStrategy: public NotificationStrategy<TArgs, TDelegate>
|
||||
class FIFOStrategy//: public NotificationStrategy<TArgs, TDelegate>
|
||||
{
|
||||
public:
|
||||
typedef std::list<TDelegate*> Delegates;
|
||||
|
@ -166,6 +166,55 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class Foundation_API NullMutex
|
||||
/// A NullMutex is an empty mutex implementation
|
||||
/// which performs no locking at all. Useful in policy driven design
|
||||
/// where the type of mutex used can be now a template parameter allowing the user to switch
|
||||
/// between thread-safe and not thread-safe depending on his need
|
||||
/// Works with the ScopedLock class
|
||||
{
|
||||
public:
|
||||
typedef Poco::ScopedLock<NullMutex> ScopedLock;
|
||||
|
||||
NullMutex()
|
||||
/// creates the NullMutex.
|
||||
{
|
||||
}
|
||||
|
||||
~NullMutex()
|
||||
/// destroys the NullMutex.
|
||||
{
|
||||
}
|
||||
|
||||
void lock()
|
||||
/// Always succeeds
|
||||
{
|
||||
}
|
||||
|
||||
void lock(long milliseconds)
|
||||
/// Always succeeds
|
||||
{
|
||||
}
|
||||
|
||||
bool tryLock()
|
||||
/// Always returns true
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tryLock(long)
|
||||
/// Always returns true
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void unlock()
|
||||
/// Always succeeds
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
@ -49,6 +49,9 @@ namespace Poco {
|
||||
template <class TArgs, class TDelegate>
|
||||
class NotificationStrategy
|
||||
/// The interface that all notification strategies must implement.
|
||||
/// Note: Event is based on policy-driven design, so your strategy implementation
|
||||
/// must offer all the methods from this interface (otherwise: compile errors)
|
||||
/// but you don't need to extend from NotificationStrategy!
|
||||
{
|
||||
public:
|
||||
NotificationStrategy()
|
||||
|
@ -49,11 +49,12 @@
|
||||
namespace Poco {
|
||||
|
||||
|
||||
template <class TArgs>
|
||||
template <class TArgs, class TMutex = FastMutex>
|
||||
class PriorityEvent: public AbstractEvent <
|
||||
TArgs,
|
||||
DefaultStrategy<TArgs, AbstractPriorityDelegate< TArgs>, p_less<AbstractPriorityDelegate<TArgs> > >,
|
||||
AbstractPriorityDelegate<TArgs>
|
||||
AbstractPriorityDelegate<TArgs>,
|
||||
TMutex
|
||||
>
|
||||
/// A PriorityEvent uses internally a DefaultStrategy which
|
||||
/// invokes delegates in a manner determined by the priority field
|
||||
|
@ -62,11 +62,14 @@ void BasicEventTest::testNoDelegate()
|
||||
EventArgs args;
|
||||
|
||||
assert (_count == 0);
|
||||
assert (Simple.empty());
|
||||
Simple.notify(this, tmp);
|
||||
assert (_count == 0);
|
||||
|
||||
Simple += delegate(this, &BasicEventTest::onSimple);
|
||||
assert (!Simple.empty());
|
||||
Simple -= delegate(this, &BasicEventTest::onSimple);
|
||||
assert (Simple.empty());
|
||||
Simple.notify(this, tmp);
|
||||
assert (_count == 0);
|
||||
|
||||
@ -166,6 +169,24 @@ void BasicEventTest::testDuplicateRegister()
|
||||
assert (_count == 1);
|
||||
}
|
||||
|
||||
|
||||
void BasicEventTest::testNullMutex()
|
||||
{
|
||||
Poco::BasicEvent<int, NullMutex> ev;
|
||||
int tmp = 0;
|
||||
|
||||
assert (_count == 0);
|
||||
|
||||
ev += delegate(this, &BasicEventTest::onSimple);
|
||||
ev += delegate(this, &BasicEventTest::onSimple);
|
||||
ev.notify(this, tmp);
|
||||
assert (_count == 1);
|
||||
ev -= delegate(this, &BasicEventTest::onSimple);
|
||||
ev.notify(this, tmp);
|
||||
assert (_count == 1);
|
||||
}
|
||||
|
||||
|
||||
void BasicEventTest::testDuplicateUnregister()
|
||||
{
|
||||
// duplicate unregister shouldn't give an error,
|
||||
@ -406,5 +427,6 @@ CppUnit::Test* BasicEventTest::suite()
|
||||
CppUnit_addTest(pSuite, BasicEventTest, testExpireReRegister);
|
||||
CppUnit_addTest(pSuite, BasicEventTest, testOverwriteDelegate);
|
||||
CppUnit_addTest(pSuite, BasicEventTest, testAsyncNotify);
|
||||
CppUnit_addTest(pSuite, BasicEventTest, testNullMutex);
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
void testReturnParams();
|
||||
void testOverwriteDelegate();
|
||||
void testAsyncNotify();
|
||||
void testNullMutex();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user