blob: 56b2f05b03c6728ef33744bc3b835dc62e0b39e1 [file] [log] [blame]
Ryan Keanedeb48b32019-06-28 16:24:40 -07001// Copyright 2019 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 "platform/api/udp_socket.h"
6
Ryan Keanea4dfaa12019-08-19 10:30:20 -07007#include "platform/api/task_runner.h"
8
Ryan Keanedeb48b32019-06-28 16:24:40 -07009namespace openscreen {
10namespace platform {
11
Ryan Keanea4dfaa12019-08-19 10:30:20 -070012UdpSocket::UdpSocket(TaskRunner* task_runner, Client* client)
13 : client_(client), task_runner_(task_runner) {
14 OSP_CHECK(task_runner_);
Ryan Keane9222e042019-08-27 10:44:13 -070015 if (lifetime_observer_.load()) {
16 lifetime_observer_.load()->OnCreate(this);
17 }
Ryan Keanedeb48b32019-06-28 16:24:40 -070018}
19
20UdpSocket::~UdpSocket() {
Ryan Keane83050af2019-08-26 08:58:09 -070021 OSP_DCHECK(is_closed_);
Ryan Keanedeb48b32019-06-28 16:24:40 -070022}
23
Ryan Keane9222e042019-08-27 10:44:13 -070024// static
25void UdpSocket::SetLifetimeObserver(LifetimeObserver* observer) {
26 lifetime_observer_.store(observer);
Ryan Keanedeb48b32019-06-28 16:24:40 -070027}
28
Ryan Keane9222e042019-08-27 10:44:13 -070029// static
30std::atomic<UdpSocket::LifetimeObserver*> UdpSocket::lifetime_observer_{
31 nullptr};
32
Ryan Keane63fbedd2019-08-19 12:33:41 -070033void UdpSocket::OnError(Error error) {
Ryan Keane83050af2019-08-26 08:58:09 -070034 CloseIfError(error);
35
Ryan Keane63fbedd2019-08-19 12:33:41 -070036 if (!client_) {
37 return;
38 }
39
40 task_runner_->PostTask([e = std::move(error), this]() mutable {
41 this->client_->OnError(this, std::move(e));
42 });
43}
44void UdpSocket::OnSendError(Error error) {
45 if (!client_) {
46 return;
47 }
48
49 task_runner_->PostTask([e = std::move(error), this]() mutable {
50 this->client_->OnSendError(this, std::move(e));
51 });
52}
53void UdpSocket::OnRead(ErrorOr<UdpPacket> read_data) {
54 if (!client_) {
55 return;
56 }
57
58 task_runner_->PostTask([data = std::move(read_data), this]() mutable {
59 this->client_->OnRead(this, std::move(data));
60 });
61}
62
Ryan Keane83050af2019-08-26 08:58:09 -070063void UdpSocket::CloseIfError(const Error& error) {
64 if (error.code() != Error::Code::kNone &&
65 error.code() != Error::Code::kAgain) {
66 CloseIfOpen();
67 }
68}
69
70void UdpSocket::CloseIfOpen() {
71 if (!is_closed_.exchange(true)) {
Ryan Keane9222e042019-08-27 10:44:13 -070072 if (lifetime_observer_.load()) {
73 lifetime_observer_.load()->OnDestroy(this);
74 }
Ryan Keane83050af2019-08-26 08:58:09 -070075 Close();
76 }
77}
78
Ryan Keanedeb48b32019-06-28 16:24:40 -070079} // namespace platform
80} // namespace openscreen