mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-03 21:56:06 +00:00
ipc/android: Refactor and cleanup IPC glue code
This commit is contained in:
parent
3bb151e4bf
commit
9339e6022f
|
@ -65,7 +65,6 @@ public class MonadoImpl extends IMonado.Stub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connect(@NotNull ParcelFileDescriptor parcelFileDescriptor) {
|
public void connect(@NotNull ParcelFileDescriptor parcelFileDescriptor) {
|
||||||
nativeWaitForServerStartup();
|
|
||||||
int fd = parcelFileDescriptor.getFd();
|
int fd = parcelFileDescriptor.getFd();
|
||||||
Log.i(TAG, "connect: given fd " + fd);
|
Log.i(TAG, "connect: given fd " + fd);
|
||||||
if (nativeAddClient(fd) != 0) {
|
if (nativeAddClient(fd) != 0) {
|
||||||
|
@ -115,12 +114,6 @@ public class MonadoImpl extends IMonado.Stub {
|
||||||
@SuppressWarnings("JavaJniMissingFunction")
|
@SuppressWarnings("JavaJniMissingFunction")
|
||||||
private native void nativeStartServer();
|
private native void nativeStartServer();
|
||||||
|
|
||||||
/**
|
|
||||||
* Native method that waits until the server reports that it is, in fact, started up.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("JavaJniMissingFunction")
|
|
||||||
private native void nativeWaitForServerStartup();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native handling of receiving a surface: should convert it to an ANativeWindow then do stuff
|
* Native handling of receiving a surface: should convert it to an ANativeWindow then do stuff
|
||||||
* with it.
|
* with it.
|
||||||
|
|
|
@ -21,78 +21,113 @@
|
||||||
|
|
||||||
#include "android/android_globals.h"
|
#include "android/android_globals.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
using wrap::android::view::Surface;
|
using wrap::android::view::Surface;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct IpcServerHelper
|
struct IpcServerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IpcServerHelper() {}
|
static IpcServerHelper &
|
||||||
|
instance()
|
||||||
void
|
|
||||||
waitForStartupComplete()
|
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock{running_mutex};
|
static IpcServerHelper instance;
|
||||||
running_cond.wait(lock, [&]() { return this->startup_complete; });
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
signalStartupComplete()
|
signalStartupComplete()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock{running_mutex};
|
std::unique_lock<std::mutex> lock{server_mutex};
|
||||||
startup_complete = true;
|
startup_complete = true;
|
||||||
running_cond.notify_all();
|
startup_cond.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
startServer()
|
||||||
|
{
|
||||||
|
std::unique_lock lock(server_mutex);
|
||||||
|
if (!server && !server_thread) {
|
||||||
|
server_thread = std::make_unique<std::thread>(
|
||||||
|
[&]() { ipc_server_main_android(&server, signalStartupCompleteTrampoline, this); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
signalStartupCompleteTrampoline(void *data)
|
||||||
|
{
|
||||||
|
static_cast<IpcServerHelper *>(data)->signalStartupComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
addClient(int fd)
|
||||||
|
{
|
||||||
|
if (!waitForStartupComplete()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ipc_server_mainloop_add_fd(server, &server->ml, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
shutdownServer()
|
||||||
|
{
|
||||||
|
if (!server || !server_thread) {
|
||||||
|
// Should not happen.
|
||||||
|
U_LOG_E("service: shutdownServer called before server started up!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Wait until IPC server stop
|
||||||
|
std::unique_lock lock(server_mutex);
|
||||||
|
ipc_server_handle_shutdown_signal(server);
|
||||||
|
server_thread->join();
|
||||||
|
server_thread.reset(nullptr);
|
||||||
|
server = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
IpcServerHelper() {}
|
||||||
|
|
||||||
|
bool
|
||||||
|
waitForStartupComplete()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock{server_mutex};
|
||||||
|
return startup_cond.wait_for(lock, 2s, [&]() { return server != NULL && startup_complete; });
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Reference to the ipc_server, managed by ipc_server_process
|
||||||
|
struct ipc_server *server = NULL;
|
||||||
|
|
||||||
//! Mutex for starting thread
|
//! Mutex for starting thread
|
||||||
std::mutex running_mutex;
|
std::mutex server_mutex;
|
||||||
|
|
||||||
|
//! Server thread
|
||||||
|
std::unique_ptr<std::thread> server_thread{};
|
||||||
|
|
||||||
//! Condition variable for starting thread
|
//! Condition variable for starting thread
|
||||||
std::condition_variable running_cond;
|
std::condition_variable startup_cond;
|
||||||
|
|
||||||
|
//! Server startup state
|
||||||
bool startup_complete = false;
|
bool startup_complete = false;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
static struct ipc_server *server = NULL;
|
|
||||||
static IpcServerHelper *helper = nullptr;
|
|
||||||
static std::condition_variable helper_ready;
|
|
||||||
static std::unique_ptr<std::thread> server_thread{};
|
|
||||||
static std::mutex server_thread_mutex;
|
|
||||||
|
|
||||||
static void
|
|
||||||
signalStartupCompleteTrampoline(void *data)
|
|
||||||
{
|
|
||||||
static_cast<IpcServerHelper *>(data)->signalStartupComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
Java_org_freedesktop_monado_ipc_MonadoImpl_nativeStartServer(JNIEnv *env, jobject thiz)
|
Java_org_freedesktop_monado_ipc_MonadoImpl_nativeStartServer(JNIEnv *env, jobject thiz)
|
||||||
{
|
{
|
||||||
jni::init(env);
|
jni::init(env);
|
||||||
jni::Object monadoImpl(thiz);
|
jni::Object monadoImpl(thiz);
|
||||||
U_LOG_D("service: Called nativeThreadEntry");
|
U_LOG_D("service: Called nativeStartServer");
|
||||||
|
|
||||||
{
|
IpcServerHelper::instance().startServer();
|
||||||
// Start IPC server
|
|
||||||
std::unique_lock lock(server_thread_mutex);
|
|
||||||
if (!server && !server_thread) {
|
|
||||||
helper = new IpcServerHelper();
|
|
||||||
helper_ready.notify_all();
|
|
||||||
server_thread = std::make_unique<std::thread>(
|
|
||||||
[]() { ipc_server_main_android(&server, signalStartupCompleteTrampoline, helper); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_org_freedesktop_monado_ipc_MonadoImpl_nativeWaitForServerStartup(JNIEnv *env, jobject thiz)
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(server_thread_mutex);
|
|
||||||
helper_ready.wait(lock, [&] { return helper != nullptr; });
|
|
||||||
helper->waitForStartupComplete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
@ -101,13 +136,9 @@ Java_org_freedesktop_monado_ipc_MonadoImpl_nativeAddClient(JNIEnv *env, jobject
|
||||||
jni::init(env);
|
jni::init(env);
|
||||||
jni::Object monadoImpl(thiz);
|
jni::Object monadoImpl(thiz);
|
||||||
U_LOG_D("service: Called nativeAddClient with fd %d", fd);
|
U_LOG_D("service: Called nativeAddClient with fd %d", fd);
|
||||||
if (server == nullptr) {
|
|
||||||
// Should not happen.
|
|
||||||
U_LOG_E("service: nativeAddClient called before service started up!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// We try pushing the fd number to the server. If and only if we get a 0 return, has the server taken ownership.
|
// We try pushing the fd number to the server. If and only if we get a 0 return, has the server taken ownership.
|
||||||
return ipc_server_mainloop_add_fd(server, &server->ml, fd);
|
return IpcServerHelper::instance().addClient(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
@ -127,22 +158,6 @@ Java_org_freedesktop_monado_ipc_MonadoImpl_nativeShutdownServer(JNIEnv *env, job
|
||||||
{
|
{
|
||||||
jni::init(env);
|
jni::init(env);
|
||||||
jni::Object monadoImpl(thiz);
|
jni::Object monadoImpl(thiz);
|
||||||
if (server == nullptr || !server_thread) {
|
|
||||||
// Should not happen.
|
|
||||||
U_LOG_E("service: nativeShutdownServer called before service started up!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
return IpcServerHelper::instance().shutdownServer();
|
||||||
// Wait until IPC server stop
|
|
||||||
std::unique_lock lock(server_thread_mutex);
|
|
||||||
ipc_server_handle_shutdown_signal(server);
|
|
||||||
server_thread->join();
|
|
||||||
server_thread.reset(nullptr);
|
|
||||||
delete helper;
|
|
||||||
helper = nullptr;
|
|
||||||
server = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue