Add NonBlockingSave option for background saving

This feature introduces a new configuration option, `NonBlockingSave`, which allows background saving for large files. With this param the saving process will not block the main thread with all network sockets.
By default, it's enabled for the DosBox core.
This commit is contained in:
Sergey Stepanov 2024-08-07 20:20:21 +03:00
parent 1ff7be38eb
commit 466257d3be
No known key found for this signature in database
GPG key ID: A56B4929BAA8556B
4 changed files with 19 additions and 5 deletions

View file

@ -192,6 +192,7 @@ emulator:
# Some cores allow binding multiple devices to a single port (DosBox), but typically,
# you should bind just one device to one port.
# - kbMouseSupport (bool) -- (temp) a flag if the core needs the keyboard and mouse on the client
# - nonBlockingSave (bool) -- write save file in a non-blocking way, needed for huge save files
# - vfr (bool)
# (experimental)
# Enable variable frame rate only for cores that can't produce a constant frame rate.
@ -271,6 +272,7 @@ emulator:
roms: [ "zip", "cue" ]
folder: dos
kbMouseSupport: true
nonBlockingSave: true
hid:
0: [ 257, 513 ]
1: [ 257, 513 ]

View file

@ -50,6 +50,7 @@ type LibretroCoreConfig struct {
IsGlAllowed bool
KbMouseSupport bool
Lib string
NonBlockingSave bool
Options map[string]string
Options4rom map[string]map[string]string // <(^_^)>
Roms []string

View file

@ -158,6 +158,7 @@ func (f *Frontend) LoadCore(emu string) {
scale = conf.Scale
f.log.Debug().Msgf("Scale: x%v", scale)
}
f.storage.SetNonBlocking(conf.NonBlockingSave)
f.scale = scale
f.nano.CoreLoad(meta)
f.mu.Unlock()

View file

@ -13,6 +13,7 @@ type (
GetSavePath() string
GetSRAMPath() string
SetMainSaveName(name string)
SetNonBlocking(v bool)
Load(path string) ([]byte, error)
Save(path string, data []byte) error
}
@ -24,17 +25,26 @@ type (
// needed for Google Cloud save/restore which
// doesn't support multiple files
MainSave string
NonBlock bool
}
ZipStorage struct {
Storage
}
)
func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name }
func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") }
func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") }
func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) }
func (s *StateStorage) Save(path string, dat []byte) error { return os.WriteFile(path, dat, 0644) }
func (s *StateStorage) SetMainSaveName(name string) { s.MainSave = name }
func (s *StateStorage) SetNonBlocking(v bool) { s.NonBlock = v }
func (s *StateStorage) GetSavePath() string { return filepath.Join(s.Path, s.MainSave+".dat") }
func (s *StateStorage) GetSRAMPath() string { return filepath.Join(s.Path, s.MainSave+".srm") }
func (s *StateStorage) Load(path string) ([]byte, error) { return os.ReadFile(path) }
func (s *StateStorage) Save(path string, dat []byte) error {
if s.NonBlock {
go func() { _ = os.WriteFile(path, dat, 0644) }()
return nil
}
return os.WriteFile(path, dat, 0644)
}
func (z *ZipStorage) GetSavePath() string { return z.Storage.GetSavePath() + zip.Ext }
func (z *ZipStorage) GetSRAMPath() string { return z.Storage.GetSRAMPath() + zip.Ext }