mirror of https://github.com/shirou/gopsutil
fix: optimize performance of process.OpenFiles()
parent
ce7e4c88d9
commit
81edea074a
@ -0,0 +1,51 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var bufferPool = sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
b := make([]byte, syscall.PathMax)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following three functions are copied from stdlib.
|
||||||
|
|
||||||
|
// ignoringEINTR2 is ignoringEINTR, but returning an additional value.
|
||||||
|
func ignoringEINTR2[T any](fn func() (T, error)) (T, error) {
|
||||||
|
for {
|
||||||
|
v, err := fn()
|
||||||
|
if !errors.Is(err, syscall.EINTR) {
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Many functions in package syscall return a count of -1 instead of 0.
|
||||||
|
// Using fixCount(call()) instead of call() corrects the count.
|
||||||
|
func fixCount(n int, err error) (int, error) {
|
||||||
|
if n < 0 {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Readlink behaves like os.Readlink but caches the buffer passed to syscall.Readlink.
|
||||||
|
func Readlink(name string) (string, error) {
|
||||||
|
b := bufferPool.Get().(*[]byte)
|
||||||
|
defer bufferPool.Put(b)
|
||||||
|
|
||||||
|
n, err := ignoringEINTR2(func() (int, error) {
|
||||||
|
return fixCount(syscall.Readlink(name, *b))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", &os.PathError{Op: "readlink", Path: name, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string((*b)[:n]), nil
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
/foo
|
@ -0,0 +1 @@
|
|||||||
|
/bar
|
@ -0,0 +1 @@
|
|||||||
|
/baz
|
Loading…
Reference in New Issue