返回 DeepSeek-Reasonix
tabs_layout_queue.go
根目录 / desktop / tabs_layout_queue.go
1 package main
2
3 import (
4 "sync"
5 "time"
6 )
7
8 type tabLayoutSave struct {
9 dir string
10 entries []desktopTabEntry
11 activeID string
12 version uint64
13 }
14
15 // Only rebuildable navigation layout is coalesced. Session durability barriers
16 // remain synchronous in SetActiveTab and are never owned by this queue.
17 type tabLayoutWriter struct {
18 mu sync.Mutex
19 pending *tabLayoutSave
20 done chan struct{}
21 flush chan struct{}
22 }
23
24 func (a *App) queueTabLayoutSave(dir string, entries []desktopTabEntry, activeID string, version uint64) {
25 q := &a.desktopSessions.layoutWrites
26 q.mu.Lock()
27 if a.shuttingDown.Load() {
28 q.mu.Unlock()
29 return
30 }
31 if q.pending == nil || version >= q.pending.version {
32 q.pending = &tabLayoutSave{dir, entries, activeID, version}
33 }
34 if q.done != nil {
35 q.mu.Unlock()
36 return
37 }
38 q.done, q.flush = make(chan struct{}), make(chan struct{}, 1)
39 flush := q.flush
40 q.mu.Unlock()
41 go func() {
42 timer := time.NewTimer(25 * time.Millisecond)
43 defer timer.Stop()
44 select {
45 case <-timer.C:
46 case <-flush:
47 }
48 for {
49 q.mu.Lock()
50 next := q.pending
51 q.pending = nil
52 if next == nil {
53 close(q.done)
54 q.done, q.flush = nil, nil
55 q.mu.Unlock()
56 return
57 }
58 q.mu.Unlock()
59 a.saveTabsWrite(next.dir, next.entries, next.activeID, next.version)
60 }
61 }()
62 }
63
64 func (a *App) queueCurrentTabLayout() {
65 a.mu.Lock()
66 dir, entries, activeID, version := a.saveTabsCollectLocked()
67 a.mu.Unlock()
68 a.queueTabLayoutSave(dir, entries, activeID, version)
69 }
70
71 func (a *App) flushTabLayoutWrites() {
72 q := &a.desktopSessions.layoutWrites
73 q.mu.Lock()
74 done := q.done
75 if done != nil {
76 select {
77 case q.flush <- struct{}{}:
78 default:
79 }
80 }
81 q.mu.Unlock()
82 if done != nil {
83 <-done
84 }
85 }
86
86 lines GO