Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmcppdap/src/network.cpp
3153 views
1
// Copyright 2019 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "dap/network.h"
16
17
#include "socket.h"
18
19
#include <atomic>
20
#include <mutex>
21
#include <string>
22
#include <thread>
23
24
namespace {
25
26
class Impl : public dap::net::Server {
27
public:
28
Impl() : stopped{true} {}
29
30
~Impl() { stop(); }
31
32
bool start(int port,
33
const OnConnect& onConnect,
34
const OnError& onError) override {
35
return start("localhost", port, onConnect, onError);
36
}
37
38
bool start(const char* address,
39
int port,
40
const OnConnect& onConnect,
41
const OnError& onError) override {
42
std::unique_lock<std::mutex> lock(mutex);
43
stopWithLock();
44
socket = std::unique_ptr<dap::Socket>(
45
new dap::Socket(address, std::to_string(port).c_str()));
46
47
if (!socket->isOpen()) {
48
onError("Failed to open socket");
49
return false;
50
}
51
52
stopped = false;
53
thread = std::thread([=] {
54
while (true) {
55
if (auto rw = socket->accept()) {
56
onConnect(rw);
57
continue;
58
}
59
if (!stopped) {
60
onError("Failed to accept connection");
61
}
62
break;
63
};
64
});
65
66
return true;
67
}
68
69
void stop() override {
70
std::unique_lock<std::mutex> lock(mutex);
71
stopWithLock();
72
}
73
74
private:
75
bool isRunning() { return !stopped; }
76
77
void stopWithLock() {
78
if (!stopped.exchange(true)) {
79
socket->close();
80
thread.join();
81
}
82
}
83
84
std::mutex mutex;
85
std::thread thread;
86
std::unique_ptr<dap::Socket> socket;
87
std::atomic<bool> stopped;
88
OnError errorHandler;
89
};
90
91
} // anonymous namespace
92
93
namespace dap {
94
namespace net {
95
96
std::unique_ptr<Server> Server::create() {
97
return std::unique_ptr<Server>(new Impl());
98
}
99
100
std::shared_ptr<ReaderWriter> connect(const char* addr,
101
int port,
102
uint32_t timeoutMillis) {
103
return Socket::connect(addr, std::to_string(port).c_str(), timeoutMillis);
104
}
105
106
} // namespace net
107
} // namespace dap
108
109