| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ipc/attachment_broker.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/location.h" | |
| 11 #include "base/sequenced_task_runner.h" | |
| 12 | |
| 13 namespace { | |
| 14 IPC::AttachmentBroker* g_attachment_broker = nullptr; | |
| 15 } | |
| 16 | |
| 17 namespace IPC { | |
| 18 | |
| 19 // static | |
| 20 void AttachmentBroker::SetGlobal(AttachmentBroker* broker) { | |
| 21 g_attachment_broker = broker; | |
| 22 } | |
| 23 | |
| 24 // static | |
| 25 AttachmentBroker* AttachmentBroker::GetGlobal() { | |
| 26 return g_attachment_broker; | |
| 27 } | |
| 28 | |
| 29 AttachmentBroker::AttachmentBroker() : last_unique_id_(0) {} | |
| 30 AttachmentBroker::~AttachmentBroker() {} | |
| 31 | |
| 32 bool AttachmentBroker::GetAttachmentWithId( | |
| 33 BrokerableAttachment::AttachmentId id, | |
| 34 scoped_refptr<BrokerableAttachment>* out_attachment) { | |
| 35 base::AutoLock auto_lock(*get_lock()); | |
| 36 for (AttachmentVector::iterator it = attachments_.begin(); | |
| 37 it != attachments_.end(); ++it) { | |
| 38 if ((*it)->GetIdentifier() == id) { | |
| 39 *out_attachment = *it; | |
| 40 attachments_.erase(it); | |
| 41 return true; | |
| 42 } | |
| 43 } | |
| 44 return false; | |
| 45 } | |
| 46 | |
| 47 void AttachmentBroker::AddObserver( | |
| 48 AttachmentBroker::Observer* observer, | |
| 49 const scoped_refptr<base::SequencedTaskRunner>& runner) { | |
| 50 base::AutoLock auto_lock(*get_lock()); | |
| 51 auto it = std::find_if(observers_.begin(), observers_.end(), | |
| 52 [observer](const ObserverInfo& info) { | |
| 53 return info.observer == observer; | |
| 54 }); | |
| 55 if (it == observers_.end()) { | |
| 56 ObserverInfo info; | |
| 57 info.observer = observer; | |
| 58 info.runner = runner; | |
| 59 info.unique_id = ++last_unique_id_; | |
| 60 observers_.push_back(info); | |
| 61 | |
| 62 // Give the observer a chance to handle attachments that arrived while the | |
| 63 // observer was handling the message that caused it to register, but our | |
| 64 // mutex was not yet locked. | |
| 65 for (const auto& attachment : attachments_) { | |
| 66 info.runner->PostTask( | |
| 67 FROM_HERE, | |
| 68 base::Bind(&AttachmentBroker::NotifyObserver, base::Unretained(this), | |
| 69 info.unique_id, attachment->GetIdentifier())); | |
| 70 } | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 void AttachmentBroker::RemoveObserver(AttachmentBroker::Observer* observer) { | |
| 75 base::AutoLock auto_lock(*get_lock()); | |
| 76 auto it = std::find_if(observers_.begin(), observers_.end(), | |
| 77 [observer](const ObserverInfo& info) { | |
| 78 return info.observer == observer; | |
| 79 }); | |
| 80 if (it != observers_.end()) | |
| 81 observers_.erase(it); | |
| 82 } | |
| 83 | |
| 84 void AttachmentBroker::RegisterCommunicationChannel( | |
| 85 Endpoint* endpoint, | |
| 86 scoped_refptr<base::SingleThreadTaskRunner> runner) { | |
| 87 NOTREACHED(); | |
| 88 } | |
| 89 | |
| 90 void AttachmentBroker::DeregisterCommunicationChannel(Endpoint* endpoint) { | |
| 91 NOTREACHED(); | |
| 92 } | |
| 93 | |
| 94 void AttachmentBroker::RegisterBrokerCommunicationChannel(Endpoint* endpoint) { | |
| 95 NOTREACHED(); | |
| 96 } | |
| 97 | |
| 98 void AttachmentBroker::DeregisterBrokerCommunicationChannel( | |
| 99 Endpoint* endpoint) { | |
| 100 NOTREACHED(); | |
| 101 } | |
| 102 | |
| 103 void AttachmentBroker::ReceivedPeerPid(base::ProcessId peer_pid) { | |
| 104 NOTREACHED(); | |
| 105 } | |
| 106 | |
| 107 bool AttachmentBroker::IsPrivilegedBroker() { | |
| 108 NOTREACHED(); | |
| 109 return false; | |
| 110 } | |
| 111 | |
| 112 void AttachmentBroker::HandleReceivedAttachment( | |
| 113 const scoped_refptr<BrokerableAttachment>& attachment) { | |
| 114 { | |
| 115 base::AutoLock auto_lock(*get_lock()); | |
| 116 attachments_.push_back(attachment); | |
| 117 } | |
| 118 NotifyObservers(attachment->GetIdentifier()); | |
| 119 } | |
| 120 | |
| 121 void AttachmentBroker::NotifyObservers( | |
| 122 const BrokerableAttachment::AttachmentId& id) { | |
| 123 base::AutoLock auto_lock(*get_lock()); | |
| 124 | |
| 125 // Dispatch notifications onto the appropriate task runners. This has two | |
| 126 // effects: | |
| 127 // 1. Ensures that the notification is posted from the right task runner. | |
| 128 // 2. Avoids any complications from re-entrant functions, since one of the | |
| 129 // observers may be halfway through processing some messages. | |
| 130 for (const auto& info : observers_) { | |
| 131 info.runner->PostTask( | |
| 132 FROM_HERE, base::Bind(&AttachmentBroker::NotifyObserver, | |
| 133 base::Unretained(this), info.unique_id, id)); | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 void AttachmentBroker::NotifyObserver( | |
| 138 int unique_id, | |
| 139 const BrokerableAttachment::AttachmentId& id) { | |
| 140 Observer* observer = nullptr; | |
| 141 { | |
| 142 // Check that the same observer is still registered. | |
| 143 base::AutoLock auto_lock(*get_lock()); | |
| 144 auto it = std::find_if(observers_.begin(), observers_.end(), | |
| 145 [unique_id](const ObserverInfo& info) { | |
| 146 return info.unique_id == unique_id; | |
| 147 }); | |
| 148 if (it == observers_.end()) | |
| 149 return; | |
| 150 observer = it->observer; | |
| 151 } | |
| 152 | |
| 153 observer->ReceivedBrokerableAttachmentWithId(id); | |
| 154 } | |
| 155 | |
| 156 AttachmentBroker::ObserverInfo::ObserverInfo() {} | |
| 157 AttachmentBroker::ObserverInfo::ObserverInfo(const ObserverInfo& other) = | |
| 158 default; | |
| 159 AttachmentBroker::ObserverInfo::~ObserverInfo() {} | |
| 160 | |
| 161 } // namespace IPC | |
| OLD | NEW |