Bug 1760357 - Part 5: Add basic annotations to the mojo ports code, r=jesup

Unfortunately the locking behaviour in ports around the Port type is a bit too
complex to easily express in a way which satisfies the thread safety analysis,
so it was not annotated.

Differential Revision: https://phabricator.services.mozilla.com/D141536
This commit is contained in:
Nika Layzell 2022-03-22 14:59:42 +00:00
Родитель 8b588479cd
Коммит 2637d4b88f
3 изменённых файлов: 19 добавлений и 11 удалений

Просмотреть файл

@ -1053,8 +1053,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref,
{
// Needed to swap peer map entries below.
PortLocker::AssertNoPortsLockedOnCurrentThread();
mozilla::Maybe<mozilla::MutexAutoLock> ports_locker(std::in_place,
ports_lock_);
mozilla::ReleasableMutexAutoLock ports_locker(ports_lock_);
mozilla::Maybe<PortLocker> locker(std::in_place, port_refs, size_t(2));
auto* port0 = locker->GetPort(port0_ref);
@ -1085,7 +1084,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref, const PortRef& port1_ref,
const bool close_port1 =
port1->state == Port::kReceiving || allow_close_on_bad_state;
locker.reset();
ports_locker.reset();
ports_locker.Unlock();
if (close_port0) {
ClosePort(port0_ref);
}

Просмотреть файл

@ -222,7 +222,8 @@ class Node {
bool allow_close_on_bad_state);
void ConvertToProxy(Port* port, const NodeName& to_node_name,
PortName* port_name,
Event::PortDescriptor* port_descriptor);
Event::PortDescriptor* port_descriptor)
REQUIRES(ports_lock_);
int AcceptPort(const PortName& port_name,
const Event::PortDescriptor& port_descriptor);
@ -244,17 +245,20 @@ class Node {
// exist in |ports_|.
void UpdatePortPeerAddress(const PortName& local_port_name, Port* local_port,
const NodeName& new_peer_node,
const PortName& new_peer_port);
const PortName& new_peer_port)
REQUIRES(ports_lock_);
// Removes an entry from |peer_port_map_| corresponding to |local_port|'s peer
// address, if valid.
void RemoveFromPeerPortMap(const PortName& local_port_name, Port* local_port);
void RemoveFromPeerPortMap(const PortName& local_port_name, Port* local_port)
REQUIRES(ports_lock_);
// Swaps the peer information for two local ports. Used during port merges.
// Note that |ports_lock_| must be held along with each of the two port's own
// locks, through the extent of this method.
void SwapPortPeers(const PortName& port0_name, Port* port0,
const PortName& port1_name, Port* port1);
const PortName& port1_name, Port* port1)
REQUIRES(ports_lock_);
// Sends an acknowledge request to the peer if the port has a non-zero
// |sequence_num_acknowledge_interval|. This needs to be done when the port's
@ -287,8 +291,9 @@ class Node {
// Because UserMessage events may execute arbitrary user code during
// destruction, it is also important to ensure that such events are never
// destroyed while this (or any individual Port) lock is held.
mozilla::Mutex ports_lock_ MOZ_UNANNOTATED{"Ports Lock"};
std::unordered_map<LocalPortName, RefPtr<Port>> ports_;
mozilla::Mutex ports_lock_{"Ports Lock"};
std::unordered_map<LocalPortName, RefPtr<Port>> ports_
GUARDED_BY(ports_lock_);
// Maps a peer port name to a list of PortRefs for all local ports which have
// the port name key designated as their peer port. The set of local ports
@ -307,7 +312,8 @@ class Node {
// a given peer node or a local port that references a specific given peer
// port on a peer node. The key to this map is the corresponding peer node
// name.
std::unordered_map<NodeName, PeerPortMap> peer_port_maps_;
std::unordered_map<NodeName, PeerPortMap> peer_port_maps_
GUARDED_BY(ports_lock_);
};
} // namespace ports

Просмотреть файл

@ -188,7 +188,10 @@ class Port {
~Port();
mozilla::Mutex lock_ MOZ_UNANNOTATED{"Port State"};
// This lock guards all fields in Port, but is locked in a unique way which is
// unfortunately somewhat difficult to get to work with the thread-safety
// analysis.
mozilla::Mutex lock_ MOZ_ANNOTATED{"Port State"};
};
} // namespace ports