1
2
3
4
5
6 #include <cmajor/build/SocketServer.hpp>
7 #include <cmajor/build/ServerConfig.hpp>
8 #include <cmajor/symbols/GlobalFlags.hpp>
9 #include <soulng/util/Log.hpp>
10
11 namespace cmajor { namespace build {
12
13 using namespace cmajor::symbols;
14 using namespace soulng::util;
15
16 SocketServer::SocketServer(Log* log_, const std::string& serverName_, bool continuous_) :
17 log(log_), serverName(serverName_), name("socket server: '" + serverName + "'"), socket(), running(), isRunning(false), exiting(false), continuous(continuous_)
18 {
19 ServerInfo* serverInfo = ServerConfig::Instance().GetServerInfo(serverName, true, true);
20 if (serverInfo)
21 {
22 if (GetGlobalFlag(GlobalFlags::verbose))
23 {
24 LogMessage(-1, "socket server: binding server '" + serverName + "' to port " + std::to_string(serverInfo->Port()) + "...");
25 }
26 socket.Bind(serverInfo->Port());
27 if (GetGlobalFlag(GlobalFlags::verbose))
28 {
29 LogMessage(-1, "socket server: server '" + serverName + "' listening...");
30 }
31 socket.Listen(10);
32 }
33 else
34 {
35 throw std::runtime_error("socket server: server name '" + serverName + "' not found");
36 }
37 }
38
39 const std::string& SocketServer::Name() const
40 {
41 return name;
42 }
43
44 void SocketServer::WaitForRunning()
45 {
46 if (GetGlobalFlag(GlobalFlags::verbose))
47 {
48 LogMessage(-1, "socket server: '" + serverName + "' wait for running...");
49 }
50 {
51 std::unique_lock<std::mutex> lock(mtx);
52 running.wait(lock, [this]{ return isRunning; });
53 }
54 if (GetGlobalFlag(GlobalFlags::verbose))
55 {
56 LogMessage(-1, "socket server: '" + serverName + "' running");
57 }
58 }
59
60 void SocketServer::Run(const std::string& prompt)
61 {
62 while (!exiting)
63 {
64 if (!prompt.empty())
65 {
66 LogMessage(-1, "socket server: " + prompt);
67 }
68 isRunning = true;
69 running.notify_all();
70 if (GetGlobalFlag(GlobalFlags::verbose))
71 {
72 LogMessage(-1, "socket server: '" + serverName + "' waiting for client connection...");
73 }
74 TcpSocket connectedSocket = socket.Accept();
75 if (GetGlobalFlag(GlobalFlags::verbose))
76 {
77 LogMessage(-1, "socket server: '" + serverName + "' accepted a client connection...");
78 }
79 connection.reset(new SocketConnection(log, this, std::move(connectedSocket)));
80 buildServer.reset(new BuildServer(connection.get()));
81 if (GetGlobalFlag(GlobalFlags::verbose))
82 {
83 LogMessage(-1, "socket server: '" + serverName + "' running build server...");
84 }
85 buildServer->Run();
86 }
87 }
88
89 void SocketServer::Exit()
90 {
91 if (continuous)
92 {
93 buildServer->Exit();
94 buildServer->SetConnection(nullptr);
95 connection->SetServer(nullptr);
96 return;
97 }
98 exiting = true;
99 if (GetGlobalFlag(GlobalFlags::verbose))
100 {
101 LogMessage(-1, "socket server: '" + serverName + "' exiting...");
102 }
103 try
104 {
105 socket.Close();
106 }
107 catch (const std::exception&;)
108 {
109 }
110 if (GetGlobalFlag(GlobalFlags::verbose))
111 {
112 LogMessage(-1, "socket server: '" + serverName + "' exited");
113 }
114 }
115
116 void SocketServer::ExitContinuous()
117 {
118 continuous = false;
119 Exit();
120 }
121
122 } }