kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/platform/kcd/locked/locked.go (about) 1 /* 2 * Copyright 2016 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Package locked implements a delegating wrapper that protects each method of 18 // the resulting kcd.Reader or kcd.ReadWriter with a mutex, so that the result 19 // is safe for concurrent use by multiple goroutines. 20 package locked // import "kythe.io/kythe/go/platform/kcd/locked" 21 22 import ( 23 "context" 24 "errors" 25 "io" 26 "sync" 27 28 "kythe.io/kythe/go/platform/kcd" 29 ) 30 31 type locker struct { 32 μ sync.Mutex 33 rd kcd.Reader 34 wr kcd.Writer 35 del kcd.Deleter 36 } 37 38 // Reader returns a kcd.Reader that delegates to r with method calls protected 39 // by a mutex. 40 func Reader(r kcd.Reader) kcd.Reader { return &locker{rd: r} } 41 42 // ReadWriter returns a kcd.ReadWriter that delegates to rw with method calls 43 // protected by a mutex. 44 func ReadWriter(rw kcd.ReadWriter) kcd.ReadWriter { return &locker{rd: rw, wr: rw} } 45 46 // ReadWriteDeleter returns a kcd.ReadWriteDeleter that delegates to rwd with 47 // method calls protected by a mutex. 48 func ReadWriteDeleter(rwd kcd.ReadWriteDeleter) kcd.ReadWriteDeleter { 49 return &locker{rd: rwd, wr: rwd, del: rwd} 50 } 51 52 // ErrNotSupported is returned by the write methods if no Writer is available. 53 var ErrNotSupported = errors.New("write operation not supported") 54 55 // Revisions implements a method of kcd.Reader. 56 func (db *locker) Revisions(ctx context.Context, want *kcd.RevisionsFilter, f func(kcd.Revision) error) error { 57 db.μ.Lock() 58 defer db.μ.Unlock() 59 return db.rd.Revisions(ctx, want, f) 60 } 61 62 // Find implements a method of kcd.Reader. 63 func (db *locker) Find(ctx context.Context, filter *kcd.FindFilter, f func(string) error) error { 64 db.μ.Lock() 65 defer db.μ.Unlock() 66 return db.rd.Find(ctx, filter, f) 67 } 68 69 // Units implements a method of kcd.Reader. 70 func (db *locker) Units(ctx context.Context, unitDigests []string, f func(digest, key string, data []byte) error) error { 71 db.μ.Lock() 72 defer db.μ.Unlock() 73 return db.rd.Units(ctx, unitDigests, f) 74 } 75 76 // Files implements a method of kcd.Reader. 77 func (db *locker) Files(ctx context.Context, fileDigests []string, f func(string, []byte) error) error { 78 db.μ.Lock() 79 defer db.μ.Unlock() 80 return db.rd.Files(ctx, fileDigests, f) 81 } 82 83 // FilesExist implements a method of kcd.Reader. 84 func (db *locker) FilesExist(ctx context.Context, fileDigests []string, f func(string) error) error { 85 db.μ.Lock() 86 defer db.μ.Unlock() 87 return db.rd.FilesExist(ctx, fileDigests, f) 88 } 89 90 // WriteRevision implements a method of kcd.Writer. 91 func (db *locker) WriteRevision(ctx context.Context, rev kcd.Revision, replace bool) error { 92 if db.wr == nil { 93 return ErrNotSupported 94 } 95 db.μ.Lock() 96 defer db.μ.Unlock() 97 return db.wr.WriteRevision(ctx, rev, replace) 98 } 99 100 // WriteUnit implements a method of kcd.Writer. 101 func (db *locker) WriteUnit(ctx context.Context, rev kcd.Revision, formatKey string, unit kcd.Unit) (string, error) { 102 if db.wr == nil { 103 return "", ErrNotSupported 104 } 105 db.μ.Lock() 106 defer db.μ.Unlock() 107 return db.wr.WriteUnit(ctx, rev, formatKey, unit) 108 } 109 110 // WriteFile implements a method of kcd.Writer. 111 func (db *locker) WriteFile(ctx context.Context, r io.Reader) (string, error) { 112 if db.wr == nil { 113 return "", ErrNotSupported 114 } 115 db.μ.Lock() 116 defer db.μ.Unlock() 117 return db.wr.WriteFile(ctx, r) 118 } 119 120 // DeleteUnit implements a method of kcd.Deleter. 121 func (db *locker) DeleteUnit(ctx context.Context, unitDigest string) error { 122 if db.del == nil { 123 return ErrNotSupported 124 } 125 db.μ.Lock() 126 defer db.μ.Unlock() 127 return db.del.DeleteUnit(ctx, unitDigest) 128 } 129 130 // DeleteFile implements a method of kcd.Deleter. 131 func (db *locker) DeleteFile(ctx context.Context, fileDigest string) error { 132 if db.del == nil { 133 return ErrNotSupported 134 } 135 db.μ.Lock() 136 defer db.μ.Unlock() 137 return db.del.DeleteFile(ctx, fileDigest) 138 } 139 140 // DeleteRevision implements a method of kcd.Deleter. 141 func (db *locker) DeleteRevision(ctx context.Context, revision, corpus string) error { 142 if db.del == nil { 143 return ErrNotSupported 144 } 145 db.μ.Lock() 146 defer db.μ.Unlock() 147 return db.del.DeleteRevision(ctx, revision, corpus) 148 }