summaryrefslogtreecommitdiffhomepage
path: root/metrics/fds_linux.go
blob: 34740c2bb1c74918ddd09229f777f221d6c6abda (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause

package metrics

import (
	"io/fs"
	"sync"

	"go4.org/mem"
	"tailscale.com/util/dirwalk"
)

// counter is a reusable counter for counting file descriptors.
type counter struct {
	n int

	// cb is the (*counter).count method value. Creating it allocates,
	// so we have to save it away and use a sync.Pool to keep currentFDs
	// amortized alloc-free.
	cb func(name mem.RO, de fs.DirEntry) error
}

var counterPool = &sync.Pool{New: func() any {
	c := new(counter)
	c.cb = c.count
	return c
}}

func (c *counter) count(name mem.RO, de fs.DirEntry) error {
	c.n++
	return nil
}

func currentFDs() int {
	c := counterPool.Get().(*counter)
	defer counterPool.Put(c)
	c.n = 0
	dirwalk.WalkShallow(mem.S("/proc/self/fd"), c.cb)
	return c.n
}