Refactor.

This commit is contained in:
Nuno Cruces
2023-01-23 14:00:37 +00:00
parent b9369d5544
commit 2fd2a4062c
2 changed files with 49 additions and 36 deletions

20
vfs.go
View File

@@ -133,6 +133,9 @@ func vfsDelete(ctx context.Context, mod api.Module, pVfs, zPath, syncDir uint32)
}
func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath, flags, pResOut uint32) uint32 {
// Consider using [syscall.Access] for [ACCESS_READWRITE]/[ACCESS_READ]
// (as the Unix VFS does).
path := getString(mod.Memory(), zPath, _MAX_PATHNAME)
fi, err := os.Stat(path)
@@ -192,11 +195,11 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile, flags, pOu
return uint32(CANTOPEN)
}
id, err := vfsGetFileID(file)
id, err := vfsGetOpenFileID(file)
if err != nil {
return uint32(CANTOPEN)
}
vfsSetFileData(mod, pFile, id, _NO_LOCK)
vfsFilePtr{mod, pFile}.SetID(id).SetLock(_NO_LOCK)
if pOutFlags == 0 {
return _OK
@@ -208,7 +211,8 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile, flags, pOu
}
func vfsClose(ctx context.Context, mod api.Module, pFile uint32) uint32 {
err := vfsReleaseFile(mod, pFile)
id := vfsFilePtr{mod, pFile}.ID()
err := vfsReleaseOpenFile(id)
if err != nil {
return uint32(IOERR_CLOSE)
}
@@ -221,7 +225,7 @@ func vfsRead(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOfs
panic(rangeErr)
}
file := vfsGetOSFile(mod, pFile)
file := vfsFilePtr{mod, pFile}.OSFile()
n, err := file.ReadAt(mem, int64(iOfst))
if n == int(iAmt) {
return _OK
@@ -241,7 +245,7 @@ func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOf
panic(rangeErr)
}
file := vfsGetOSFile(mod, pFile)
file := vfsFilePtr{mod, pFile}.OSFile()
_, err := file.WriteAt(mem, int64(iOfst))
if err != nil {
return uint32(IOERR_WRITE)
@@ -250,7 +254,7 @@ func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOf
}
func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64) uint32 {
file := vfsGetOSFile(mod, pFile)
file := vfsFilePtr{mod, pFile}.OSFile()
err := file.Truncate(int64(nByte))
if err != nil {
return uint32(IOERR_TRUNCATE)
@@ -259,7 +263,7 @@ func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64
}
func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 {
file := vfsGetOSFile(mod, pFile)
file := vfsFilePtr{mod, pFile}.OSFile()
err := file.Sync()
if err != nil {
return uint32(IOERR_FSYNC)
@@ -270,7 +274,7 @@ func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 {
func vfsFileSize(ctx context.Context, mod api.Module, pFile, pSize uint32) uint32 {
// This uses [file.Seek] because we don't care about the offset for reading/writing.
// But consider using [file.Stat] instead (as other VFSes do).
file := vfsGetOSFile(mod, pFile)
file := vfsFilePtr{mod, pFile}.OSFile()
off, err := file.Seek(0, io.SeekEnd)
if err != nil {
return uint32(IOERR_SEEK)

View File

@@ -15,18 +15,18 @@ type vfsOpenFile struct {
}
var (
vfsMutex sync.Mutex
vfsOpenFiles []*vfsOpenFile
vfsOpenFiles []*vfsOpenFile
vfsOpenFilesMtx sync.Mutex
)
func vfsGetFileID(file *os.File) (uint32, error) {
func vfsGetOpenFileID(file *os.File) (uint32, error) {
fi, err := file.Stat()
if err != nil {
return 0, err
}
vfsMutex.Lock()
defer vfsMutex.Unlock()
vfsOpenFilesMtx.Lock()
defer vfsOpenFilesMtx.Unlock()
// Reuse an already opened file.
for id, of := range vfsOpenFiles {
@@ -62,14 +62,9 @@ func vfsGetFileID(file *os.File) (uint32, error) {
return uint32(id), nil
}
func vfsReleaseFile(mod api.Module, pFile uint32) error {
id, ok := mod.Memory().ReadUint32Le(pFile + ptrSize)
if !ok {
panic(rangeErr)
}
vfsMutex.Lock()
defer vfsMutex.Unlock()
func vfsReleaseOpenFile(id uint32) error {
vfsOpenFilesMtx.Lock()
defer vfsOpenFilesMtx.Unlock()
of := vfsOpenFiles[id]
if of.nref--; of.nref > 0 {
@@ -80,32 +75,46 @@ func vfsReleaseFile(mod api.Module, pFile uint32) error {
return err
}
func vfsGetOSFile(mod api.Module, pFile uint32) *os.File {
id, ok := mod.Memory().ReadUint32Le(pFile + ptrSize)
if !ok {
panic(rangeErr)
}
type vfsFilePtr struct {
api.Module
ptr uint32
}
func (p vfsFilePtr) OSFile() *os.File {
id := p.ID()
vfsOpenFilesMtx.Lock()
defer vfsOpenFilesMtx.Unlock()
return vfsOpenFiles[id].file
}
func vfsGetFileData(mod api.Module, pFile uint32) (id, lock uint32) {
var ok bool
if id, ok = mod.Memory().ReadUint32Le(pFile + ptrSize); !ok {
func (p vfsFilePtr) ID() uint32 {
id, ok := p.Memory().ReadUint32Le(p.ptr + ptrSize)
if !ok {
panic(rangeErr)
}
if lock, ok = mod.Memory().ReadUint32Le(pFile + 2*ptrSize); !ok {
panic(rangeErr)
}
return
return id
}
func vfsSetFileData(mod api.Module, pFile, id, lock uint32) {
if ok := mod.Memory().WriteUint32Le(pFile+ptrSize, id); !ok {
func (p vfsFilePtr) Lock() uint32 {
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*ptrSize)
if !ok {
panic(rangeErr)
}
if ok := mod.Memory().WriteUint32Le(pFile+2*ptrSize, lock); !ok {
return lk
}
func (p vfsFilePtr) SetID(id uint32) vfsFilePtr {
if ok := p.Memory().WriteUint32Le(p.ptr+ptrSize, id); !ok {
panic(rangeErr)
}
return p
}
func (p vfsFilePtr) SetLock(lock uint32) vfsFilePtr {
if ok := p.Memory().WriteUint32Le(p.ptr+2*ptrSize, lock); !ok {
panic(rangeErr)
}
return p
}
const (