From 26c0b77f5009e57230b1d4505c5d76c3336a0386 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 14 May 2019 11:11:17 +0200 Subject: Enforce minimum delay for RPC actions if user is active --- src/main.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 4291b54..3501f5a 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #define CAP_SLEEP(newval) do { if ( (newval) < sleepTime ) sleepTime = (newval); } while (0) static time_t lastActivity; +static int userCount; // Tracked user sessions #define USERS (50) @@ -96,7 +97,7 @@ int main( int argc, char **argv ) for ( ;; ) { int sleepTime = defaultSleep; const int count = getUserList( users, USERS ); - int minIdleTime = -1; + userCount = count; for ( idx = 0; idx < count; ++idx ) { struct user * const usr = &users[idx]; if ( !usr->mark ) { @@ -178,10 +179,6 @@ int main( int argc, char **argv ) } //printf( "Have User %d: %s Locked %d (%+d) Idle %d (%+d) -- Leader: %d\n", idx, usr->user, (int)usr->lockTime, usr->lockTimeOffset, (int)usr->lastActivity, usr->lastActivityOffset, (int)usr->sessionLeader ); const int idleTime = NOW - usr->lastActivity; - // Min of all sessions - if ( idleTime >= 0 && idleTime < minIdleTime ) { - minIdleTime = idleTime; - } // See if we need to shorten sleep time for a pending session kill // or warn the user about an imminent session kill // or whether the screen saver is supposed to activate @@ -201,6 +198,7 @@ int main( int argc, char **argv ) } usr->logoutTime = NOW + remaining; } + // Update timestamp of last use of system const time_t laMono = monoNOW - idleTime; if ( laMono > lastActivity ) { lastActivity = laMono; @@ -251,7 +249,7 @@ int main( int argc, char **argv ) } } } - if ( nextAction.deadline != 0 && ( count == 0 || minIdleTime >= config.minIdle || nextAction.force ) ) { + if ( nextAction.deadline != 0 && ( count == 0 || ( monoNOW - lastActivity ) >= config.minIdle || nextAction.force ) ) { // Some action seems pending const int remaining = nextAction.deadline - monoNOW; if ( remaining < -60 ) { @@ -282,7 +280,7 @@ int main( int argc, char **argv ) // Handle requests rpcHandle( listenFd ); // Might have set a new scheduled action - if ( nextAction.deadline != 0 && ( count == 0 || minIdleTime >= config.minIdle || nextAction.force ) ) { + if ( nextAction.deadline != 0 && nextAction.force ) { int delta = nextAction.deadline - monoNOW; CAP_SLEEP( delta ); } @@ -516,11 +514,27 @@ struct user* main_getUser( const char *terminal ) return NULL; } +/** + * Called from RPC, only by root: Set the next action (but only + * if it's sooner than anything already pending) + */ void main_queueAction( enum Shutdown action, int delta ) { if ( delta < 0 || action < 0 || action >= SHUTDOWN_ENUM_END ) return; time_t monoNOW = now(); + if ( userCount != 0 ) { + int idleTime = monoNOW - lastActivity; + if ( idleTime < 3600 ) { + if ( delta < 306 ) { + delta = 306; + } + } else if ( idleTime < 7200 ) { + if ( delta < 66 ) { + delta = 66; + } + } + } if ( nextAction.deadline == 0 || ( nextAction.deadline - monoNOW - 3 ) > delta ) { // Engage nextAction.deadline = monoNOW + delta; -- cgit v1.2.3-55-g7522