Synchronize virtfs rdwr state

This commit is contained in:
Ollie Agent 2026-08-18 06:48:34 +02:00
parent c0ce185051
commit 562e1ef780
1 changed files with 28 additions and 10 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"sync"
) )
// BuildTree walks an FsNodeDecl spec and produces a *Tree. // BuildTree walks an FsNodeDecl spec and produces a *Tree.
@ -257,31 +258,48 @@ func openLeaf(d *FsNodeDecl, uid, gid string, mode os.FileMode, name string) (Fi
isStreaming = true isStreaming = true
case d.Rdwr != nil: case d.Rdwr != nil:
fn := d.Rdwr fn := d.Rdwr
var stateMu sync.Mutex
var writeMu sync.Mutex
var result []byte var result []byte
var reqCtx context.Context
var reqCancel context.CancelFunc var reqCancel context.CancelFunc
blockFn = notBlocking blockFn = notBlocking
readFn = func() ([]byte, error) { readFn = func() ([]byte, error) {
stateMu.Lock()
if result != nil { if result != nil {
return result, nil out := make([]byte, len(result))
copy(out, result)
stateMu.Unlock()
return out, nil
} }
stateMu.Unlock()
if d.Read != nil { if d.Read != nil {
return d.Read() return d.Read()
} }
return nil, nil return nil, nil
} }
writeFn = func(data []byte) error { writeFn = func(data []byte) error {
reqCtx, reqCancel = context.WithCancel(context.Background()) writeMu.Lock()
r, err := fn(reqCtx, data) defer writeMu.Unlock()
if err != nil { ctx, cancel := context.WithCancel(context.Background())
return err stateMu.Lock()
reqCancel = cancel
stateMu.Unlock()
r, err := fn(ctx, data)
stateMu.Lock()
reqCancel = nil
if err == nil {
result = append(result[:0], r...)
} }
result = r stateMu.Unlock()
return nil cancel()
return err
} }
closeFn := func() error { closeFn := func() error {
if reqCancel != nil { stateMu.Lock()
reqCancel() cancel := reqCancel
stateMu.Unlock()
if cancel != nil {
cancel()
} }
return nil return nil
} }