Skip to content

Commit

Permalink
fix: delay loop once charging is disabled before sleep
Browse files Browse the repository at this point in the history
to prevent the main loop from re-enabling it

use time.Tick to refactor sleep-loop
  • Loading branch information
charlie0129 committed Apr 5, 2023
1 parent da9c905 commit d76d3b3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func send(method string, path string, data string) (string, error) {
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
conn, err := net.Dial("unix", unixSocketPath)
if err != nil {
logrus.Errorf("failed to connect to unix socket, do you have adequate permissions? Is the daemon running?")
logrus.Errorf("failed to connect to unix socket. 1) Do you have adequate permissions? Please re-run as root. 2) Is the daemon running? Have installed it?")
return nil, err
}
return conn, err
Expand Down
4 changes: 1 addition & 3 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ func runDaemon() {
go func() {
logrus.Infof("main loop starts")

//nolint:revive // not empty
for mainLoop() {
}
mainLoop()

logrus.Errorf("main loop exited unexpectedly")
}()
Expand Down
52 changes: 22 additions & 30 deletions loop.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
package main

import (
"sync"
"sync/atomic"
"time"

"github.com/sirupsen/logrus"
)

var (
maintainedChargingInProgress = false
maintainLoopLock = &sync.Mutex{}
maintainTick = time.NewTicker(time.Second * time.Duration(config.LoopIntervalSeconds))
skipLoop = &atomic.Bool{}
)

func mainLoop() bool {
defer time.Sleep(time.Second * time.Duration(config.LoopIntervalSeconds))

return maintainLoop()
}

func checkMaintainedChargingStatus() {
maintain := config.Limit < 100
if maintain {
maintainedChargingInProgress = false
}

isChargingEnabled, err := smcConn.IsChargingEnabled()
if err != nil {
logrus.Errorf("IsChargingEnabled failed: %v", err)
return
func mainLoop() {
for range maintainTick.C {
maintainLoop()
}
}

isPluggedIn, err := smcConn.IsPluggedIn()
if err != nil {
logrus.Errorf("IsPluggedIn failed: %v", err)
return
}
func maintainLoop() bool {
maintainLoopLock.Lock()
defer maintainLoopLock.Unlock()

if isChargingEnabled && isPluggedIn {
maintainedChargingInProgress = true
} else {
maintainedChargingInProgress = false
if skipLoop.Load() {
logrus.Debugln("maintainLoop skipped")
return true
}
}

func maintainLoop() bool {
limit := config.Limit
maintain := limit < 100

Expand Down Expand Up @@ -69,7 +57,11 @@ func maintainLoop() bool {
return false
}

checkMaintainedChargingStatus()
if isChargingEnabled && isPluggedIn {
maintainedChargingInProgress = true
} else {
maintainedChargingInProgress = false
}

logrus.Debugf("batteryCharge=%d, limit=%d, chargingEnabled=%t, isPluggedIn=%t, maintainedChargingInProgress=%t",
batteryCharge,
Expand All @@ -80,7 +72,7 @@ func maintainLoop() bool {
)

if batteryCharge < limit && !isChargingEnabled {
logrus.Infof("battery charge (%d) below limit (%d), enable charging...",
logrus.Infof("battery charge (%d) below limit (%d) but charging is disabled, enabling charging",
batteryCharge,
limit,
)
Expand All @@ -93,7 +85,7 @@ func maintainLoop() bool {
}

if batteryCharge > limit && isChargingEnabled {
logrus.Infof("battery charge (%d) above limit (%d), disable charging...",
logrus.Infof("battery charge (%d) above limit (%d) but charging is enabled, disabling charging",
batteryCharge,
limit,
)
Expand Down
19 changes: 19 additions & 0 deletions sleepcallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import "C"

import (
"fmt"
"time"

"github.com/sirupsen/logrus"
)

var (
delayNextLoopSeconds = 60
)

//export canSystemSleepCallback
func canSystemSleepCallback() {
/* Idle sleep is about to kick in. This message will not be sent for forced sleep.
Expand Down Expand Up @@ -64,6 +69,20 @@ func systemWillSleepCallback() {

if maintainedChargingInProgress {
logrus.Info("system is going to sleep, but maintained charging is in progress, disabling charging just before sleep")
// Delay next loop to prevent charging to be re-enabled after we disabled it.
// macOS will wait 30s before going to sleep, so we delay double that time (60s), just to be sure.
// no need to prevent duplicated runs.
logrus.Debugf("delaying next loop by %d seconds", delayNextLoopSeconds)
skipLoop.Store(true)
go func() {
<-time.After(time.Duration(delayNextLoopSeconds) * time.Second)
if skipLoop.Load() {
logrus.Debug("previously stopped loop re-started")
skipLoop.Store(false)
} else {
logrus.Debug("previously stopped loop already re-started")
}
}()
err := smcConn.DisableCharging()
if err != nil {
logrus.Errorf("DisableCharging failed: %v", err)
Expand Down

0 comments on commit d76d3b3

Please sign in to comment.