|
@@ -2713,7 +2713,7 @@ public:
|
|
CCovenSDSManager &owner;
|
|
CCovenSDSManager &owner;
|
|
OwningSimpleHashTableOf<CNodeSubscriberContainer, SubscriptionId> subscribersById;
|
|
OwningSimpleHashTableOf<CNodeSubscriberContainer, SubscriptionId> subscribersById;
|
|
OwningSimpleHashTableOf<CNodeSubscriberContainerList, CServerRemoteTree *> subscriberListByNode;
|
|
OwningSimpleHashTableOf<CNodeSubscriberContainerList, CServerRemoteTree *> subscriberListByNode;
|
|
- CriticalSection lock;
|
|
|
|
|
|
+ mutable CriticalSection subscriberListCrit;
|
|
|
|
|
|
void _notify(CServerRemoteTree *node, PDState state, IArrayOf<CNodeSubscriberContainer> &subscribers)
|
|
void _notify(CServerRemoteTree *node, PDState state, IArrayOf<CNodeSubscriberContainer> &subscribers)
|
|
{
|
|
{
|
|
@@ -2784,13 +2784,13 @@ public:
|
|
void notify(CServerRemoteTree &node, PDState state)
|
|
void notify(CServerRemoteTree &node, PDState state)
|
|
{
|
|
{
|
|
// shouldn't be here, unless node is in subscribers table
|
|
// shouldn't be here, unless node is in subscribers table
|
|
- CriticalBlock b(lock);
|
|
|
|
|
|
+ CriticalBlock b(subscriberListCrit);
|
|
_notify(&node, state);
|
|
_notify(&node, state);
|
|
}
|
|
}
|
|
void notifyDelete(CServerRemoteTree *node)
|
|
void notifyDelete(CServerRemoteTree *node)
|
|
{
|
|
{
|
|
// shouldn't be here, unless node is in subscribers table
|
|
// shouldn't be here, unless node is in subscribers table
|
|
- CriticalBlock b(lock);
|
|
|
|
|
|
+ CriticalBlock b(subscriberListCrit);
|
|
/* Need to be careful not to release subscribers here (on this thread)
|
|
/* Need to be careful not to release subscribers here (on this thread)
|
|
* 1) gather subscribers(linked)
|
|
* 1) gather subscribers(linked)
|
|
* 2) remove nodes and lists, so no longer in use by SDS
|
|
* 2) remove nodes and lists, so no longer in use by SDS
|
|
@@ -2809,7 +2809,9 @@ public:
|
|
// ISubscriptionManager impl.
|
|
// ISubscriptionManager impl.
|
|
virtual void add(ISubscription *sub, SubscriptionId id)
|
|
virtual void add(ISubscription *sub, SubscriptionId id)
|
|
{
|
|
{
|
|
- CriticalBlock b(lock);
|
|
|
|
|
|
+ CHECKEDDALIREADLOCKBLOCK(owner.dataRWLock, readWriteTimeout);
|
|
|
|
+ CHECKEDCRITICALBLOCK(owner.treeRegCrit, fakeCritTimeout);
|
|
|
|
+ CriticalBlock b(subscriberListCrit);
|
|
/* calls back out to owner to scan for match, so that SDSManager can protect root/treereg.
|
|
/* calls back out to owner to scan for match, so that SDSManager can protect root/treereg.
|
|
* It calls back (associateSubscriber) in this class to add subscribers based on matches.
|
|
* It calls back (associateSubscriber) in this class to add subscribers based on matches.
|
|
*/
|
|
*/
|
|
@@ -2822,7 +2824,7 @@ public:
|
|
*/
|
|
*/
|
|
CHECKEDDALIREADLOCKBLOCK(owner.dataRWLock, readWriteTimeout);
|
|
CHECKEDDALIREADLOCKBLOCK(owner.dataRWLock, readWriteTimeout);
|
|
CHECKEDCRITICALBLOCK(owner.treeRegCrit, fakeCritTimeout);
|
|
CHECKEDCRITICALBLOCK(owner.treeRegCrit, fakeCritTimeout);
|
|
- CriticalBlock b(lock);
|
|
|
|
|
|
+ CriticalBlock b(subscriberListCrit);
|
|
/* calls back out to owner to protect root/treereg.
|
|
/* calls back out to owner to protect root/treereg.
|
|
* It calls back into removeSubscriberAssociation.
|
|
* It calls back into removeSubscriberAssociation.
|
|
*/
|
|
*/
|
|
@@ -2862,6 +2864,12 @@ public:
|
|
}
|
|
}
|
|
MemoryBuffer &collectSubscribers(MemoryBuffer &out) const
|
|
MemoryBuffer &collectSubscribers(MemoryBuffer &out) const
|
|
{
|
|
{
|
|
|
|
+ /* important to ensure have exclusive data lock on removal, ahead of subscriber lock
|
|
|
|
+ * as can get notifications whilst holding data lock, e.g. notifyDelete on node destruction.
|
|
|
|
+ */
|
|
|
|
+ CHECKEDDALIREADLOCKBLOCK(owner.dataRWLock, readWriteTimeout);
|
|
|
|
+ CHECKEDCRITICALBLOCK(owner.treeRegCrit, fakeCritTimeout);
|
|
|
|
+ CriticalBlock b(subscriberListCrit);
|
|
out.append(subscribersById.count());
|
|
out.append(subscribersById.count());
|
|
SuperHashIteratorOf<CNodeSubscriberContainer> sdsNodeIter(subscribersById);
|
|
SuperHashIteratorOf<CNodeSubscriberContainer> sdsNodeIter(subscribersById);
|
|
ForEach(sdsNodeIter)
|
|
ForEach(sdsNodeIter)
|
|
@@ -8636,8 +8644,6 @@ void CCovenSDSManager::addNodeSubscriber(ISubscription *sub, SubscriptionId id)
|
|
mb.read(xpath);
|
|
mb.read(xpath);
|
|
mb.read(sendValue);
|
|
mb.read(sendValue);
|
|
|
|
|
|
- CHECKEDDALIREADLOCKBLOCK(dataRWLock, readWriteTimeout);
|
|
|
|
- CHECKEDCRITICALBLOCK(treeRegCrit, fakeCritTimeout);
|
|
|
|
Owned<IPropertyTreeIterator> iter = root->getElements(xpath+1);
|
|
Owned<IPropertyTreeIterator> iter = root->getElements(xpath+1);
|
|
if (!iter->first())
|
|
if (!iter->first())
|
|
throw MakeSDSException(SDSExcpt_SubscriptionNoMatch, "Failed to match any nodes: %s", xpath.get());
|
|
throw MakeSDSException(SDSExcpt_SubscriptionNoMatch, "Failed to match any nodes: %s", xpath.get());
|