sm-commit AT lists.ibiblio.org
Subject: Source Mage code commit list
List archive
[SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (25b2a8a8f56f443f1a5deb369e8c36ba7c6a5da0)
- From: Pavel Vinogradov <scm AT sourcemage.org>
- To: sm-commit AT lists.ibiblio.org
- Subject: [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (25b2a8a8f56f443f1a5deb369e8c36ba7c6a5da0)
- Date: Tue, 2 Jan 2024 00:07:00 +0000
GIT changes to master grimoire by Pavel Vinogradov <public AT sourcemage.org>:
http/firefox/HISTORY |
3
http/firefox/patches/0030-bmo-1743144-add-wayland-proxy-cache.patch |
936 ++++++++++
http/firefox/patches/0031-bgo-919418-ppc64-flac-decoder-unsupported.patch |
11
3 files changed, 950 insertions(+)
New commits:
commit 25b2a8a8f56f443f1a5deb369e8c36ba7c6a5da0
Author: Pavel Vinogradov <public AT sourcemage.org>
Commit: Pavel Vinogradov <public AT sourcemage.org>
http/firefox: updated patches for 121.0 once more
diff --git a/http/firefox/HISTORY b/http/firefox/HISTORY
index 7a73129..716a6f9 100644
--- a/http/firefox/HISTORY
+++ b/http/firefox/HISTORY
@@ -1,3 +1,6 @@
+2024-01-01 Pavel Vinogradov <public AT sourcemage.org>
+ * patches/*: updated
+
2023-12-21 Pavel Vinogradov <public AT sourcemage.org>
* patches/*: updated once again
diff --git
a/http/firefox/patches/0030-bmo-1743144-add-wayland-proxy-cache.patch
b/http/firefox/patches/0030-bmo-1743144-add-wayland-proxy-cache.patch
new file mode 100644
index 0000000..080afe7
--- /dev/null
+++ b/http/firefox/patches/0030-bmo-1743144-add-wayland-proxy-cache.patch
@@ -0,0 +1,936 @@
+diff -Naur a/third_party/wayland-proxy/moz.build
b/third_party/wayland-proxy/moz.build
+--- a/third_party/wayland-proxy/moz.build 1970-01-01 00:00:00.000000000
-0000
++++ b/third_party/wayland-proxy/moz.build 2023-12-27 07:11:03.708390110
-0000
+@@ -0,0 +1,16 @@
++# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++with Files("**"):
++ BUG_COMPONENT = ("Core", "Widget: Gtk")
++
++SOURCES += [
++ "wayland-proxy.cpp",
++]
++EXPORTS += [
++ "wayland-proxy.h",
++]
++FINAL_LIBRARY = "xul"
+diff -Naur a/third_party/wayland-proxy/wayland-proxy.cpp
b/third_party/wayland-proxy/wayland-proxy.cpp
+--- a/third_party/wayland-proxy/wayland-proxy.cpp 1970-01-01
00:00:00.000000000 -0000
++++ b/third_party/wayland-proxy/wayland-proxy.cpp 2023-12-27
07:11:03.708390110 -0000
+@@ -0,0 +1,731 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
++ * This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++// This code is based on Rust implementation at
++// https://github.com/the8472/weyland-p5000
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdarg.h>
++#include <sys/ioctl.h>
++#include <sys/socket.h>
++#include <sys/stat.h>
++#include <sys/wait.h>
++#include <sys/un.h>
++#include <spawn.h>
++#include <poll.h>
++#include <vector>
++#include <cerrno>
++#include <fcntl.h>
++#include <unistd.h>
++#include <memory>
++#include <cassert>
++#include <pthread.h>
++#include <sched.h>
++
++#include "wayland-proxy.h"
++
++// The maximum number of fds libwayland can recvmsg at once
++#define MAX_LIBWAY_FDS 28
++#define MAX_DATA_SIZE 4096
++#define POLL_TIMEOUT 30000
++
++// sockaddr_un has hardcoded max len of sun_path
++#define MAX_WAYLAND_DISPLAY_NAME_LEN 108
++
++// Name of Wayland display provided by compositor
++char sWaylandDisplay[MAX_WAYLAND_DISPLAY_NAME_LEN];
++
++// Name of Wayland display provided by us
++char sWaylandProxy[MAX_WAYLAND_DISPLAY_NAME_LEN];
++
++bool sPrintInfo = false;
++
++void Info(const char* aFormat, ...) {
++ if (!sPrintInfo) {
++ return;
++ }
++ va_list args;
++ va_start(args, aFormat);
++ vfprintf(stderr, aFormat, args);
++ va_end(args);
++}
++
++void Warning(const char* aOperation, bool aPrintErrno = true) {
++ fprintf(stderr, "Wayland Proxy warning: %s : %s\n", aOperation,
++ aPrintErrno ? strerror(errno) : "");
++}
++
++void Error(const char* aOperation, bool aPrintErrno = true) {
++ fprintf(stderr, "Wayland Proxy error: %s : %s\n", aOperation,
++ aPrintErrno ? strerror(errno) : "");
++}
++
++void ErrorPlain(const char* aFormat, ...) {
++ va_list args;
++ va_start(args, aFormat);
++ vfprintf(stderr, aFormat, args);
++ va_end(args);
++}
++
++class WaylandMessage {
++ public:
++ bool Write(int aSocket);
++
++ bool Loaded() { return mLoaded && (mFds.size() || mData.size()); }
++ bool Failed() { return mFailed; }
++
++ explicit WaylandMessage(int aSocket) { Read(aSocket); }
++ ~WaylandMessage();
++
++ private:
++ bool Read(int aSocket);
++
++ private:
++ bool mLoaded = false;
++ bool mFailed = false;
++
++ std::vector<int> mFds;
++ std::vector<byte> mData;
++};
++
++class ProxiedConnection {
++ public:
++ bool Init(int aChildSocket);
++
++ struct pollfd* AddToPollFd(struct pollfd* aPfds);
++ struct pollfd* LoadPollFd(struct pollfd* aPfds);
++
++ // Process this connection (send/receive data).
++ // Returns false if connection is broken and should be removed.
++ bool Process();
++
++ ~ProxiedConnection();
++
++ private:
++ // Try to connect to compositor. Returns false in case of fatal error.
++ bool ConnectToCompositor();
++
++ bool TransferOrQueue(
++ int aSourceSocket, int aSourcePollFlags, int aDestSocket,
++ std::vector<std::unique_ptr<WaylandMessage>>* aMessageQueue);
++ bool FlushQueue(int aDestSocket, int aDestPollFlags,
++ std::vector<std::unique_ptr<WaylandMessage>>&
aMessageQueue);
++
++ // We don't have connected compositor yet. Try to connect
++ bool mCompositorConnected = false;
++
++ // We're disconnected from app or compositor. We will close this
connection.
++ bool mFailed = false;
++
++ int mCompositorSocket = -1;
++ int mCompositorFlags = 0;
++
++ int mApplicationSocket = -1;
++ int mApplicationFlags = 0;
++
++ // Stored proxied data
++ std::vector<std::unique_ptr<WaylandMessage>> mToCompositorQueue;
++ std::vector<std::unique_ptr<WaylandMessage>> mToApplicationQueue;
++};
++
++WaylandMessage::~WaylandMessage() {
++ for (auto const fd : mFds) {
++ close(fd);
++ }
++}
++
++bool WaylandMessage::Read(int aSocket) {
++ // We don't expect WaylandMessage re-read
++ assert(!mLoaded && !mFailed);
++
++ mData.resize(MAX_DATA_SIZE);
++
++ struct msghdr msg = {0};
++ struct iovec iov = {mData.data(), mData.size()};
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++
++ char cmsgdata[(CMSG_LEN(MAX_LIBWAY_FDS * sizeof(int32_t)))] = {0};
++ msg.msg_control = &cmsgdata;
++ msg.msg_controllen = sizeof(cmsgdata);
++
++ ssize_t ret = recvmsg(aSocket, &msg, MSG_CMSG_CLOEXEC | MSG_DONTWAIT);
++ if (msg.msg_flags & (MSG_CTRUNC | MSG_TRUNC)) {
++ Error("WaylandMessage::Read() data truncated, small buffer?");
++ mFailed = true;
++ return false;
++ }
++
++ if (ret < 1) {
++ switch (errno) {
++ case EAGAIN:
++ case EINTR:
++ // Neither loaded nor failed, we'll try again later
++ Info("WaylandMessage::Write() failed %s\n", strerror(errno));
++ return false;
++ default:
++ Error("WaylandMessage::Write() failed");
++ mFailed = true;
++ return false;
++ }
++ }
++
++ // Set correct data size
++ mData.resize(ret);
++
++ // Read cmsg
++ struct cmsghdr* header = CMSG_FIRSTHDR(&msg);
++ while (header) {
++ struct cmsghdr* next = CMSG_NXTHDR(&msg, header);
++ if (header->cmsg_level != SOL_SOCKET || header->cmsg_type !=
SCM_RIGHTS) {
++ header = next;
++ continue;
++ }
++
++ int* data = (int*)CMSG_DATA(header);
++ int filenum = (int)((header->cmsg_len - CMSG_LEN(0)) / sizeof(int));
++ for (int i = 0; i < filenum; i++) {
++#ifdef DEBUG
++ int flags = fcntl(data[i], F_GETFL, 0);
++ if (flags == -1 && errno == EBADF) {
++ Error("WaylandMessage::Read() invalid fd");
++ }
++#endif
++ mFds.push_back(data[i]);
++ }
++ header = next;
++ }
++
++ mLoaded = true;
++ return true;
++}
++
++bool WaylandMessage::Write(int aSocket) {
++ if (!mLoaded || mFailed) {
++ return false;
++ }
++
++ struct msghdr msg = {0};
++ struct iovec iov = {mData.data(), mData.size()};
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++
++ int filenum = mFds.size();
++ if (filenum) {
++ if (filenum >= MAX_LIBWAY_FDS) {
++ Error("WaylandMessage::Write() too many files to send\n", false);
++ return false;
++ }
++#ifdef DEBUG
++ for (int i = 0; i < filenum; i++) {
++ int flags = fcntl(mFds[i], F_GETFL, 0);
++ if (flags == -1 && errno == EBADF) {
++ Error("WaylandMessage::Write() invalid fd\n");
++ }
++ }
++#endif
++ union {
++ char buf[CMSG_SPACE(sizeof(int) * MAX_LIBWAY_FDS)];
++ struct cmsghdr align;
++ } cmsgu;
++ memset(cmsgu.buf, 0, sizeof(cmsgu.buf));
++
++ msg.msg_control = cmsgu.buf;
++ msg.msg_controllen = sizeof(cmsgu.buf);
++ msg.msg_controllen = CMSG_SPACE(filenum * sizeof(int));
++
++ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
++ cmsg->cmsg_level = SOL_SOCKET;
++ cmsg->cmsg_type = SCM_RIGHTS;
++ cmsg->cmsg_len = CMSG_LEN(filenum * sizeof(int));
++ memcpy(CMSG_DATA(cmsg), mFds.data(), filenum * sizeof(int));
++ }
++
++ ssize_t ret = sendmsg(aSocket, &msg, MSG_CMSG_CLOEXEC | MSG_DONTWAIT);
++ if (ret < 1) {
++ switch (errno) {
++ case EAGAIN:
++ case EINTR:
++ // Neither loaded nor failed, we'll try again later
++ Info("WaylandMessage::Write() failed %s\n", strerror(errno));
++ return false;
++ default:
++ Warning("WaylandMessage::Write() failed");
++ mFailed = true;
++ return false;
++ }
++ }
++
++ if (ret != (ssize_t)mData.size()) {
++ Info("WaylandMessage::Write() failed to write all data! (%d vs. %d)\n",
ret,
++ mData.size());
++ }
++ return true;
++}
++
++ProxiedConnection::~ProxiedConnection() {
++ if (mCompositorSocket != -1) {
++ close(mCompositorSocket);
++ }
++ if (mApplicationSocket != -1) {
++ close(mApplicationSocket);
++ }
++}
++
++bool ProxiedConnection::Init(int aApplicationSocket) {
++ mApplicationSocket = aApplicationSocket;
++ mCompositorSocket =
++ socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
++ if (mCompositorSocket == -1) {
++ Error("ConnectToCompositor() socket()");
++ }
++ return mApplicationSocket > 0 && mCompositorSocket > 0;
++}
++
++struct pollfd* ProxiedConnection::AddToPollFd(struct pollfd* aPfds) {
++ // Listen application's requests
++ aPfds->fd = mApplicationSocket;
++ aPfds->events = POLLIN;
++
++ // We're connected and we have data for appplication from compositor.
++ // Add POLLOUT to request write to app socket.
++ if (mCompositorConnected && mToApplicationQueue.size()) {
++ aPfds->events |= POLLOUT;
++ }
++ aPfds++;
++
++ aPfds->fd = mCompositorSocket;
++ // We're waiting for connection or we have data for compositor
++ if (!mCompositorConnected || mToCompositorQueue.size()) {
++ aPfds->events |= POLLOUT;
++ }
++ if (mCompositorConnected) {
++ aPfds->events = POLLIN;
++ }
++ aPfds++;
++
++ return aPfds;
++}
++
++struct pollfd* ProxiedConnection::LoadPollFd(struct pollfd* aPfds) {
++ if (aPfds->fd != mApplicationSocket) {
++ return aPfds;
++ }
++ mApplicationFlags = aPfds->revents;
++ aPfds++;
++ mCompositorFlags = aPfds->revents;
++ aPfds++;
++ return aPfds;
++}
++
++bool ProxiedConnection::ConnectToCompositor() {
++ if (!(mCompositorFlags & POLLOUT)) {
++ // Try again later
++ return true;
++ }
++
++ struct sockaddr_un addr = {};
++ addr.sun_family = AF_UNIX;
++ strcpy(addr.sun_path, sWaylandDisplay);
++
++ mCompositorConnected =
++ connect(mCompositorSocket, (const struct sockaddr*)&addr,
++ sizeof(struct sockaddr_un)) != -1;
++ if (!mCompositorConnected) {
++ switch (errno) {
++ case EAGAIN:
++ case EALREADY:
++ case ECONNREFUSED:
++ case EINPROGRESS:
++ case EINTR:
++ case EISCONN:
++ case ETIMEDOUT:
++ // We can recover from these errors and try again
++ Warning("ConnectToCompositor() try again");
++ return true;
++ default:
++ Error("ConnectToCompositor() connect()");
++ return false;
++ }
++ }
++ return true;
++}
++
++// Read data from aSourceSocket and try to twite them to aDestSocket.
++// If data write fails, append them to aMessageQueue.
++// Return
++bool ProxiedConnection::TransferOrQueue(
++ int aSourceSocket, int aSourcePollFlags, int aDestSocket,
++ std::vector<std::unique_ptr<WaylandMessage>>* aMessageQueue) {
++ // Don't read if we don't have any data ready
++ if (!(aSourcePollFlags & POLLIN)) {
++ return true;
++ }
++
++ while (1) {
++ int availableData = 0;
++ if (ioctl(aSourceSocket, FIONREAD, &availableData) < 0) {
++ // Broken connection, we're finished here
++ Warning("ProxiedConnection::TransferOrQueue() broken source socket
%s\n");
++ return false;
++ }
++ if (availableData == 0) {
++ return true;
++ }
++
++ auto message = std::make_unique<WaylandMessage>(aSourceSocket);
++ if (message->Failed()) {
++ // Failed to read message due to error
++ return false;
++ }
++ if (!message->Loaded()) {
++ // Let's try again
++ return true;
++ }
++ if (!message->Write(aDestSocket)) {
++ if (message->Failed()) {
++ // Failed to write and we can't recover
++ return false;
++ }
++ aMessageQueue->push_back(std::move(message));
++ }
++ }
++}
++
++// Try to flush all data to aMessageQueue.
++bool ProxiedConnection::FlushQueue(
++ int aDestSocket, int aDestPollFlags,
++ std::vector<std::unique_ptr<WaylandMessage>>& aMessageQueue) {
++ // Can't write to destination yet
++ if (!(aDestPollFlags & POLLOUT)) {
++ return true;
++ }
++
++ while (aMessageQueue.size()) {
++ if (!aMessageQueue[0]->Write(aDestSocket)) {
++ return !aMessageQueue[0]->Failed();
++ }
++ aMessageQueue.erase(aMessageQueue.begin());
++ }
++ return true;
++}
++
++bool ProxiedConnection::Process() {
++ if (mFailed) {
++ return false;
++ }
++
++ // Check if appplication is still listening
++ if (mApplicationFlags & (POLLHUP | POLLERR)) {
++ return false;
++ }
++
++ // Check if compositor is still listening
++ if (mCompositorConnected) {
++ if (mCompositorFlags & (POLLHUP | POLLERR)) {
++ return false;
++ }
++ } else {
++ // Try to reconnect to compositor.
++ if (!ConnectToCompositor()) {
++ return false;
++ }
++ // We're not connected yet but ConnectToCompositor() didn't return
++ // fatal error. Try again later.
++ if (!mCompositorConnected) {
++ return true;
++ }
++ }
++
++ mFailed =
++ !TransferOrQueue(mCompositorSocket, mCompositorFlags,
mApplicationSocket,
++ &mToApplicationQueue) ||
++ !TransferOrQueue(mApplicationSocket, mApplicationFlags,
mCompositorSocket,
++ &mToCompositorQueue) ||
++ !FlushQueue(mCompositorSocket, mCompositorFlags, mToCompositorQueue)
||
++ !FlushQueue(mApplicationSocket, mApplicationFlags,
mToApplicationQueue);
++
++ return !mFailed;
++}
++
++bool WaylandProxy::SetupWaylandDisplays() {
++ char* waylandDisplay = getenv("WAYLAND_DISPLAY");
++ if (!waylandDisplay) {
++ Error("Init(), Missing Wayland display, WAYLAND_DISPLAY is empty.",
false);
++ return false;
++ }
++
++ char* XDGRuntimeDir = getenv("XDG_RUNTIME_DIR");
++ if (!XDGRuntimeDir) {
++ Error("Init() Missing XDG_RUNTIME_DIR", false);
++ return false;
++ }
++
++ // WAYLAND_DISPLAY can be absolute path
++ if (waylandDisplay[0] == '/') {
++ if (strlen(sWaylandDisplay) >= MAX_WAYLAND_DISPLAY_NAME_LEN) {
++ Error("Init() WAYLAND_DISPLAY is too large.", false);
++ return false;
++ }
++ strcpy(sWaylandDisplay, waylandDisplay);
++ } else {
++ int ret = snprintf(sWaylandDisplay, MAX_WAYLAND_DISPLAY_NAME_LEN,
"%s/%s",
++ XDGRuntimeDir, waylandDisplay);
++ if (ret < 0 || ret >= MAX_WAYLAND_DISPLAY_NAME_LEN) {
++ Error("Init() WAYLAND_DISPLAY/XDG_RUNTIME_DIR is too large.", false);
++ return false;
++ }
++ }
++ int ret = snprintf(sWaylandProxy, MAX_WAYLAND_DISPLAY_NAME_LEN,
++ "%s/wayland-proxy-%d", XDGRuntimeDir, getpid());
++ if (ret < 0 || ret >= MAX_WAYLAND_DISPLAY_NAME_LEN) {
++ Error("Init() WAYLAND_DISPLAY/XDG_RUNTIME_DIR is too large.", false);
++ return false;
++ }
++
++ return true;
++}
++
++bool WaylandProxy::StartProxyServer() {
++ mProxyServerSocket =
++ socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
++ if (mProxyServerSocket == -1) {
++ Error("StartProxyServer(): failed to create socket");
++ return false;
++ }
++
++ struct sockaddr_un serverName = {0};
++ serverName.sun_family = AF_UNIX;
++ strcpy(serverName.sun_path, sWaylandProxy);
++
++ if (bind(mProxyServerSocket, (struct sockaddr*)&serverName,
++ sizeof(serverName)) == -1) {
++ Error("StartProxyServer(): bind() error");
++ return false;
++ }
++ if (listen(mProxyServerSocket, 128) == -1) {
++ Error("StartProxyServer(): listen() error");
++ return false;
++ }
++
++ return true;
++}
++
++bool WaylandProxy::Init() {
++ if (!SetupWaylandDisplays()) {
++ return false;
++ }
++
++ if (!StartProxyServer()) {
++ return false;
++ }
++ return true;
++}
++
++void WaylandProxy::SetWaylandProxyDisplay() {
++ setenv("WAYLAND_DISPLAY", sWaylandProxy, true);
++}
++
++void WaylandProxy::SetWaylandDisplay() {
++ setenv("WAYLAND_DISPLAY", sWaylandDisplay, true);
++}
++
++bool WaylandProxy::IsChildAppTerminated() {
++ if (!mApplicationPID) {
++ return false;
++ }
++ int status = 0;
++ int ret = waitpid(mApplicationPID, &status, WNOHANG | WUNTRACED |
WCONTINUED);
++ if (ret == 0) {
++ return false;
++ }
++ if (ret == mApplicationPID) {
++ // Child application is terminated, so quit too.
++ return true;
++ }
++ bool terminate = (errno == ECHILD);
++ Error("IsChildAppTerminated: waitpid() error");
++ return terminate;
++}
++
++bool WaylandProxy::PollConnections() {
++ int nfds_max = mConnections.size() * 2 + 1;
++
++ struct pollfd pollfds[nfds_max];
++ struct pollfd* addedPollfd = pollfds;
++
++ for (auto const& connection : mConnections) {
++ addedPollfd = connection->AddToPollFd(addedPollfd);
++ }
++
++ // Add extra listening socket
++ addedPollfd->fd = mProxyServerSocket;
++ addedPollfd->events = POLLIN;
++ assert(addedPollfd < pollfds + nfds_max);
++
++ int nfds = (addedPollfd - pollfds) + 1;
++
++ while (1) {
++ int ret = poll(pollfds, nfds, POLL_TIMEOUT);
++ if (ret == 0) {
++ // No change on fds
++ continue;
++ } else if (ret > 0) {
++ // We have FD to read
++ break;
++ } else if (ret == -1) {
++ switch (errno) {
++ case EINTR:
++ case EAGAIN:
++ if (IsChildAppTerminated()) {
++ return false;
++ }
++ continue;
++ default:
++ Error("Run: poll() error");
++ return false;
++ }
++ }
++ }
++
++ struct pollfd* loadedPollfd = pollfds;
++ for (auto const& connection : mConnections) {
++ loadedPollfd = connection->LoadPollFd(loadedPollfd);
++ }
++
++ assert(loadedPollfd == addedPollfd);
++ assert(loadedPollfd < pollfds + nfds_max);
++
++ // Create a new connection if there's a new client waiting
++ if (loadedPollfd->revents & POLLIN) {
++ Info("WaylandProxy: new child connection\n");
++ int applicationSocket = accept4(loadedPollfd->fd, nullptr, nullptr,
++ SOCK_NONBLOCK | SOCK_CLOEXEC);
++ if (applicationSocket == -1) {
++ switch (errno) {
++ case EAGAIN:
++ case EINTR:
++ // Try again later
++ break;
++ default:
++ Error("Faild to accept connection from application");
++ return false;
++ }
++ } else {
++ auto connection = std::make_unique<ProxiedConnection>();
++ if (connection->Init(applicationSocket)) {
++ mConnections.push_back(std::move(connection));
++ }
++ }
++ }
++
++ return true;
++}
++
++bool WaylandProxy::ProcessConnections() {
++ std::vector<std::unique_ptr<ProxiedConnection>>::iterator connection;
++ for (connection = mConnections.begin(); connection !=
mConnections.end();) {
++ if (!(*connection)->Process()) {
++ Info("WaylandProxy: remove connection\n");
++ connection = mConnections.erase(connection);
++ if (!mConnections.size()) {
++ // We removed last connection - quit.
++ Info("WaylandProxy: removed last connection, quit\n");
++ return false;
++ }
++ } else {
++ connection++;
++ }
++ }
++ return true;
++}
++
++void WaylandProxy::Run() {
++ while (!IsChildAppTerminated() && PollConnections() &&
ProcessConnections())
++ ;
++}
++
++WaylandProxy::~WaylandProxy() {
++ Info("WaylandProxy terminated\n");
++ if (mThreadRunning) {
++ Info("WaylandProxy thread is still running, terminating.\n");
++ pthread_cancel(mThread);
++ pthread_join(mThread, nullptr);
++ }
++ unlink(sWaylandProxy);
++ if (mProxyServerSocket != -1) {
++ close(mProxyServerSocket);
++ }
++}
++
++void* WaylandProxy::RunProxyThread(WaylandProxy* aProxy) {
++#ifdef __linux__
++ pthread_setname_np(pthread_self(), "WaylandProxy");
++#endif
++ aProxy->Run();
++ aProxy->mThreadRunning = false;
++ Info("WaylandProxy thread exited\n");
++ return nullptr;
++}
++
++std::unique_ptr<WaylandProxy> WaylandProxy::Create() {
++ auto proxy = std::make_unique<WaylandProxy>();
++ if (!proxy->Init()) {
++ return nullptr;
++ }
++
++ Info("WaylandProxyCreated, display %s\n", sWaylandProxy);
++ return proxy;
++}
++
++bool WaylandProxy::RunChildApplication(char* argv[]) {
++ if (!argv[0]) {
++ Error("WaylandProxy::RunChildApplication: missing application to run",
false);
++ return false;
++ }
++
++ mApplicationPID = fork();
++ if (mApplicationPID == -1) {
++ Error("WaylandProxy::RunChildApplication: fork() error");
++ return false;
++ }
++ if (mApplicationPID == 0) {
++ SetWaylandProxyDisplay();
++ if (execv(argv[0], argv) == -1) {
++ ErrorPlain("WaylandProxy::RunChildApplication: failed to run %s error
%s\n", argv[0], strerror(errno));
++ exit(1);
++ }
++ }
++
++ Run();
++ return true;
++}
++
++bool WaylandProxy::RunThread() {
++ pthread_attr_t attr;
++ if (pthread_attr_init(&attr) != 0) {
++ return false;
++ }
++
++ sched_param param;
++ if (pthread_attr_getschedparam(&attr, ¶m) == 0) {
++ param.sched_priority = sched_get_priority_min(SCHED_RR);
++ pthread_attr_setschedparam(&attr, ¶m);
++ }
++
++ SetWaylandProxyDisplay();
++
++ mThreadRunning = pthread_create(&mThread, nullptr, (void*
(*)(void*))RunProxyThread, this) == 0;
++ if (!mThreadRunning) {
++ // If we failed to run proxy thread, set WAYLAND_DISPLAY back.
++ SetWaylandDisplay();
++ }
++
++ pthread_attr_destroy(&attr);
++ return mThreadRunning;
++}
++
++void WaylandProxy::SetVerbose(bool aVerbose) { sPrintInfo = aVerbose; }
+diff -Naur a/third_party/wayland-proxy/wayland-proxy.h
b/third_party/wayland-proxy/wayland-proxy.h
+--- a/third_party/wayland-proxy/wayland-proxy.h 1970-01-01
00:00:00.000000000 -0000
++++ b/third_party/wayland-proxy/wayland-proxy.h 2023-12-27
07:11:03.708390110 -0000
+@@ -0,0 +1,54 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
++ * This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++#ifndef _wayland_proxy_h_
++#define _wayland_proxy_h_
++
++#include <poll.h>
++#include <vector>
++#include <fcntl.h>
++#include <atomic>
++
++typedef unsigned char byte;
++
++class ProxiedConnection;
++
++class WaylandProxy {
++ public:
++
++ static std::unique_ptr<WaylandProxy> Create();
++
++ bool RunChildApplication(char* argv[]);
++ bool RunThread();
++
++ void SetWaylandDisplay();
++ void SetVerbose(bool aVerbose);
++
++ ~WaylandProxy();
++
++ private:
++ bool Init();
++ void Run();
++
++ void SetWaylandProxyDisplay();
++ static void* RunProxyThread(WaylandProxy* aProxy);
++
++ bool SetupWaylandDisplays();
++ bool StartProxyServer();
++ bool IsChildAppTerminated();
++
++ bool PollConnections();
++ bool ProcessConnections();
++
++ private:
++ // List of all Compositor <-> Application connections
++ std::vector<std::unique_ptr<ProxiedConnection>> mConnections;
++ int mProxyServerSocket = -1;
++ pid_t mApplicationPID = 0;
++ std::atomic<bool> mThreadRunning = false;
++ pthread_t mThread;
++};
++
++#endif // _wayland_proxy_h_
+diff -Naur a/toolkit/moz.configure b/toolkit/moz.configure
+--- a/toolkit/moz.configure 2023-12-11 20:42:21.000000000 -0000
++++ b/toolkit/moz.configure 2023-12-27 07:11:03.723390573 -0000
+@@ -534,6 +534,20 @@
+ set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
+ set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
+
++# Wayland proxy is used as load balancer between Firefox and Wayland
++# compositor.
++# ==============================================================
++option("--disable-wayland-proxy", help="Disable Wayland load balancer")
++
++
++@depends("--enable-wayland-proxy", when=toolkit_gtk_wayland)
++def wayland_proxy(value):
++ if value:
++ return True
++
++
++set_config("MOZ_WAYLAND_PROXY", wayland_proxy)
++set_define("MOZ_WAYLAND_PROXY", wayland_proxy)
+
+ # Hardware-accelerated video decode with VAAPI and V4L2 on Linux
+ # ==============================================================
+diff -Naur a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+--- a/toolkit/xre/nsAppRunner.cpp 2023-12-11 20:42:21.000000000 -0000
++++ b/toolkit/xre/nsAppRunner.cpp 2023-12-27 07:11:03.716390357 -0000
+@@ -341,12 +341,20 @@
+ # include <gdk/gdkwayland.h>
+ # include "mozilla/widget/nsWaylandDisplay.h"
+ # endif
++# ifdef MOZ_WAYLAND_PROXY
++# include "wayland-proxy.h"
++# endif
+ # ifdef MOZ_X11
+ # include <gdk/gdkx.h>
+ # endif /* MOZ_X11 */
+ #endif
+ #include "BinaryPath.h"
+
++#ifdef MOZ_LOGGING
++# include "mozilla/Logging.h"
++extern mozilla::LazyLogModule gWidgetWaylandLog;
++#endif /* MOZ_LOGGING */
++
+ #ifdef FUZZING
+ # include "FuzzerRunner.h"
+
+@@ -3668,6 +3676,9 @@
+ XREMain() = default;
+
+ ~XREMain() {
++#if defined(MOZ_WAYLAND_PROXY)
++ mWaylandProxy = nullptr;
++#endif
+ mScopedXPCOM = nullptr;
+ mAppData = nullptr;
+ }
+@@ -3687,6 +3698,9 @@
+ #if defined(MOZ_HAS_REMOTE)
+ RefPtr<nsRemoteService> mRemoteService;
+ #endif
++#if defined(MOZ_WAYLAND_PROXY)
++ std::unique_ptr<WaylandProxy> mWaylandProxy;
++#endif
+
+ UniquePtr<ScopedXPCOMStartup> mScopedXPCOM;
+ UniquePtr<XREAppData> mAppData;
+@@ -4707,6 +4721,21 @@
+ const char* display_name = nullptr;
+ bool saveDisplayArg = false;
+
++ bool waylandEnabled = IsWaylandEnabled();
++# ifdef MOZ_WAYLAND_PROXY
++ auto* proxyEnv = getenv("MOZ_DISABLE_WAYLAND_PROXY");
++ bool disableWaylandProxy = proxyEnv && *proxyEnv;
++ if (!disableWaylandProxy && XRE_IsParentProcess() && waylandEnabled) {
++ mWaylandProxy = WaylandProxy::Create();
++ mWaylandProxy->RunThread();
++# ifdef MOZ_LOGGING
++ if (MOZ_LOG_TEST(gWidgetWaylandLog, mozilla::LogLevel::Debug)) {
++ mWaylandProxy->SetVerbose(true);
++ }
++# endif
++ }
++# endif
++
+ // display_name is owned by gdk.
+ display_name = gdk_get_display_arg_name();
+ // if --display argument is given make sure it's
+@@ -4716,7 +4745,6 @@
+ saveDisplayArg = true;
+ }
+
+- bool waylandEnabled = IsWaylandEnabled();
+ // On Wayland disabled builds read X11 DISPLAY env exclusively
+ // and don't care about different displays.
+ if (!waylandEnabled && !display_name) {
+@@ -5919,6 +5947,11 @@
+ # ifdef MOZ_WAYLAND
+ WaylandDisplayRelease();
+ # endif
++# ifdef MOZ_WAYLAND_PROXY
++ if (mWaylandProxy) {
++ mWaylandProxy = nullptr;
++ }
++# endif
+ }
+ #endif
+
+diff -Naur a/widget/gtk/moz.build b/widget/gtk/moz.build
+--- a/widget/gtk/moz.build 2023-12-11 20:42:21.000000000 -0000
++++ b/widget/gtk/moz.build 2023-12-27 07:11:03.709390141 -0000
+@@ -25,6 +25,9 @@
+ if CONFIG["MOZ_WAYLAND"]:
+ DIRS += ["wayland", "mozwayland"]
+
++if CONFIG["MOZ_WAYLAND_PROXY"]:
++ DIRS += ["../../third_party/wayland-proxy"]
++
+ if CONFIG["MOZ_ENABLE_VAAPI"]:
+ DIRS += ["vaapitest"]
+
diff --git
a/http/firefox/patches/0031-bgo-919418-ppc64-flac-decoder-unsupported.patch
b/http/firefox/patches/0031-bgo-919418-ppc64-flac-decoder-unsupported.patch
new file mode 100644
index 0000000..660b1ff
--- /dev/null
+++
b/http/firefox/patches/0031-bgo-919418-ppc64-flac-decoder-unsupported.patch
@@ -0,0 +1,11 @@
+--- a/dom/media/flac/FlacDecoder.cpp 2023-11-23 07:59:17.466486168 -0500
++++ b/dom/media/flac/FlacDecoder.cpp 2023-11-23 08:00:49.048026379 -0500
+@@ -18,7 +18,7 @@
+ #elif defined(MOZ_FFMPEG)
+ RefPtr<PDMFactory> platform = new PDMFactory();
+ return StaticPrefs::media_flac_enabled() &&
+- (platform->SupportsMimeType("audio/flac"_ns) !=
media::DecodeSupport::Unsupported);
++ !(platform->SupportsMimeType("audio/flac"_ns).isEmpty());
+ #else
+ return false;
+ #endif
- [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (25b2a8a8f56f443f1a5deb369e8c36ba7c6a5da0), Pavel Vinogradov, 01/01/2024
Archive powered by MHonArc 2.6.24.