MCPcopy Create free account
hub / github.com/containers/image / queueOrCommit

Method queueOrCommit

storage/storage_dest.go:890–938  ·  view source on GitHub ↗

queueOrCommit queues the specified layer to be committed to the storage. If no other goroutine is already committing layers, the layer and all subsequent layers (if already queued) will be committed to the storage.

(index int, info addedLayerInfo)

Source from the content-addressed store, hash-verified

888// If no other goroutine is already committing layers, the layer and all
889// subsequent layers (if already queued) will be committed to the storage.
890func (s *storageImageDestination) queueOrCommit(index int, info addedLayerInfo) error {
891 // NOTE: whenever the code below is touched, make sure that all code
892 // paths unlock the lock and to unlock it exactly once.
893 //
894 // Conceptually, the code is divided in two stages:
895 //
896 // 1) Queue in work by marking the layer as ready to be committed.
897 // If at least one previous/parent layer with a lower index has
898 // not yet been committed, return early.
899 //
900 // 2) Process the queued-in work by committing the "ready" layers
901 // in sequence. Make sure that more items can be queued-in
902 // during the comparatively I/O expensive task of committing a
903 // layer.
904 //
905 // The conceptual benefit of this design is that caller can continue
906 // pulling layers after an early return. At any given time, only one
907 // caller is the "worker" routine committing layers. All other routines
908 // can continue pulling and queuing in layers.
909 s.lock.Lock()
910 s.lockProtected.indexToAddedLayerInfo[index] = info
911
912 // We're still waiting for at least one previous/parent layer to be
913 // committed, so there's nothing to do.
914 if index != s.lockProtected.currentIndex {
915 s.lock.Unlock()
916 return nil
917 }
918
919 for {
920 info, ok := s.lockProtected.indexToAddedLayerInfo[index]
921 if !ok {
922 break
923 }
924 s.lock.Unlock()
925 // Note: commitLayer locks on-demand.
926 if stopQueue, err := s.commitLayer(index, info, -1); stopQueue || err != nil {
927 return err
928 }
929 s.lock.Lock()
930 index++
931 }
932
933 // Set the index at the very end to make sure that only one routine
934 // enters stage 2).
935 s.lockProtected.currentIndex = index
936 s.lock.Unlock()
937 return nil
938}
939
940// commitLayer commits the specified layer with the given index to the storage.
941// size can usually be -1; it can be provided if the layer is not known to be already present in blobDiffIDs.

Callers 3

PutBlobWithOptionsMethod · 0.95
PutBlobPartialMethod · 0.95

Calls 1

commitLayerMethod · 0.95

Tested by

no test coverage detected