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) var errLogicalDrives error
errChan := make(chan error) retChan := make(chan PartitionStat)
lpBuffer := make([]byte, 254) quitChan := make(chan struct{})
defer close(quitChan)
var waitgrp sync.WaitGroup
waitgrp.Add(1) getPartitions := func() {
defer waitgrp.Done() 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,27 +147,37 @@ 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()
select {
case err := <-errChan: var ret []PartitionStat
return ret, err for {
case ret := <-retChan: select {
return ret, warnings.Reference() case p, ok := <-retChan:
case <-ctx.Done(): if !ok {
return ret, ctx.Err() if errLogicalDrives != nil {
return ret, errLogicalDrives
}
return ret, warnings.Reference()
}
ret = append(ret, p)
case <-ctx.Done():
return ret, ctx.Err()
}
} }
} }

Loading…
Cancel
Save