Files
FlClash/core/platform/limit.go
T
chen08209 db6f5d9036 refactor: rebuild core, providers, and application interface
Changelog: Rebuilt the core, provider, and application layers
Changelog-Type: feat
2026-08-28 10:07:17 +08:00

75 lines
1.4 KiB
Go

//go:build android && cgo
package platform
import (
"sync/atomic"
"syscall"
"time"
"github.com/metacubex/mihomo/log"
)
const fdPressureWindow = 10 * time.Millisecond
var nullFd = -1
var maxFdCount int
var (
lastProbeAt atomic.Int64
lastProbeBlocked atomic.Bool
)
func init() {
// This runs while the shared library is being loaded, so a panic here takes
// the application down before it has a chance to report anything. The probe
// is a safety valve against fd exhaustion rather than something correctness
// depends on, so a failure to arm it degrades to never blocking.
fd, err := syscall.Open("/dev/null", syscall.O_WRONLY, 0644)
if err != nil {
log.Errorln("[APP] fd pressure probe disabled: %v", err)
return
}
nullFd = fd
var limit syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
maxFdCount = 1024
} else {
maxFdCount = int(limit.Cur)
}
maxFdCount = maxFdCount / 4 * 3
}
func ShouldBlockConnection() bool {
if nullFd < 0 {
return false
}
now := time.Now().UnixNano()
if !lastProbeBlocked.Load() {
if last := lastProbeAt.Load(); last != 0 && now-last < int64(fdPressureWindow) {
return false
}
}
blocked := probeFdPressure()
lastProbeBlocked.Store(blocked)
lastProbeAt.Store(now)
return blocked
}
func probeFdPressure() bool {
fd, err := syscall.Dup(nullFd)
if err != nil {
return true
}
_ = syscall.Close(fd)
return fd > maxFdCount
}