[Libreoffice-commits] core.git: include/svl svl/source
Jan Holesovsky
kendy at collabora.com
Sat Dec 21 11:56:13 PST 2013
include/svl/broadcast.hxx | 1
svl/source/notify/broadcast.cxx | 93 ++++++++++++++++++++--------------------
2 files changed, 48 insertions(+), 46 deletions(-)
New commits:
commit df9883411a5423793ad411ac05d7a28c355209aa
Author: Jan Holesovsky <kendy at collabora.com>
Date: Sat Dec 21 20:51:29 2013 +0100
Make the broadcasting work even when about to destruct.
Change-Id: Idba9302e1ec5234d3d472cda047c09ba52afd328
diff --git a/include/svl/broadcast.hxx b/include/svl/broadcast.hxx
index 72ac303..a77ebdb 100644
--- a/include/svl/broadcast.hxx
+++ b/include/svl/broadcast.hxx
@@ -82,6 +82,7 @@ private:
bool mbAboutToDie:1;
bool mbDisposing:1;
bool mbNormalized:1;
+ bool mbDestNormalized:1;
};
diff --git a/svl/source/notify/broadcast.cxx b/svl/source/notify/broadcast.cxx
index 50d68a9..8d3905a 100644
--- a/svl/source/notify/broadcast.cxx
+++ b/svl/source/notify/broadcast.cxx
@@ -21,44 +21,23 @@
#include <svl/listener.hxx>
#include <svl/smplhint.hxx>
-namespace {
-
-class StartListeningHandler : std::unary_function<SvtListener*, void>
+void SvtBroadcaster::Normalize()
{
- SvtBroadcaster& mrBC;
-public:
- StartListeningHandler( SvtBroadcaster& rBC ) : mrBC(rBC) {}
-
- void operator() ( SvtListener* p )
+ if (!mbNormalized)
{
- p->StartListening(mrBC);
+ std::sort(maListeners.begin(), maListeners.end());
+ ListenersType::iterator itUniqueEnd = std::unique(maListeners.begin(), maListeners.end());
+ maListeners.erase(itUniqueEnd, maListeners.end());
+ mbNormalized = true;
}
-};
-
-class NotifyHandler : std::unary_function<SvtListener*, void>
-{
- SvtBroadcaster& mrBC;
- const SfxHint& mrHint;
-public:
- NotifyHandler( SvtBroadcaster& rBC, const SfxHint& rHint ) : mrBC(rBC), mrHint(rHint) {}
- void operator() ( SvtListener* p )
+ if (!mbDestNormalized)
{
- p->Notify(mrBC, mrHint);
+ std::sort(maDestructedListeners.begin(), maDestructedListeners.end());
+ ListenersType::iterator itUniqueEnd = std::unique(maDestructedListeners.begin(), maDestructedListeners.end());
+ maDestructedListeners.erase(itUniqueEnd, maDestructedListeners.end());
+ mbDestNormalized = true;
}
-};
-
-}
-
-void SvtBroadcaster::Normalize()
-{
- if (mbNormalized)
- return;
-
- std::sort(maListeners.begin(), maListeners.end());
- ListenersType::iterator itUniqueEnd = std::unique(maListeners.begin(), maListeners.end());
- maListeners.erase(itUniqueEnd, maListeners.end());
- mbNormalized = true;
}
void SvtBroadcaster::Add( SvtListener* p )
@@ -75,6 +54,7 @@ void SvtBroadcaster::Remove( SvtListener* p )
if (mbAboutToDie)
{
maDestructedListeners.push_back(p);
+ mbDestNormalized = false;
return;
}
@@ -88,12 +68,33 @@ void SvtBroadcaster::Remove( SvtListener* p )
ListenersGone();
}
-SvtBroadcaster::SvtBroadcaster() : mbAboutToDie(false), mbDisposing(false), mbNormalized(false) {}
+SvtBroadcaster::SvtBroadcaster() : mbAboutToDie(false), mbDisposing(false), mbNormalized(false), mbDestNormalized(false) {}
SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) :
- maListeners(rBC.maListeners), mbAboutToDie(false), mbDisposing(false), mbNormalized(rBC.mbNormalized)
+ maListeners(rBC.maListeners), maDestructedListeners(rBC.maDestructedListeners),
+ mbAboutToDie(rBC.mbAboutToDie), mbDisposing(false),
+ mbNormalized(rBC.mbNormalized), mbDestNormalized(rBC.mbDestNormalized)
{
- std::for_each(maListeners.begin(), maListeners.end(), StartListeningHandler(*this));
+ if (mbAboutToDie)
+ Normalize();
+
+ ListenersType::iterator dest(maDestructedListeners.begin());
+ for (ListenersType::iterator it(maListeners.begin()); it < maListeners.end(); ++it)
+ {
+ bool bStart = true;
+
+ if (mbAboutToDie)
+ {
+ // skip the destructed ones
+ while (dest != maDestructedListeners.end() && (*dest < *it))
+ ++dest;
+
+ bStart = (dest == maDestructedListeners.end() || *dest != *it);
+ }
+
+ if (bStart)
+ (*it)->StartListening(*this);
+ }
}
SvtBroadcaster::~SvtBroadcaster()
@@ -101,12 +102,6 @@ SvtBroadcaster::~SvtBroadcaster()
mbDisposing = true;
Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
- // normalize the list of listeners than already asked for destruction
- std::sort(maDestructedListeners.begin(), maDestructedListeners.end());
- ListenersType::iterator itUniqueEnd = std::unique(maDestructedListeners.begin(), maDestructedListeners.end());
- maDestructedListeners.erase(itUniqueEnd, maDestructedListeners.end());
-
- // and the list of registered listeners too
Normalize();
// now when both lists are sorted, we can linearly unregister all
@@ -126,12 +121,18 @@ SvtBroadcaster::~SvtBroadcaster()
void SvtBroadcaster::Broadcast( const SfxHint &rHint )
{
- if (mbAboutToDie)
- return;
-
Normalize();
- ListenersType listeners(maListeners);
- std::for_each(listeners.begin(), listeners.end(), NotifyHandler(*this, rHint));
+
+ ListenersType::iterator dest(maDestructedListeners.begin());
+ for (ListenersType::iterator it(maListeners.begin()); it < maListeners.end(); ++it)
+ {
+ // skip the destructed ones
+ while (dest != maDestructedListeners.end() && (*dest < *it))
+ ++dest;
+
+ if (dest == maDestructedListeners.end() || *dest != *it)
+ (*it)->Notify(*this, rHint);
+ }
}
void SvtBroadcaster::ListenersGone() {}
More information about the Libreoffice-commits
mailing list