Remove/fix calls to std::abort() (#648)

This commit is contained in:
Cameron Gutman
2022-12-29 10:09:11 -06:00
committed by GitHub
parent 8ad7af86c0
commit d6db10afb4
9 changed files with 90 additions and 68 deletions

View File

@@ -241,8 +241,7 @@ Application List
- ``undo`` - Run after the application has terminated - ``undo`` - Run after the application has terminated
- This should not fail considering it is supposed to undo the ``do`` commands - Failures of ``undo`` commands are ignored
- If it fails, Sunshine is terminated
- ``working-dir`` - The working directory to use. If not specified, Sunshine will use the application directory. - ``working-dir`` - The working directory to use. If not specified, Sunshine will use the application directory.

View File

@@ -11,6 +11,7 @@
#include <mutex> #include <mutex>
#include <string> #include <string>
#include "src/main.h"
#include "src/thread_safe.h" #include "src/thread_safe.h"
#include "src/utility.h" #include "src/utility.h"
@@ -197,7 +198,7 @@ struct hwdevice_t {
* implementations must take ownership of 'frame' * implementations must take ownership of 'frame'
*/ */
virtual int set_frame(AVFrame *frame) { virtual int set_frame(AVFrame *frame) {
std::abort(); // ^ This function must never be called BOOST_LOG(error) << "Illegal call to hwdevice_t::set_frame(). Did you forget to override it?";
return -1; return -1;
}; };

View File

@@ -89,9 +89,7 @@ std::unique_ptr<mic_t> microphone(const std::uint8_t *mapping, int channels, std
if(!mic->mic) { if(!mic->mic) {
auto err_str = pa_strerror(status); auto err_str = pa_strerror(status);
BOOST_LOG(error) << "pa_simple_new() failed: "sv << err_str; BOOST_LOG(error) << "pa_simple_new() failed: "sv << err_str;
return nullptr;
log_flush();
std::abort();
} }
return mic; return mic;
@@ -232,10 +230,8 @@ public:
auto status = pa_mainloop_run(loop, &retval); auto status = pa_mainloop_run(loop, &retval);
if(status < 0) { if(status < 0) {
BOOST_LOG(fatal) << "Couldn't run pulseaudio main loop"sv; BOOST_LOG(error) << "Couldn't run pulseaudio main loop"sv;
return;
log_flush();
std::abort();
} }
}, },
loop.get() loop.get()

View File

@@ -902,6 +902,9 @@ void broadcastRumble(safe::queue_t<mail_evdev_t> &rumble_queue_queue) {
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
auto touchscreen = ((input_raw_t *)input.get())->touch_input.get(); auto touchscreen = ((input_raw_t *)input.get())->touch_input.get();
if(!touchscreen) {
return;
}
auto scaled_x = (int)std::lround((x + touch_port.offset_x) * ((float)target_touch_port.width / (float)touch_port.width)); auto scaled_x = (int)std::lround((x + touch_port.offset_x) * ((float)target_touch_port.width / (float)touch_port.width));
auto scaled_y = (int)std::lround((y + touch_port.offset_y) * ((float)target_touch_port.height / (float)touch_port.height)); auto scaled_y = (int)std::lround((y + touch_port.offset_y) * ((float)target_touch_port.height / (float)touch_port.height));
@@ -916,6 +919,9 @@ void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y)
void move_mouse(input_t &input, int deltaX, int deltaY) { void move_mouse(input_t &input, int deltaX, int deltaY) {
auto mouse = ((input_raw_t *)input.get())->mouse_input.get(); auto mouse = ((input_raw_t *)input.get())->mouse_input.get();
if(!mouse) {
return;
}
if(deltaX) { if(deltaX) {
libevdev_uinput_write_event(mouse, EV_REL, REL_X, deltaX); libevdev_uinput_write_event(mouse, EV_REL, REL_X, deltaX);
@@ -954,6 +960,10 @@ void button_mouse(input_t &input, int button, bool release) {
} }
auto mouse = ((input_raw_t *)input.get())->mouse_input.get(); auto mouse = ((input_raw_t *)input.get())->mouse_input.get();
if(!mouse) {
return;
}
libevdev_uinput_write_event(mouse, EV_MSC, MSC_SCAN, scan); libevdev_uinput_write_event(mouse, EV_MSC, MSC_SCAN, scan);
libevdev_uinput_write_event(mouse, EV_KEY, btn_type, release ? 0 : 1); libevdev_uinput_write_event(mouse, EV_KEY, btn_type, release ? 0 : 1);
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
@@ -963,6 +973,10 @@ void scroll(input_t &input, int high_res_distance) {
int distance = high_res_distance / 120; int distance = high_res_distance / 120;
auto mouse = ((input_raw_t *)input.get())->mouse_input.get(); auto mouse = ((input_raw_t *)input.get())->mouse_input.get();
if(!mouse) {
return;
}
libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL, distance); libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL, distance);
libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL_HI_RES, high_res_distance); libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL_HI_RES, high_res_distance);
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
@@ -978,6 +992,9 @@ static keycode_t keysym(std::uint16_t modcode) {
void keyboard(input_t &input, uint16_t modcode, bool release) { void keyboard(input_t &input, uint16_t modcode, bool release) {
auto keyboard = ((input_raw_t *)input.get())->keyboard_input.get(); auto keyboard = ((input_raw_t *)input.get())->keyboard_input.get();
if(!keyboard) {
return;
}
auto keycode = keysym(modcode); auto keycode = keysym(modcode);
if(keycode.keycode == UNKNOWN) { if(keycode.keycode == UNKNOWN) {
@@ -1255,10 +1272,13 @@ input_t input() {
gp.mouse_dev = mouse(); gp.mouse_dev = mouse();
gp.gamepad_dev = x360(); gp.gamepad_dev = x360();
// If we do not have a keyboard, gamepad or mouse, no input is possible and we should abort gp.create_mouse();
if(gp.create_mouse() || gp.create_touchscreen() || gp.create_keyboard()) { gp.create_touchscreen();
log_flush(); gp.create_keyboard();
std::abort();
// If we do not have a keyboard, touchscreen, or mouse, no input is possible
if(!gp.mouse_input && !gp.touch_input && !gp.keyboard_input) {
BOOST_LOG(error) << "Unable to create any input devices! Are you a member of the 'input' group?"sv;
} }
return result; return result;

View File

@@ -251,11 +251,18 @@ public:
fb_t fb(plane_t::pointer plane) { fb_t fb(plane_t::pointer plane) {
cap_sys_admin admin; cap_sys_admin admin;
auto fb = drmModeGetFB2(fd.el, plane->fb_id);
auto fb2 = drmModeGetFB2(fd.el, plane->fb_id);
if(fb2) {
return std::make_unique<wrapper_fb>(fb2);
}
auto fb = drmModeGetFB(fd.el, plane->fb_id);
if(fb) { if(fb) {
return std::make_unique<wrapper_fb>(fb); return std::make_unique<wrapper_fb>(fb);
} }
return std::make_unique<wrapper_fb>(drmModeGetFB(fd.el, plane->fb_id));
return nullptr;
} }
crtc_t crtc(std::uint32_t id) { crtc_t crtc(std::uint32_t id) {

View File

@@ -495,10 +495,7 @@ void gamepad(input_t &input, int nr, const gamepad_state_t &gamepad_state) {
} }
if(!VIGEM_SUCCESS(status)) { if(!VIGEM_SUCCESS(status)) {
BOOST_LOG(fatal) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']'; BOOST_LOG(warning) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
log_flush();
std::abort();
} }
} }

View File

@@ -25,8 +25,9 @@ using namespace std::literals;
#define SV(quote) __SV(quote) #define SV(quote) __SV(quote)
extern "C" { extern "C" {
#ifndef __MINGW32__
constexpr auto DNS_REQUEST_PENDING = 9506L; constexpr auto DNS_REQUEST_PENDING = 9506L;
#ifndef __MINGW32__
constexpr auto DNS_QUERY_REQUEST_VERSION1 = 0x1; constexpr auto DNS_QUERY_REQUEST_VERSION1 = 0x1;
constexpr auto DNS_QUERY_RESULTS_VERSION1 = 0x1; constexpr auto DNS_QUERY_RESULTS_VERSION1 = 0x1;
#endif #endif
@@ -88,26 +89,17 @@ _FN(_DnsServiceRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _I
namespace platf::publish { namespace platf::publish {
VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) { VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance) {
auto alarm = (safe::alarm_t<DNS_STATUS>::element_type *)pQueryContext; auto alarm = (safe::alarm_t<PDNS_SERVICE_INSTANCE>::element_type *)pQueryContext;
auto fg = util::fail_guard([&]() {
if(pInstance) {
_DnsServiceFreeInstance(pInstance);
}
});
if(status) { if(status) {
print_status("register_cb()"sv, status); print_status("register_cb()"sv, status);
alarm->ring(-1);
return;
} }
alarm->ring(0); alarm->ring(pInstance);
} }
static int service(bool enable) { static int service(bool enable, PDNS_SERVICE_INSTANCE &existing_instance) {
auto alarm = safe::make_alarm<DNS_STATUS>(); auto alarm = safe::make_alarm<PDNS_SERVICE_INSTANCE>();
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
@@ -124,38 +116,66 @@ static int service(bool enable) {
DNS_SERVICE_REGISTER_REQUEST req {}; DNS_SERVICE_REGISTER_REQUEST req {};
req.Version = DNS_QUERY_REQUEST_VERSION1; req.Version = DNS_QUERY_REQUEST_VERSION1;
req.pQueryContext = alarm.get(); req.pQueryContext = alarm.get();
req.pServiceInstance = &instance; req.pServiceInstance = enable ? &instance : existing_instance;
req.pRegisterCompletionCallback = register_cb; req.pRegisterCompletionCallback = register_cb;
DNS_STATUS status {}; DNS_STATUS status {};
if(enable) { if(enable) {
status = _DnsServiceRegister(&req, nullptr); status = _DnsServiceRegister(&req, nullptr);
if(status != DNS_REQUEST_PENDING) {
print_status("DnsServiceRegister()"sv, status);
return -1;
}
} }
else { else {
status = _DnsServiceDeRegister(&req, nullptr); status = _DnsServiceDeRegister(&req, nullptr);
if(status != DNS_REQUEST_PENDING) {
print_status("DnsServiceDeRegister()"sv, status);
return -1;
}
} }
alarm->wait(); alarm->wait();
status = *alarm->status(); auto registered_instance = alarm->status();
if(status) { if(enable) {
BOOST_LOG(error) << "No mDNS service"sv; // Store this instance for later deregistration
return -1; existing_instance = registered_instance;
}
else if(registered_instance) {
// Deregistration was successful
_DnsServiceFreeInstance(registered_instance);
existing_instance = nullptr;
} }
return 0; return registered_instance ? 0 : -1;
} }
class deinit_t : public ::platf::deinit_t { class mdns_registration_t : public ::platf::deinit_t {
public: public:
~deinit_t() override { mdns_registration_t() : existing_instance(nullptr) {
if(service(false)) { if(service(true, existing_instance)) {
std::abort(); BOOST_LOG(error) << "Unable to register Sunshine mDNS service"sv;
return;
} }
BOOST_LOG(info) << "Unregistered Sunshine Gamestream service"sv; BOOST_LOG(info) << "Registered Sunshine mDNS service"sv;
} }
~mdns_registration_t() override {
if(existing_instance) {
if(service(false, existing_instance)) {
BOOST_LOG(error) << "Unable to unregister Sunshine mDNS service"sv;
return;
}
BOOST_LOG(info) << "Unregistered Sunshine mDNS service"sv;
}
}
private:
PDNS_SERVICE_INSTANCE existing_instance;
}; };
int load_funcs(HMODULE handle) { int load_funcs(HMODULE handle) {
@@ -184,12 +204,6 @@ std::unique_ptr<::platf::deinit_t> start() {
return nullptr; return nullptr;
} }
if(service(true)) { return std::make_unique<mdns_registration_t>();
return nullptr;
}
BOOST_LOG(info) << "Registered Sunshine Gamestream service"sv;
return std::make_unique<deinit_t>();
} }
} // namespace platf::publish } // namespace platf::publish

View File

@@ -195,12 +195,6 @@ void proc_t::terminate() {
_process_handle = bp::group(); _process_handle = bp::group();
_app_id = -1; _app_id = -1;
if(ec) {
BOOST_LOG(fatal) << "System: "sv << ec.message();
log_flush();
std::abort();
}
for(; _undo_it != _undo_begin; --_undo_it) { for(; _undo_it != _undo_begin; --_undo_it) {
auto &cmd = (_undo_it - 1)->undo_cmd; auto &cmd = (_undo_it - 1)->undo_cmd;
@@ -213,15 +207,11 @@ void proc_t::terminate() {
auto ret = exe_with_full_privs(cmd, _env, _pipe, ec); auto ret = exe_with_full_privs(cmd, _env, _pipe, ec);
if(ec) { if(ec) {
BOOST_LOG(fatal) << "System: "sv << ec.message(); BOOST_LOG(warning) << "System: "sv << ec.message();
log_flush();
std::abort();
} }
if(ret != 0) { if(ret != 0) {
BOOST_LOG(fatal) << "Return code ["sv << ret << ']'; BOOST_LOG(warning) << "Return code ["sv << ret << ']';
log_flush();
std::abort();
} }
} }

View File

@@ -877,10 +877,8 @@ void recvThread(broadcast_ctx_t &ctx) {
} }
if(ec || !bytes) { if(ec || !bytes) {
BOOST_LOG(fatal) << "Couldn't receive data from udp socket: "sv << ec.message(); BOOST_LOG(error) << "Couldn't receive data from udp socket: "sv << ec.message();
return;
log_flush();
std::abort();
} }
auto it = peer_to_session.find(peer.address()); auto it = peer_to_session.find(peer.address());