mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
gtk: convert cgroup operations to gobject (#6009)
This commit is contained in:
@ -2,8 +2,12 @@
|
|||||||
/// each individual surface into its own cgroup.
|
/// each individual surface into its own cgroup.
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
const gio = @import("gio");
|
||||||
|
const glib = @import("glib");
|
||||||
|
const gobject = @import("gobject");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const c = @import("c.zig").c;
|
|
||||||
const App = @import("App.zig");
|
const App = @import("App.zig");
|
||||||
const internal_os = @import("../../os/main.zig");
|
const internal_os = @import("../../os/main.zig");
|
||||||
|
|
||||||
@ -15,8 +19,6 @@ const log = std.log.scoped(.gtk_systemd_cgroup);
|
|||||||
pub fn init(app: *App) ![]const u8 {
|
pub fn init(app: *App) ![]const u8 {
|
||||||
const pid = std.os.linux.getpid();
|
const pid = std.os.linux.getpid();
|
||||||
const alloc = app.core_app.alloc;
|
const alloc = app.core_app.alloc;
|
||||||
const connection = c.g_application_get_dbus_connection(@ptrCast(app.app)) orelse
|
|
||||||
return error.DbusConnectionRequired;
|
|
||||||
|
|
||||||
// Get our initial cgroup. We need this so we can compare
|
// Get our initial cgroup. We need this so we can compare
|
||||||
// and detect when we've switched to our transient group.
|
// and detect when we've switched to our transient group.
|
||||||
@ -29,7 +31,7 @@ pub fn init(app: *App) ![]const u8 {
|
|||||||
// Create our transient scope. If this succeeds then the unit
|
// Create our transient scope. If this succeeds then the unit
|
||||||
// was created, but we may not have moved into it yet, so we need
|
// was created, but we may not have moved into it yet, so we need
|
||||||
// to do a dumb busy loop to wait for the move to complete.
|
// to do a dumb busy loop to wait for the move to complete.
|
||||||
try createScope(connection);
|
try createScope(app, pid);
|
||||||
const transient = transient: while (true) {
|
const transient = transient: while (true) {
|
||||||
const current = try internal_os.cgroup.current(
|
const current = try internal_os.cgroup.current(
|
||||||
alloc,
|
alloc,
|
||||||
@ -110,9 +112,13 @@ fn enableControllers(alloc: Allocator, cgroup: []const u8) !void {
|
|||||||
///
|
///
|
||||||
/// On success this will return the name of the transient scope
|
/// On success this will return the name of the transient scope
|
||||||
/// cgroup prefix, allocated with the given allocator.
|
/// cgroup prefix, allocated with the given allocator.
|
||||||
fn createScope(connection: *c.GDBusConnection) !void {
|
fn createScope(app: *App, pid_: std.os.linux.pid_t) !void {
|
||||||
// Our pid that we will move into the cgroup
|
// FIXME: when app.app gets converted to gobject
|
||||||
const pid: c.guint32 = @intCast(std.os.linux.getpid());
|
const g_app: *gio.Application = @ptrCast(@alignCast(app.app));
|
||||||
|
const connection = g_app.getDbusConnection() orelse
|
||||||
|
return error.DbusConnectionRequired;
|
||||||
|
|
||||||
|
const pid: u32 = @intCast(pid_);
|
||||||
|
|
||||||
// The unit name needs to be unique. We use the pid for this.
|
// The unit name needs to be unique. We use the pid for this.
|
||||||
var name_buf: [256]u8 = undefined;
|
var name_buf: [256]u8 = undefined;
|
||||||
@ -122,70 +128,79 @@ fn createScope(connection: *c.GDBusConnection) !void {
|
|||||||
.{pid},
|
.{pid},
|
||||||
) catch unreachable;
|
) catch unreachable;
|
||||||
|
|
||||||
|
const builder_type = glib.VariantType.new("(ssa(sv)a(sa(sv)))");
|
||||||
|
defer glib.free(builder_type);
|
||||||
|
|
||||||
// Initialize our builder to build up our parameters
|
// Initialize our builder to build up our parameters
|
||||||
var builder: c.GVariantBuilder = undefined;
|
var builder: glib.VariantBuilder = undefined;
|
||||||
c.g_variant_builder_init(&builder, c.G_VARIANT_TYPE("(ssa(sv)a(sa(sv)))"));
|
builder.init(builder_type);
|
||||||
c.g_variant_builder_add(&builder, "s", name.ptr);
|
|
||||||
c.g_variant_builder_add(&builder, "s", "fail");
|
builder.add("s", name.ptr);
|
||||||
|
builder.add("s", "fail");
|
||||||
|
|
||||||
{
|
{
|
||||||
// Properties
|
// Properties
|
||||||
c.g_variant_builder_open(&builder, c.G_VARIANT_TYPE("a(sv)"));
|
const properties_type = glib.VariantType.new("a(sv)");
|
||||||
defer c.g_variant_builder_close(&builder);
|
defer glib.free(properties_type);
|
||||||
|
|
||||||
|
builder.open(properties_type);
|
||||||
|
defer builder.close();
|
||||||
|
|
||||||
// https://www.freedesktop.org/software/systemd/man/latest/systemd-oomd.service.html
|
// https://www.freedesktop.org/software/systemd/man/latest/systemd-oomd.service.html
|
||||||
c.g_variant_builder_add(
|
const pressure_value = glib.Variant.newString("kill");
|
||||||
&builder,
|
|
||||||
"(sv)",
|
builder.add("(sv)", "ManagedOOMMemoryPressure", pressure_value);
|
||||||
"ManagedOOMMemoryPressure",
|
|
||||||
c.g_variant_new_string("kill"),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Delegate
|
// Delegate
|
||||||
c.g_variant_builder_add(
|
const delegate_value = glib.Variant.newBoolean(1);
|
||||||
&builder,
|
builder.add("(sv)", "Delegate", delegate_value);
|
||||||
"(sv)",
|
|
||||||
"Delegate",
|
|
||||||
c.g_variant_new_boolean(1),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Pid to move into the unit
|
// Pid to move into the unit
|
||||||
c.g_variant_builder_add(
|
const pids_value_type = glib.VariantType.new("u");
|
||||||
&builder,
|
defer glib.free(pids_value_type);
|
||||||
"(sv)",
|
|
||||||
"PIDs",
|
const pids_value = glib.Variant.newFixedArray(pids_value_type, &pid, 1, @sizeOf(u32));
|
||||||
c.g_variant_new_fixed_array(
|
|
||||||
c.G_VARIANT_TYPE("u"),
|
builder.add("(sv)", "PIDs", pids_value);
|
||||||
&pid,
|
|
||||||
1,
|
|
||||||
@sizeOf(c.guint32),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// Aux
|
|
||||||
c.g_variant_builder_open(&builder, c.G_VARIANT_TYPE("a(sa(sv))"));
|
|
||||||
defer c.g_variant_builder_close(&builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var err: ?*c.GError = null;
|
{
|
||||||
defer if (err) |e| c.g_error_free(e);
|
// Aux
|
||||||
_ = c.g_dbus_connection_call_sync(
|
const aux_type = glib.VariantType.new("a(sa(sv))");
|
||||||
connection,
|
defer glib.free(aux_type);
|
||||||
|
|
||||||
|
builder.open(aux_type);
|
||||||
|
defer builder.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var err: ?*glib.Error = null;
|
||||||
|
defer if (err) |e| e.free();
|
||||||
|
|
||||||
|
const reply_type = glib.VariantType.new("(o)");
|
||||||
|
defer glib.free(reply_type);
|
||||||
|
|
||||||
|
const value = builder.end();
|
||||||
|
|
||||||
|
const reply = connection.callSync(
|
||||||
"org.freedesktop.systemd1",
|
"org.freedesktop.systemd1",
|
||||||
"/org/freedesktop/systemd1",
|
"/org/freedesktop/systemd1",
|
||||||
"org.freedesktop.systemd1.Manager",
|
"org.freedesktop.systemd1.Manager",
|
||||||
"StartTransientUnit",
|
"StartTransientUnit",
|
||||||
c.g_variant_builder_end(&builder),
|
value,
|
||||||
c.G_VARIANT_TYPE("(o)"),
|
reply_type,
|
||||||
c.G_DBUS_CALL_FLAGS_NONE,
|
.{},
|
||||||
-1,
|
-1,
|
||||||
null,
|
null,
|
||||||
&err,
|
&err,
|
||||||
) orelse {
|
) orelse {
|
||||||
if (err) |e| log.err(
|
if (err) |e| log.err(
|
||||||
"creating transient cgroup scope failed code={} err={s}",
|
"creating transient cgroup scope failed code={} err={s}",
|
||||||
.{ e.code, e.message },
|
.{
|
||||||
|
e.f_code,
|
||||||
|
if (e.f_message) |msg| msg else "(no message)",
|
||||||
|
},
|
||||||
);
|
);
|
||||||
return error.DbusCallFailed;
|
return error.DbusCallFailed;
|
||||||
};
|
};
|
||||||
|
defer reply.unref();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user