github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/observer_list.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "sync" 9 10 "github.com/keybase/client/go/kbfs/kbfsmd" 11 "github.com/keybase/client/go/kbfs/tlf" 12 "github.com/keybase/client/go/kbfs/tlfhandle" 13 "github.com/keybase/client/go/protocol/keybase1" 14 "golang.org/x/net/context" 15 ) 16 17 // observerList is a thread-safe list of observers. 18 type observerList struct { 19 lock sync.RWMutex 20 observers []Observer 21 } 22 23 func newObserverList() *observerList { 24 return &observerList{} 25 } 26 27 // It's the caller's responsibility to make sure add isn't called 28 // twice for the same Observer. 29 func (ol *observerList) add(o Observer) { 30 ol.lock.Lock() 31 defer ol.lock.Unlock() 32 ol.observers = append(ol.observers, o) 33 } 34 35 func (ol *observerList) remove(o Observer) { 36 ol.lock.Lock() 37 defer ol.lock.Unlock() 38 for i, oldObs := range ol.observers { 39 if oldObs == o { 40 ol.observers = append(ol.observers[:i], ol.observers[i+1:]...) 41 return 42 } 43 } 44 } 45 46 func (ol *observerList) localChange( 47 ctx context.Context, node Node, write WriteRange) { 48 ol.lock.RLock() 49 defer ol.lock.RUnlock() 50 for _, o := range ol.observers { 51 o.LocalChange(ctx, node, write) 52 } 53 } 54 55 func (ol *observerList) batchChanges( 56 ctx context.Context, changes []NodeChange, affectedNodeIDs []NodeID) { 57 ol.lock.RLock() 58 defer ol.lock.RUnlock() 59 for _, o := range ol.observers { 60 o.BatchChanges(ctx, changes, affectedNodeIDs) 61 } 62 } 63 64 func (ol *observerList) tlfHandleChange( 65 ctx context.Context, newHandle *tlfhandle.Handle) { 66 ol.lock.RLock() 67 defer ol.lock.RUnlock() 68 for _, o := range ol.observers { 69 o.TlfHandleChange(ctx, newHandle) 70 } 71 } 72 73 // syncedTlfObserverList is a thread-safe list of synced TLF observers. 74 type syncedTlfObserverList struct { 75 lock sync.RWMutex 76 observers []SyncedTlfObserver 77 } 78 79 func newSyncedTlfObserverList() *syncedTlfObserverList { 80 return &syncedTlfObserverList{} 81 } 82 83 // It's the caller's responsibility to make sure add isn't called 84 // twice for the same SyncedTlfObserver. 85 func (stol *syncedTlfObserverList) add(o SyncedTlfObserver) { 86 stol.lock.Lock() 87 defer stol.lock.Unlock() 88 stol.observers = append(stol.observers, o) 89 } 90 91 func (stol *syncedTlfObserverList) remove(o SyncedTlfObserver) { 92 stol.lock.Lock() 93 defer stol.lock.Unlock() 94 for i, oldObs := range stol.observers { 95 if oldObs == o { 96 stol.observers = append(stol.observers[:i], stol.observers[i+1:]...) 97 return 98 } 99 } 100 } 101 102 func (stol *syncedTlfObserverList) fullSyncStarted( 103 ctx context.Context, tlfID tlf.ID, rev kbfsmd.Revision, 104 waitCh <-chan struct{}) { 105 stol.lock.RLock() 106 defer stol.lock.RUnlock() 107 for _, o := range stol.observers { 108 o.FullSyncStarted(ctx, tlfID, rev, waitCh) 109 } 110 } 111 112 func (stol *syncedTlfObserverList) syncModeChanged( 113 ctx context.Context, tlfID tlf.ID, newMode keybase1.FolderSyncMode) { 114 stol.lock.RLock() 115 defer stol.lock.RUnlock() 116 for _, o := range stol.observers { 117 o.SyncModeChanged(ctx, tlfID, newMode) 118 } 119 }