Merge pull request #422 from morphis/f/various-fixes
Fix various problems with the session manager startup process
This commit is contained in:
commit
17f6c8cd8b
7 changed files with 97 additions and 33 deletions
|
|
@ -29,6 +29,10 @@
|
|||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace {
|
||||
constexpr const std::chrono::milliseconds default_rpc_call_timeout{5000};
|
||||
} // namespace
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
AndroidApiStub::AndroidApiStub() {}
|
||||
|
|
@ -103,7 +107,9 @@ void AndroidApiStub::launch(const android::Intent &intent,
|
|||
google::protobuf::NewCallback(this, &AndroidApiStub::application_launched,
|
||||
c.get()));
|
||||
|
||||
launch_wait_handle_.wait_for_all();
|
||||
launch_wait_handle_.wait_for_pending(default_rpc_call_timeout);
|
||||
if (!launch_wait_handle_.has_result())
|
||||
throw std::runtime_error("RPC call timed out");
|
||||
|
||||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
|
@ -135,7 +141,9 @@ void AndroidApiStub::set_focused_task(const std::int32_t &id) {
|
|||
google::protobuf::NewCallback(
|
||||
this, &AndroidApiStub::focused_task_set, c.get()));
|
||||
|
||||
set_focused_task_handle_.wait_for_all();
|
||||
set_focused_task_handle_.wait_for_pending(default_rpc_call_timeout);
|
||||
if (!set_focused_task_handle_.has_result())
|
||||
throw std::runtime_error("RPC call timed out");
|
||||
|
||||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
|
@ -162,7 +170,9 @@ void AndroidApiStub::remove_task(const std::int32_t &id) {
|
|||
google::protobuf::NewCallback(
|
||||
this, &AndroidApiStub::task_removed, c.get()));
|
||||
|
||||
remove_task_handle_.wait_for_all();
|
||||
remove_task_handle_.wait_for_pending(default_rpc_call_timeout);
|
||||
if (!remove_task_handle_.has_result())
|
||||
throw std::runtime_error("RPC call timed out");
|
||||
|
||||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
|
@ -198,7 +208,9 @@ void AndroidApiStub::resize_task(const std::int32_t &id,
|
|||
google::protobuf::NewCallback(
|
||||
this, &AndroidApiStub::task_resized, c.get()));
|
||||
|
||||
resize_task_handle_.wait_for_all();
|
||||
resize_task_handle_.wait_for_pending(default_rpc_call_timeout);
|
||||
if (!resize_task_handle_.has_result())
|
||||
throw std::runtime_error("RPC call timed out");
|
||||
|
||||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,21 @@ namespace {
|
|||
const boost::posix_time::seconds max_wait_timeout{240};
|
||||
const int max_restart_attempts{3};
|
||||
const std::chrono::seconds restart_interval{5};
|
||||
|
||||
static int redirect_to_null(int flags, int fd) {
|
||||
int fd2;
|
||||
if ((fd2 = open("/dev/null", flags)) < 0)
|
||||
return -1;
|
||||
|
||||
if (fd2 == fd)
|
||||
return fd;
|
||||
|
||||
if (dup2(fd2, fd) < 0)
|
||||
return -1;
|
||||
|
||||
close(fd2);
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptr<dbus::stub::ApplicationManager> &stub) {
|
||||
|
|
@ -84,6 +99,8 @@ anbox::cmds::Launch::Launch()
|
|||
action([this](const cli::Command::Context&) {
|
||||
if (!intent_.valid()) {
|
||||
ERROR("The intent you provided is invalid. Please provide a correct launch intent.");
|
||||
ERROR("For example to launch the application manager, run:");
|
||||
ERROR("$ anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -142,12 +159,34 @@ anbox::cmds::Launch::Launch()
|
|||
}
|
||||
|
||||
try {
|
||||
auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr;
|
||||
// If we have logging enable in debug mode then we allow the child process
|
||||
// to print to stdout/stderr too.
|
||||
if (Log().GetSeverity() == Logger::Severity::kDebug)
|
||||
flags = core::posix::StandardStream::empty;
|
||||
auto flags = core::posix::StandardStream::empty;
|
||||
auto child = core::posix::fork([&]() {
|
||||
// We redirect all in/out/err to /dev/null as they can't be seen
|
||||
// anywhere. All logging output will directly go to syslog as we
|
||||
// will become a session leader below which will get us rid of a
|
||||
// controlling terminal.
|
||||
if (redirect_to_null(O_RDONLY, 0) < 0 ||
|
||||
redirect_to_null(O_WRONLY, 1) < 0 ||
|
||||
redirect_to_null(O_WRONLY, 2) < 0) {
|
||||
ERROR("Failed to redirect stdout/stderr/stdin: %s", strerror(errno));
|
||||
return core::posix::exit::Status::failure;
|
||||
}
|
||||
|
||||
// As we forked one time already we're sure that our process is
|
||||
// not the session leader anymore so we can safely become the
|
||||
// new one and lead the process group.
|
||||
if (setsid() < 0) {
|
||||
ERROR("Failed to become new session leader: %s", strerror(errno));
|
||||
return core::posix::exit::Status::failure;
|
||||
}
|
||||
|
||||
umask(0077);
|
||||
|
||||
if (chdir("/") < 0) {
|
||||
ERROR("Failed to change current directory: %s", strerror(errno));
|
||||
return core::posix::exit::Status::failure;
|
||||
}
|
||||
|
||||
auto grandchild = core::posix::exec(exe_path, args, env, flags);
|
||||
grandchild.dont_kill_on_cleanup();
|
||||
return core::posix::exit::Status::success;
|
||||
|
|
|
|||
|
|
@ -148,13 +148,6 @@ anbox::cmds::SessionManager::SessionManager()
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// If we're running with the properietary nvidia driver we always
|
||||
// use the host EGL driver as our translation doesn't work here.
|
||||
if (fs::exists("/dev/nvidiactl")) {
|
||||
INFO("Detected properietary nvidia driver; forcing use of the host EGL driver.");
|
||||
gles_driver_ = graphics::GLRendererServer::Config::Driver::Host;
|
||||
}
|
||||
|
||||
utils::ensure_paths({
|
||||
SystemConfiguration::instance().socket_dir(),
|
||||
SystemConfiguration::instance().input_device_dir(),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ struct ApplicationManager {
|
|||
typedef anbox::dbus::interface::ApplicationManager Interface;
|
||||
typedef void ResultType;
|
||||
static inline std::chrono::milliseconds default_timeout() {
|
||||
return std::chrono::seconds{1};
|
||||
return std::chrono::seconds{60};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@ bool Renderer::bindContext(HandleType p_context, HandleType p_drawSurface,
|
|||
draw ? draw->getEGLSurface() : EGL_NO_SURFACE,
|
||||
read ? read->getEGLSurface() : EGL_NO_SURFACE,
|
||||
ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) {
|
||||
ERROR("eglMakeCurrent failed");
|
||||
ERROR("eglMakeCurrent failed: 0x%04x", s_egl.eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -737,7 +737,7 @@ bool Renderer::bind_locked() {
|
|||
|
||||
if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface, m_pbufSurface,
|
||||
m_pbufContext)) {
|
||||
ERROR("eglMakeCurrent failed");
|
||||
ERROR("eglMakeCurrent failed: 0x%04x", s_egl.eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -938,13 +938,14 @@ void Renderer::draw(RendererWindow *window, const Renderable &renderable,
|
|||
bool Renderer::draw(EGLNativeWindowType native_window,
|
||||
const anbox::graphics::Rect &window_frame,
|
||||
const RenderableList &renderables) {
|
||||
|
||||
std::unique_lock<std::mutex> l(m_lock);
|
||||
|
||||
auto w = m_nativeWindows.find(native_window);
|
||||
if (w == m_nativeWindows.end()) return false;
|
||||
|
||||
if (!bindWindow_locked(w->second)) {
|
||||
m_lock.unlock();
|
||||
if (!bindWindow_locked(w->second))
|
||||
return false;
|
||||
}
|
||||
|
||||
setupViewport(w->second, window_frame);
|
||||
s_gles2.glViewport(0, 0, window_frame.width(), window_frame.height());
|
||||
|
|
@ -959,9 +960,5 @@ bool Renderer::draw(EGLNativeWindowType native_window,
|
|||
|
||||
unbind_locked();
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
m_lock.unlock();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,14 @@
|
|||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/manipulators.hpp>
|
||||
#include <boost/log/utility/setup.hpp>
|
||||
#define BOOST_LOG_USE_NATIVE_SYSLOG
|
||||
#include <boost/log/sinks/syslog_backend.hpp>
|
||||
|
||||
#include "anbox/logger.h"
|
||||
|
||||
namespace {
|
||||
namespace attrs {
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "anbox::Severity", anbox::Logger::Severity)
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "Severity", anbox::Logger::Severity)
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(Location, "Location", anbox::Logger::Location)
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(Timestamp, "Timestamp", boost::posix_time::ptime)
|
||||
}
|
||||
|
|
@ -39,7 +41,8 @@ struct BoostLogLogger : public anbox::Logger {
|
|||
BoostLogLogger() : initialized_(false) {}
|
||||
|
||||
void Init(const anbox::Logger::Severity& severity = anbox::Logger::Severity::kWarning) override {
|
||||
if (initialized_) return;
|
||||
if (initialized_)
|
||||
return;
|
||||
|
||||
boost::log::formatter formatter =
|
||||
boost::log::expressions::stream
|
||||
|
|
@ -53,8 +56,21 @@ struct BoostLogLogger : public anbox::Logger {
|
|||
<< boost::log::expressions::smessage;
|
||||
|
||||
boost::log::core::get()->remove_all_sinks();
|
||||
auto logger = boost::log::add_console_log(std::cout);
|
||||
logger->set_formatter(formatter);
|
||||
|
||||
// If we have a controlling tty then we use the console for log outpu
|
||||
// and otherwise we move everything into the system syslog.
|
||||
if (isatty(0)) {
|
||||
auto logger = boost::log::add_console_log(std::cout);
|
||||
logger->set_formatter(formatter);
|
||||
} else {
|
||||
boost::shared_ptr<boost::log::sinks::syslog_backend> backend(
|
||||
new boost::log::sinks::syslog_backend(
|
||||
boost::log::keywords::facility = boost::log::sinks::syslog::user,
|
||||
boost::log::keywords::use_impl = boost::log::sinks::syslog::native));
|
||||
backend->set_severity_mapper(boost::log::sinks::syslog::direct_severity_mapping<int>("Severity"));
|
||||
boost::log::core::get()->add_sink(boost::make_shared<boost::log::sinks::synchronous_sink<
|
||||
boost::log::sinks::syslog_backend>>(backend));
|
||||
}
|
||||
|
||||
severity_ = severity;
|
||||
initialized_ = true;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "anbox/ui/splash_screen.h"
|
||||
#include "anbox/config.h"
|
||||
#include "anbox/utils.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
|
|
@ -44,9 +45,15 @@ SplashScreen::SplashScreen() {
|
|||
SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee));
|
||||
SDL_UpdateWindowSurface(window_);
|
||||
|
||||
auto renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not create renderer"));
|
||||
auto renderer = SDL_GetRenderer(window_);
|
||||
if (!renderer) {
|
||||
DEBUG("Window has no associated renderer yet, creating one ...");
|
||||
renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer) {
|
||||
const auto msg = utils::string_format("Could not create renderer: %s", SDL_GetError());
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(msg));
|
||||
}
|
||||
}
|
||||
|
||||
const auto icon_path = utils::string_format("%s/ui/loading-screen.png", SystemConfiguration::instance().resource_dir());
|
||||
auto img = IMG_LoadTexture(renderer, icon_path.c_str());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue