Bug 1890074 [Wayland] Implement wayland proxy state string r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D225484
This commit is contained in:
stransky 2024-10-14 13:14:48 +00:00
parent 34e65ae3e9
commit f291924657
3 changed files with 66 additions and 1 deletions

View File

@ -29,7 +29,22 @@
#include "wayland-proxy.h"
constexpr const char* stateFlags[] = {
"WP:E ",
"WP:D ",
"WP:RF ",
"WP:RT ",
"WP:CA ",
"WP:CR ",
"WP:AT ",
"WP:ACT ",
"WP:CPCA ",
"WP:CPCF ",
"WP:CPSF ",
};
CompositorCrashHandler WaylandProxy::sCompositorCrashHandler = nullptr;
std::atomic<unsigned> WaylandProxy::sProxyStateFlags = 0;
// The maximum number of fds libwayland can recvmsg at once
#define MAX_LIBWAY_FDS 28
@ -361,6 +376,7 @@ bool ProxiedConnection::ConnectToCompositor() {
mFailedCompositorConnections++;
if (mFailedCompositorConnections > sMaxFailedCompositorConnections) {
Error("ConnectToCompositor() connect() failed repeatedly");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_SOCKET_FAILED);
return false;
}
// We can recover from these errors and try again
@ -368,11 +384,13 @@ bool ProxiedConnection::ConnectToCompositor() {
return true;
default:
Error("ConnectToCompositor() connect()");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_SOCKET_FAILED);
return false;
}
}
Print("ConnectToCompositor() Connected to compositor\n");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_ATTACHED);
return true;
}
@ -486,6 +504,7 @@ bool ProxiedConnection::Process() {
// Check if appplication is still listening
if (mApplicationFlags & (POLLHUP | POLLERR)) {
Print("ProxiedConnection::Process(): Client socket is not listening\n");
WaylandProxy::AddState(WAYLAND_PROXY_APP_CONNECTION_FAILED);
mApplicationFailed = true;
return false;
}
@ -494,6 +513,7 @@ bool ProxiedConnection::Process() {
if (mCompositorConnected) {
if (mCompositorFlags & (POLLHUP | POLLERR)) {
Print("ProxiedConnection::Process(): Compositor socket is not listening\n");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_CONNECTION_FAILED);
mCompositorFailed = true;
return false;
}
@ -501,6 +521,7 @@ bool ProxiedConnection::Process() {
// Try to reconnect to compositor.
if (!ConnectToCompositor()) {
Error("ProxiedConnection::Process(): Failed to connect to compositor\n");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_CONNECTION_FAILED);
mCompositorFailed = true;
return false;
}
@ -515,6 +536,7 @@ bool ProxiedConnection::Process() {
&mToApplicationQueue, mStatRecvFromCompositor,
mStatSentToClient)) {
Error("ProxiedConnection::Process(): Failed to read data from compositor!");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_CONNECTION_FAILED);
mCompositorFailed = true;
return false;
}
@ -522,18 +544,21 @@ bool ProxiedConnection::Process() {
&mToCompositorQueue, mStatRecvFromClient,
mStatSentToCompositor)) {
Error("ProxiedConnection::Process(): Failed to read data from client!");
WaylandProxy::AddState(WAYLAND_PROXY_APP_CONNECTION_FAILED);
mApplicationFailed = true;
return false;
}
if (!FlushQueue(mCompositorSocket, mCompositorFlags, mToCompositorQueue,
mStatSentToCompositorLater)) {
Error("ProxiedConnection::Process(): Failed to flush queue to compositor!");
WaylandProxy::AddState(WAYLAND_PROXY_COMPOSITOR_CONNECTION_FAILED);
mCompositorFailed = true;
return false;
}
if (!FlushQueue(mApplicationSocket, mApplicationFlags, mToApplicationQueue,
mStatSentToClientLater)) {
Error("ProxiedConnection::Process(): Failed to flush queue to client!");
WaylandProxy::AddState(WAYLAND_PROXY_APP_CONNECTION_FAILED);
mApplicationFailed = true;
return false;
}
@ -719,6 +744,7 @@ bool WaylandProxy::IsChildAppTerminated() {
}
if (ret == mApplicationPID) {
// Child application is terminated, so quit too.
WaylandProxy::AddState(WAYLAND_PROXY_APP_TERMINATED);
return true;
}
bool terminate = (errno == ECHILD);
@ -798,6 +824,7 @@ bool WaylandProxy::PollConnections() {
} else {
auto connection = std::make_unique<ProxiedConnection>();
if (connection->Init(applicationSocket, mWaylandDisplay)) {
WaylandProxy::AddState(WAYLAND_PROXY_CONNECTION_ADDED);
mConnections.push_back(std::move(connection));
}
}
@ -810,6 +837,7 @@ bool WaylandProxy::ProcessConnections() {
std::vector<std::unique_ptr<ProxiedConnection>>::iterator connection;
for (connection = mConnections.begin(); connection != mConnections.end();) {
if (!(*connection)->Process()) {
WaylandProxy::AddState(WAYLAND_PROXY_CONNECTION_REMOVED);
(*connection)->ProcessFailure();
connection = mConnections.erase(connection);
if (mConnections.empty()) {
@ -839,6 +867,7 @@ void WaylandProxy::Run() {
break;
}
}
WaylandProxy::AddState(WAYLAND_PROXY_TERMINATED);
}
WaylandProxy::~WaylandProxy() {
@ -919,6 +948,7 @@ bool WaylandProxy::RunThread() {
ErrorPlain("WaylandProxy::RunThread(): pthread_create() failed\n");
// If we failed to run proxy thread, set WAYLAND_DISPLAY back.
RestoreWaylandDisplay();
WaylandProxy::AddState(WAYLAND_PROXY_RUN_FAILED);
}
pthread_attr_destroy(&attr);
@ -965,3 +995,18 @@ void WaylandProxy::CompositorCrashed() {
sCompositorCrashHandler();
}
}
void WaylandProxy::AddState(unsigned aState) {
sProxyStateFlags.fetch_or(aState, std::memory_order_relaxed);
}
const char* WaylandProxy::GetState() {
std::string stateString;
unsigned state = sProxyStateFlags.load(std::memory_order_relaxed);
for (unsigned i = 0, flag = 1; i < sizeof(stateFlags); i++, flag <<= 1) {
if (state & flag) {
stateString.append(stateFlags[i]);
}
}
return strdup(stateString.c_str());
}

View File

@ -16,6 +16,18 @@ class ProxiedConnection;
typedef void (*CompositorCrashHandler)();
#define WAYLAND_PROXY_ENABLED (1 << 0)
#define WAYLAND_PROXY_DISABLED (1 << 1)
#define WAYLAND_PROXY_RUN_FAILED (1 << 2)
#define WAYLAND_PROXY_TERMINATED (1 << 3)
#define WAYLAND_PROXY_CONNECTION_ADDED (1 << 4)
#define WAYLAND_PROXY_CONNECTION_REMOVED (1 << 5)
#define WAYLAND_PROXY_APP_TERMINATED (1 << 6)
#define WAYLAND_PROXY_APP_CONNECTION_FAILED (1 << 7)
#define WAYLAND_PROXY_COMPOSITOR_ATTACHED (1 << 8)
#define WAYLAND_PROXY_COMPOSITOR_CONNECTION_FAILED (1 << 9)
#define WAYLAND_PROXY_COMPOSITOR_SOCKET_FAILED (1 << 10)
class WaylandProxy {
public:
static std::unique_ptr<WaylandProxy> Create();
@ -34,6 +46,8 @@ class WaylandProxy {
static void SetVerbose(bool aVerbose);
static void SetCompositorCrashHandler(CompositorCrashHandler aCrashHandler);
static void CompositorCrashed();
static void AddState(unsigned aState);
static const char* GetState();
~WaylandProxy();
@ -75,6 +89,7 @@ class WaylandProxy {
char mWaylandProxy[sMaxDisplayNameLen];
static CompositorCrashHandler sCompositorCrashHandler;
static std::atomic<unsigned> sProxyStateFlags;
};
#endif // _wayland_proxy_h_

View File

@ -4752,10 +4752,15 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
auto* proxyLog = getenv("WAYLAND_PROXY_LOG");
WaylandProxy::SetVerbose(proxyLog && *proxyLog);
WaylandProxy::SetCompositorCrashHandler(WlCompositorCrashHandler);
WaylandProxy::AddState(WAYLAND_PROXY_ENABLED);
gWaylandProxy = WaylandProxy::Create();
if (gWaylandProxy) {
gWaylandProxy->RunThread();
if (!gWaylandProxy->RunThread()) {
Output(true, "Failed to run Wayland proxy\n");
}
}
} else {
WaylandProxy::AddState(WAYLAND_PROXY_DISABLED);
}
}
# endif