Changeset View
Changeset View
Standalone View
Standalone View
src/server/notificationsubscriber.cpp
Show All 14 Lines | 1 | /* | |||
---|---|---|---|---|---|
15 | along with this library; see the file COPYING.LIB. If not, write to the | 15 | along with this library; see the file COPYING.LIB. If not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | 02110-1301, USA. | 17 | 02110-1301, USA. | ||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include "notificationsubscriber.h" | 20 | #include "notificationsubscriber.h" | ||
21 | #include "akonadiserver_debug.h" | 21 | #include "akonadiserver_debug.h" | ||
22 | #include "notificationmanager.h" | 22 | #include "notificationmanager.h" | ||
23 | #include "collectionreferencemanager.h" | | |||
24 | #include "aggregatedfetchscope.h" | 23 | #include "aggregatedfetchscope.h" | ||
25 | #include "utils.h" | 24 | #include "utils.h" | ||
26 | 25 | | |||
27 | #include <QLocalSocket> | 26 | #include <QLocalSocket> | ||
28 | #include <QPointer> | 27 | #include <QPointer> | ||
29 | 28 | | |||
30 | #include <shared/akranges.h> | 29 | #include <shared/akranges.h> | ||
31 | #include <private/protocol_p.h> | 30 | #include <private/protocol_p.h> | ||
▲ Show 20 Lines • Show All 361 Lines • ▼ Show 20 Line(s) | |||||
393 | bool NotificationSubscriber::acceptsItemNotification(const Protocol::ItemChangeNotification &msg) const | 392 | bool NotificationSubscriber::acceptsItemNotification(const Protocol::ItemChangeNotification &msg) const | ||
394 | { | 393 | { | ||
395 | // Assumes mLock being locked by caller | 394 | // Assumes mLock being locked by caller | ||
396 | 395 | | |||
397 | if (msg.items().isEmpty()) { | 396 | if (msg.items().isEmpty()) { | ||
398 | return false; | 397 | return false; | ||
399 | } | 398 | } | ||
400 | 399 | | |||
401 | if (CollectionReferenceManager::instance()->isReferenced(msg.parentCollection())) { | | |||
402 | //We always want notifications that affect the parent resource (like an item added to a referenced collection) | | |||
403 | const bool notificationForParentResource = (mSession == msg.resource()); | | |||
404 | const bool accepts = mExclusive | | |||
405 | || isCollectionMonitored(msg.parentCollection()) | | |||
406 | || isMoveDestinationResourceMonitored(msg) | | |||
407 | || notificationForParentResource; | | |||
408 | TRACE_NTF("ACCEPTS ITEM: parent col referenced" | | |||
409 | << "exclusive:" << mExclusive << "," | | |||
410 | << "parent monitored:" << isCollectionMonitored(msg.parentCollection()) << "," | | |||
411 | << "destination monitored:" << isMoveDestinationResourceMonitored(msg) << "," | | |||
412 | << "ntf for parent resource:" << notificationForParentResource << ":" | | |||
413 | << "ACCEPTED:" << accepts); | | |||
414 | return accepts; | | |||
415 | } | | |||
416 | | ||||
417 | if (mAllMonitored) { | 400 | if (mAllMonitored) { | ||
418 | TRACE_NTF("ACCEPTS ITEM: all monitored"); | 401 | TRACE_NTF("ACCEPTS ITEM: all monitored"); | ||
419 | return true; | 402 | return true; | ||
420 | } | 403 | } | ||
421 | 404 | | |||
422 | if (!mMonitoredTypes.isEmpty() && !mMonitoredTypes.contains(Protocol::ModifySubscriptionCommand::ItemChanges)) { | 405 | if (!mMonitoredTypes.isEmpty() && !mMonitoredTypes.contains(Protocol::ModifySubscriptionCommand::ItemChanges)) { | ||
423 | TRACE_NTF("ACCEPTS ITEM: REJECTED - Item changes not monitored"); | 406 | TRACE_NTF("ACCEPTS ITEM: REJECTED - Item changes not monitored"); | ||
424 | return false; | 407 | return false; | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | 455 | { | |||
484 | if (msg.metadata().contains("DISABLED") | 467 | if (msg.metadata().contains("DISABLED") | ||
485 | && (msg.operation() != Protocol::CollectionChangeNotification::Unsubscribe) | 468 | && (msg.operation() != Protocol::CollectionChangeNotification::Unsubscribe) | ||
486 | && !msg.changedParts().contains("ENABLED")) { | 469 | && !msg.changedParts().contains("ENABLED")) { | ||
487 | // Exclusive subscriber always gets it | 470 | // Exclusive subscriber always gets it | ||
488 | if (mExclusive) { | 471 | if (mExclusive) { | ||
489 | return true; | 472 | return true; | ||
490 | } | 473 | } | ||
491 | 474 | | |||
492 | //Deliver the notification if referenced from this session | 475 | // If the subscriber is not exclusive (i.e. if we got here), then the subscriber does | ||
493 | if (CollectionReferenceManager::instance()->isReferenced(collection.id(), mSession)) { | 476 | // not care about this one, so drop it | ||
494 | return true; | | |||
495 | } | | |||
496 | | ||||
497 | //Exclusive subscribers still want the notification | | |||
498 | if (mExclusive && CollectionReferenceManager::instance()->isReferenced(collection.id())) { | | |||
499 | return true; | | |||
500 | } | | |||
501 | | ||||
502 | //The session belonging to this monitor referenced or dereferenced the collection. We always want this notification. | | |||
503 | //The referencemanager no longer holds a reference, so we have to check this way. | | |||
504 | if (msg.changedParts().contains(AKONADI_PARAM_REFERENCED) && mSession == msg.sessionId()) { | | |||
505 | return true; | | |||
506 | } | | |||
507 | | ||||
508 | // If the collection is not referenced, monitored or the subscriber is not | | |||
dfaure: The old comment had the word "monitored" here, which got removed - on purpose, or by accident? | |||||
This logic does not concern itself with "monitored" state, that is handled outside of this if, below. dvratil: This logic does not concern itself with "monitored" state, that is handled outside of this if… | |||||
509 | // exclusive (i.e. if we got here), then the subscriber does not care about | | |||
510 | // this one, so drop it | | |||
511 | return false; | 477 | return false; | ||
512 | } | 478 | } | ||
513 | 479 | | |||
514 | if (mAllMonitored) { | 480 | if (mAllMonitored) { | ||
515 | return true; | 481 | return true; | ||
516 | } | 482 | } | ||
517 | 483 | | |||
518 | if (!mMonitoredTypes.isEmpty() && !mMonitoredTypes.contains(Protocol::ModifySubscriptionCommand::CollectionChanges)) { | 484 | if (!mMonitoredTypes.isEmpty() && !mMonitoredTypes.contains(Protocol::ModifySubscriptionCommand::CollectionChanges)) { | ||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Line(s) | 638 | case Protocol::Command::DebugChangeNotification: | |||
673 | return acceptsDebugChangeNotification(static_cast<const Protocol::DebugChangeNotification &>(msg)); | 639 | return acceptsDebugChangeNotification(static_cast<const Protocol::DebugChangeNotification &>(msg)); | ||
674 | 640 | | |||
675 | default: | 641 | default: | ||
676 | qCWarning(AKONADISERVER_LOG) << "NotificationSubscriber" << mSubscriber << "received an invalid notification type" << msg.type(); | 642 | qCWarning(AKONADISERVER_LOG) << "NotificationSubscriber" << mSubscriber << "received an invalid notification type" << msg.type(); | ||
677 | return false; | 643 | return false; | ||
678 | } | 644 | } | ||
679 | } | 645 | } | ||
680 | 646 | | |||
681 | Protocol::CollectionChangeNotificationPtr NotificationSubscriber::customizeCollection(const Protocol::CollectionChangeNotificationPtr &ntf) | | |||
682 | { | | |||
683 | const bool isReferencedFromSession = CollectionReferenceManager::instance()->isReferenced(ntf->collection().id(), mSession); | | |||
684 | if (isReferencedFromSession != ntf->collection().referenced()) { | | |||
685 | auto copy = Protocol::CollectionChangeNotificationPtr::create(*ntf); | | |||
686 | auto copyCol = ntf->collection(); | | |||
687 | copyCol.setReferenced(isReferencedFromSession); | | |||
688 | copy->setCollection(std::move(copyCol)); | | |||
689 | return copy; | | |||
690 | } | | |||
691 | | ||||
692 | return ntf; | | |||
693 | } | | |||
694 | | ||||
695 | bool NotificationSubscriber::notify(const Protocol::ChangeNotificationPtr ¬ification) | 647 | bool NotificationSubscriber::notify(const Protocol::ChangeNotificationPtr ¬ification) | ||
696 | { | 648 | { | ||
697 | // Guard against this object being deleted while we are waiting for the lock | 649 | // Guard against this object being deleted while we are waiting for the lock | ||
698 | QPointer<NotificationSubscriber> ptr(this); | 650 | QPointer<NotificationSubscriber> ptr(this); | ||
699 | QMutexLocker locker(&mLock); | 651 | QMutexLocker locker(&mLock); | ||
700 | if (!ptr) { | 652 | if (!ptr) { | ||
701 | return false; | 653 | return false; | ||
702 | } | 654 | } | ||
703 | 655 | | |||
704 | if (acceptsNotification(*notification)) { | 656 | if (acceptsNotification(*notification)) { | ||
705 | auto ntf = notification; | | |||
706 | if (ntf->type() == Protocol::Command::CollectionChangeNotification) { | | |||
707 | ntf = customizeCollection(notification.staticCast<Protocol::CollectionChangeNotification>()); | | |||
708 | } | | |||
709 | QMetaObject::invokeMethod(this, "writeNotification", Qt::QueuedConnection, | 657 | QMetaObject::invokeMethod(this, "writeNotification", Qt::QueuedConnection, | ||
710 | Q_ARG(Akonadi::Protocol::ChangeNotificationPtr, ntf)); | 658 | Q_ARG(Akonadi::Protocol::ChangeNotificationPtr, notification)); | ||
711 | return true; | 659 | return true; | ||
712 | } | 660 | } | ||
713 | return false; | 661 | return false; | ||
714 | } | 662 | } | ||
715 | 663 | | |||
716 | void NotificationSubscriber::writeNotification(const Protocol::ChangeNotificationPtr ¬ification) | 664 | void NotificationSubscriber::writeNotification(const Protocol::ChangeNotificationPtr ¬ification) | ||
717 | { | 665 | { | ||
718 | // tag chosen by fair dice roll | 666 | // tag chosen by fair dice roll | ||
Show All 22 Lines |
The old comment had the word "monitored" here, which got removed - on purpose, or by accident?