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  }