Fix bug causing Sunshine thinking there is still an app running after shutting down app from within the Stream

This commit is contained in:
loki 2019-12-30 19:37:12 +01:00
parent 94e1dc903e
commit 330b0ef8ef
5 changed files with 51 additions and 46 deletions

View File

@ -36,6 +36,7 @@ int main(int argc, char *argv[]) {
if(!proc_opt) {
return 7;
}
proc::proc = std::move(*proc_opt);
reed_solomon_init();

View File

@ -87,7 +87,6 @@ enum class op_e {
REMOVE
};
std::int64_t current_appid { -1 };
std::string local_ip;
net::net_e origin_pin_allowed;
@ -448,7 +447,8 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
else {
tree.put("root.ExternalIP", config::nvhttp.external_ip);
}
auto current_appid = proc::proc.running();
tree.put("root.PairStatus", pair_status);
tree.put("root.currentgame", current_appid >= 0 ? current_appid + 2 : 0);
tree.put("root.state", "_SERVER_BUSY");
@ -491,11 +491,11 @@ void applist(resp_https_t response, req_https_t request) {
desktop.put("ID"s, 1);
int x = 2;
for(auto &[name, proc] : proc::proc.get_apps()) {
for(auto &proc : proc::proc.get_apps()) {
pt::ptree app;
app.put("IsHdrSupported"s, 0);
app.put("AppTitle"s, name);
app.put("AppTitle"s, proc.name);
app.put("ID"s, x++);
apps.push_back(std::make_pair("App", std::move(app)));
@ -527,25 +527,11 @@ void launch(resp_https_t response, req_https_t request) {
return;
}
if(!proc::proc.running()) {
current_appid = -1;
}
auto current_appid = proc::proc.running();
if(appid >= 0 && appid != current_appid) {
auto &apps = proc::proc.get_apps();
if(appid >= apps.size()) {
tree.put("root.<xmlattr>.status_code", 404);
tree.put("root.gamesession", 0);
return;
}
auto pos = std::begin(apps);
std::advance(pos, appid);
auto err = proc::proc.execute(pos->first);
auto err = proc::proc.execute(appid);
if(err) {
tree.put("root.<xmlattr>.status_code", 500);
tree.put("root.<xmlattr>.status_code", err);
tree.put("root.gamesession", 0);
return;
@ -590,15 +576,15 @@ void resume(resp_https_t response, req_https_t request) {
response->write(data.str());
});
stream::launch_session_t launch_session;
if(stream::has_session) {
auto current_appid = proc::proc.running();
if(current_appid == -1 || stream::has_session) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 503);
return;
}
stream::launch_session_t launch_session;
// Needed to determine if session must be closed when no process is running in proc::proc
launch_session.has_process = current_appid >= 0;
@ -628,6 +614,13 @@ void cancel(resp_https_t response, req_https_t request) {
response->write(data.str());
});
if(proc::proc.running() == -1) {
tree.put("root.cancel", 1);
tree.put("root.<xmlattr>.status_code", 200);
return;
}
if(stream::has_session) {
tree.put("root.<xmlattr>.status_code", 503);
tree.put("root.cancel", 0);
@ -636,7 +629,6 @@ void cancel(resp_https_t response, req_https_t request) {
}
proc::proc.terminate();
current_appid = -1;
tree.put("root.cancel", 1);
tree.put("root.<xmlattr>.status_code", 200);

View File

@ -41,18 +41,18 @@ int exe(const std::string &cmd, bp::environment &env, file_t &file, std::error_c
return bp::system(cmd, env, bp::std_out > file.get(), bp::std_err > file.get(), ec);
}
int proc_t::execute(const std::string &name) {
auto it = _name_to_proc.find(name);
int proc_t::execute(int app_id) {
if(app_id >= _apps.size()) {
std::cout << "Error: Couldn't find app with ID ["sv << app_id << ']' << std::endl;
return 404;
}
// Ensure starting from a clean slate
terminate();
if(it == std::end(_name_to_proc)) {
std::cout << "Error: Couldn't find ["sv << name << ']' << std::endl;
return 404;
}
auto &proc = it->second;
_app_id = app_id;
auto &proc = _apps[app_id];
_undo_begin = std::begin(proc.prep_cmds);
_undo_it = _undo_begin;
@ -102,8 +102,12 @@ int proc_t::execute(const std::string &name) {
return 0;
}
bool proc_t::running() {
return _process.running();
int proc_t::running() {
if(_process.running()) {
return _app_id;
}
return -1;
}
void proc_t::terminate() {
@ -142,8 +146,8 @@ void proc_t::terminate() {
_pipe.reset();
}
const std::unordered_map<std::string, ctx_t> &proc_t::get_apps() const {
return _name_to_proc;
const std::vector<ctx_t> &proc_t::get_apps() const {
return _apps;
}
proc_t::~proc_t() {
@ -221,7 +225,7 @@ std::optional<proc::proc_t> parse(const std::string& file_name) {
auto this_env = boost::this_process::environment();
std::unordered_map<std::string, proc::ctx_t> apps;
std::vector<proc::ctx_t> apps;
for(auto &[_,app_node] : apps_node) {
proc::ctx_t ctx;
@ -255,9 +259,10 @@ std::optional<proc::proc_t> parse(const std::string& file_name) {
ctx.cmd = "sh -c \"while true; do sleep 10000; done;\"";
}
ctx.name = std::move(name);
ctx.prep_cmds = std::move(prep_cmds);
apps.emplace(std::move(name), std::move(ctx));
apps.emplace_back(std::move(ctx));
}
bp::environment env = boost::this_process::environment();

View File

@ -37,6 +37,7 @@ struct cmd_t {
struct ctx_t {
std::vector<cmd_t> prep_cmds;
std::string name;
std::string cmd;
std::string output;
};
@ -47,21 +48,27 @@ public:
proc_t(
boost::process::environment &&env,
std::unordered_map<std::string, ctx_t> &&name_to_proc) :
std::vector<ctx_t> &&apps) :
_env(std::move(env)),
_name_to_proc(std::move(name_to_proc)) {}
_apps(std::move(apps)) {}
int execute(const std::string &name);
bool running();
int execute(int app_id);
/**
* @return _app_id if a process is running, otherwise returns -1
*/
int running();
~proc_t();
const std::unordered_map<std::string, ctx_t> &get_apps() const;
const std::vector<ctx_t> &get_apps() const;
void terminate();
private:
int _app_id;
boost::process::environment _env;
std::unordered_map<std::string, ctx_t> _name_to_proc;
std::vector<ctx_t> _apps;
boost::process::child _process;
boost::process::group _process_handle;

View File

@ -549,7 +549,7 @@ void controlThread(video::idr_event_t idr_events) {
stop(session);
}
if(session.has_process && !proc::proc.running()) {
if(session.has_process && proc::proc.running() == -1) {
std::cout << "Process terminated"sv << std::endl;
std::uint16_t reason = 0x0100;