fix: fixed windows disk package leaks

- fixed goroutine leak in PartitionsWithContext
- closed registry handle in init
pull/1501/head
Ozan HACIBEKİROĞLU 2 years ago
parent 3bddb2a785
commit 1ed7ea75d7

@ -7,7 +7,6 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"sync"
"syscall" "syscall"
"unsafe" "unsafe"
@ -51,6 +50,7 @@ func init() {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\PartMgr`, registry.SET_VALUE) key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\PartMgr`, registry.SET_VALUE)
if err == nil { if err == nil {
key.SetDWordValue("EnableCounterForIoctl", 1) key.SetDWordValue("EnableCounterForIoctl", 1)
key.Close()
} }
} }
@ -86,28 +86,22 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
warnings := Warnings{ warnings := Warnings{
Verbose: true, Verbose: true,
} }
var ret []PartitionStat
retChan := make(chan []PartitionStat)
errChan := make(chan error)
lpBuffer := make([]byte, 254)
var waitgrp sync.WaitGroup var errLogicalDrives error
waitgrp.Add(1) retChan := make(chan PartitionStat)
defer waitgrp.Done() quitChan := make(chan struct{})
defer close(quitChan)
getPartitions := func() {
defer close(retChan)
f := func() { lpBuffer := make([]byte, 254)
defer func() {
waitgrp.Wait()
// fires when this func and the outside func finishes.
close(errChan)
close(retChan)
}()
diskret, _, err := procGetLogicalDriveStringsW.Call( diskret, _, err := procGetLogicalDriveStringsW.Call(
uintptr(len(lpBuffer)), uintptr(len(lpBuffer)),
uintptr(unsafe.Pointer(&lpBuffer[0]))) uintptr(unsafe.Pointer(&lpBuffer[0])))
if diskret == 0 { if diskret == 0 {
errChan <- err errLogicalDrives = err
return return
} }
for _, v := range lpBuffer { for _, v := range lpBuffer {
@ -153,28 +147,38 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
opts = append(opts, "compress") opts = append(opts, "compress")
} }
d := PartitionStat{ select {
case retChan <- PartitionStat{
Mountpoint: path, Mountpoint: path,
Device: path, Device: path,
Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)), Fstype: string(bytes.ReplaceAll(lpFileSystemNameBuffer, []byte("\x00"), []byte(""))),
Opts: opts, Opts: opts,
}:
case <-quitChan:
return
} }
ret = append(ret, d)
} }
} }
} }
retChan <- ret
} }
go f() go getPartitions()
var ret []PartitionStat
for {
select { select {
case err := <-errChan: case p, ok := <-retChan:
return ret, err if !ok {
case ret := <-retChan: if errLogicalDrives != nil {
return ret, errLogicalDrives
}
return ret, warnings.Reference() return ret, warnings.Reference()
}
ret = append(ret, p)
case <-ctx.Done(): case <-ctx.Done():
return ret, ctx.Err() return ret, ctx.Err()
} }
}
} }
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {

Loading…
Cancel
Save