stdin: synthesize an "exit" NotificationMessage in abnormal termination

This commit is contained in:
Fangrui Song 2019-03-04 06:52:07 -08:00
parent 401f057027
commit cff00a8711

View File

@ -503,13 +503,14 @@ void LaunchStdin() {
set_thread_name("stdin"); set_thread_name("stdin");
std::string str; std::string str;
const std::string_view kContentLength("Content-Length: "); const std::string_view kContentLength("Content-Length: ");
bool received_exit = false;
while (true) { while (true) {
int len = 0; int len = 0;
str.clear(); str.clear();
while (true) { while (true) {
int c = getchar(); int c = getchar();
if (c == EOF) if (c == EOF)
return; goto quit;
if (c == '\n') { if (c == '\n') {
if (str.empty()) if (str.empty())
break; break;
@ -525,7 +526,7 @@ void LaunchStdin() {
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
int c = getchar(); int c = getchar();
if (c == EOF) if (c == EOF)
return; goto quit;
str[i] = c; str[i] = c;
} }
@ -549,16 +550,28 @@ void LaunchStdin() {
LOG_V(2) << "receive NotificationMessage " << method; LOG_V(2) << "receive NotificationMessage " << method;
if (method.empty()) if (method.empty())
continue; continue;
bool should_exit = method == "exit"; received_exit = method == "exit";
// g_config is not available before "initialize". Use 0 in that case. // g_config is not available before "initialize". Use 0 in that case.
on_request->PushBack( on_request->PushBack(
{id, std::move(method), std::move(message), std::move(document), {id, std::move(method), std::move(message), std::move(document),
chrono::steady_clock::now() + chrono::steady_clock::now() +
chrono::milliseconds(g_config ? g_config->request.timeout : 0)}); chrono::milliseconds(g_config ? g_config->request.timeout : 0)});
if (should_exit) if (received_exit)
break; break;
} }
quit:
if (!received_exit) {
const std::string_view str("{\"jsonrpc\":\"2.0\",\"method\":\"exit\"}");
auto message = std::make_unique<char[]>(str.size());
std::copy(str.begin(), str.end(), message.get());
auto document = std::make_unique<rapidjson::Document>();
document->Parse(message.get(), str.size());
on_request->PushBack({RequestId(), std::string("exit"),
std::move(message), std::move(document),
chrono::steady_clock::now()});
}
ThreadLeave(); ThreadLeave();
}).detach(); }).detach();
} }