// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "platform/impl/udp_socket_reader_posix.h" #include #include #include "platform/impl/socket_handle_posix.h" #include "platform/impl/udp_socket_posix.h" #include "util/osp_logging.h" namespace openscreen { UdpSocketReaderPosix::UdpSocketReaderPosix(SocketHandleWaiter* waiter) : waiter_(waiter) {} UdpSocketReaderPosix::~UdpSocketReaderPosix() { waiter_->UnsubscribeAll(this); } void UdpSocketReaderPosix::ProcessReadyHandle(SocketHandleRef handle, uint32_t flags) { if (flags & SocketHandleWaiter::Flags::kReadable) { std::lock_guard lock(mutex_); // NOTE: Because sockets_ is expected to remain small, the performance here // is better than using an unordered_set. for (UdpSocketPosix* socket : sockets_) { if (socket->GetHandle() == handle) { socket->ReceiveMessage(); break; } } } } void UdpSocketReaderPosix::OnCreate(UdpSocket* socket) { UdpSocketPosix* read_socket = static_cast(socket); { std::lock_guard lock(mutex_); sockets_.push_back(read_socket); } waiter_->Subscribe(this, std::cref(read_socket->GetHandle())); } void UdpSocketReaderPosix::OnDestroy(UdpSocket* socket) { UdpSocketPosix* destroyed_socket = static_cast(socket); OnDelete(destroyed_socket); } void UdpSocketReaderPosix::OnDelete(UdpSocketPosix* socket, bool disable_locking_for_testing) { { std::unique_lock lock(mutex_); auto it = std::find(sockets_.begin(), sockets_.end(), socket); if (it != sockets_.end()) { sockets_.erase(it); } } waiter_->OnHandleDeletion(this, std::cref(socket->GetHandle()), disable_locking_for_testing); } bool UdpSocketReaderPosix::IsMappedReadForTesting( UdpSocketPosix* socket) const { return std::find(sockets_.begin(), sockets_.end(), socket) != sockets_.end(); } } // namespace openscreen