Skip to content

Commit e0ec016

Browse files
committed
app: Add respawn rate limiting to prevent CPU spinning
When a non-client app with AutoRestart enabled exits immediately after starting, the restart logic would loop without delay, causing high CPU usage. This adds a 60-second rate limit to gsm_app_restart. If an app respawns twice within this window, the second restart is rejected. The code is adapted from: - https://gitlab.gnome.org/GNOME/gnome-session/-/commit/4df48234 - https://gitlab.gnome.org/GNOME/gnome-session/-/commit/b9aa675e Fixes #336
1 parent 6c53bde commit e0ec016

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

mate-session/gsm-app.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@
3030
#include "gsm-app.h"
3131
#include "org.gnome.SessionManager.App.h"
3232

33+
/* If a component crashes twice within a minute, we count that as a fatal error */
34+
#define _GSM_APP_RESPAWN_RATELIMIT_SECONDS 60
35+
3336
typedef struct {
3437
char *id;
3538
char *app_id;
3639
int phase;
3740
char *startup_id;
41+
gint64 last_restart_time;
3842
GDBusConnection *connection;
3943
GsmExportedApp *skeleton;
4044
} GsmAppPrivate;
@@ -522,9 +526,24 @@ gsm_app_restart (GsmApp *app,
522526
GError **error)
523527
{
524528
GsmAppPrivate *priv;
529+
gint64 current_time;
525530

526531
priv = gsm_app_get_instance_private (app);
527532

533+
current_time = g_get_real_time ();
534+
535+
if (priv->last_restart_time > 0
536+
&& (current_time - priv->last_restart_time) < _GSM_APP_RESPAWN_RATELIMIT_SECONDS * G_USEC_PER_SEC) {
537+
g_warning ("App '%s' respawning too quickly", priv->app_id ? priv->app_id : priv->id);
538+
g_set_error (error,
539+
GSM_APP_ERROR,
540+
GSM_APP_ERROR_GENERAL,
541+
"Component '%s' crashing too quickly",
542+
priv->app_id ? priv->app_id : priv->id);
543+
return FALSE;
544+
}
545+
priv->last_restart_time = current_time;
546+
528547
g_debug ("Re-starting app: %s", priv->id);
529548

530549
return GSM_APP_GET_CLASS (app)->impl_restart (app, error);

0 commit comments

Comments
 (0)