Skip to content

Commit 771aab2

Browse files
committed
save+backup: Process the save & backup with a sequential channel
As advantage we don't need to synchonize them any longer and don't need further insufficient lock mechanisms.
1 parent 35d295d commit 771aab2

2 files changed

Lines changed: 50 additions & 25 deletions

File tree

internal/buffer/backup.go

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import (
66
"io/fs"
77
"os"
88
"path/filepath"
9-
"sync/atomic"
10-
"time"
119

1210
"github.com/zyedidia/micro/v2/internal/config"
1311
"github.com/zyedidia/micro/v2/internal/screen"
@@ -34,27 +32,7 @@ The backup was created on %s and its path is:
3432
3533
Options: [r]ecover, [i]gnore, [a]bort: `
3634

37-
var backupRequestChan chan *Buffer
38-
39-
func backupThread() {
40-
for {
41-
time.Sleep(time.Second * 8)
42-
43-
for len(backupRequestChan) > 0 {
44-
b := <-backupRequestChan
45-
bfini := atomic.LoadInt32(&(b.fini)) != 0
46-
if !bfini {
47-
b.Backup()
48-
}
49-
}
50-
}
51-
}
52-
53-
func init() {
54-
backupRequestChan = make(chan *Buffer, 10)
55-
56-
go backupThread()
57-
}
35+
const backupSeconds = 8
5836

5937
func (b *Buffer) RequestBackup() {
6038
if !b.requestedBackup {

internal/buffer/save.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"runtime"
14+
"sync/atomic"
15+
"time"
1416
"unicode"
1517

1618
"github.com/zyedidia/micro/v2/internal/config"
@@ -32,6 +34,48 @@ type wrappedFile struct {
3234
sigChan chan os.Signal
3335
}
3436

37+
type saveResponse struct {
38+
size int
39+
err error
40+
}
41+
42+
type saveRequest struct {
43+
buf *Buffer
44+
path string
45+
withSudo bool
46+
newFile bool
47+
saveResponseChan chan saveResponse
48+
}
49+
50+
var saveRequestChan chan saveRequest
51+
var backupRequestChan chan *Buffer
52+
53+
func init() {
54+
saveRequestChan = make(chan saveRequest, 10)
55+
backupRequestChan = make(chan *Buffer, 10)
56+
57+
go func() {
58+
duration := backupSeconds * float64(time.Second)
59+
backupTicker := time.NewTicker(time.Duration(duration))
60+
61+
for {
62+
select {
63+
case sr := <-saveRequestChan:
64+
size, err := sr.buf.safeWrite(sr.path, sr.withSudo, sr.newFile)
65+
sr.saveResponseChan <- saveResponse{size, err}
66+
case <-backupTicker.C:
67+
for len(backupRequestChan) > 0 {
68+
b := <-backupRequestChan
69+
bfini := atomic.LoadInt32(&(b.fini)) != 0
70+
if !bfini {
71+
b.Backup()
72+
}
73+
}
74+
}
75+
}
76+
}()
77+
}
78+
3579
func openFile(name string, withSudo bool) (wrappedFile, error) {
3680
var err error
3781
var writeCloser io.WriteCloser
@@ -267,13 +311,16 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error
267311
}
268312
}
269313

270-
size, err := b.safeWrite(absFilename, withSudo, newFile)
314+
saveResponseChan := make(chan saveResponse)
315+
saveRequestChan <- saveRequest{b, absFilename, withSudo, newFile, saveResponseChan}
316+
result := <-saveResponseChan
317+
err = result.err
271318
if err != nil {
272319
return err
273320
}
274321

275322
if !b.Settings["fastdirty"].(bool) {
276-
if size > LargeFileThreshold {
323+
if result.size > LargeFileThreshold {
277324
// For large files 'fastdirty' needs to be on
278325
b.Settings["fastdirty"] = true
279326
} else {

0 commit comments

Comments
 (0)