Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit ef35f91

Browse files
committed
fix race condition on ObjectLRU
Signed-off-by: Miguel Molina <[email protected]>
1 parent 7738417 commit ef35f91

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

plumbing/cache/object_lru.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cache
22

33
import (
44
"container/list"
5+
"sync"
56

67
"gopkg.in/src-d/go-git.v4/plumbing"
78
)
@@ -14,6 +15,7 @@ type ObjectLRU struct {
1415
actualSize FileSize
1516
ll *list.List
1617
cache map[interface{}]*list.Element
18+
mut sync.Mutex
1719
}
1820

1921
// NewObjectLRU creates a new ObjectLRU with the given maximum size. The maximum
@@ -26,6 +28,9 @@ func NewObjectLRU(maxSize FileSize) *ObjectLRU {
2628
// will be marked as used. Otherwise, it will be inserted. A single object might
2729
// be evicted to make room for the new object.
2830
func (c *ObjectLRU) Put(obj plumbing.EncodedObject) {
31+
c.mut.Lock()
32+
defer c.mut.Unlock()
33+
2934
if c.cache == nil {
3035
c.actualSize = 0
3136
c.cache = make(map[interface{}]*list.Element, 1000)
@@ -67,6 +72,9 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) {
6772
// Get returns an object by its hash. It marks the object as used. If the object
6873
// is not in the cache, (nil, false) will be returned.
6974
func (c *ObjectLRU) Get(k plumbing.Hash) (plumbing.EncodedObject, bool) {
75+
c.mut.Lock()
76+
defer c.mut.Unlock()
77+
7078
ee, ok := c.cache[k]
7179
if !ok {
7280
return nil, false
@@ -78,6 +86,9 @@ func (c *ObjectLRU) Get(k plumbing.Hash) (plumbing.EncodedObject, bool) {
7886

7987
// Clear the content of this object cache.
8088
func (c *ObjectLRU) Clear() {
89+
c.mut.Lock()
90+
defer c.mut.Unlock()
91+
8192
c.ll = nil
8293
c.cache = nil
8394
c.actualSize = 0

plumbing/cache/object_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package cache
22

33
import (
4+
"fmt"
45
"io"
6+
"sync"
57
"testing"
68

79
"gopkg.in/src-d/go-git.v4/plumbing"
@@ -67,6 +69,20 @@ func (s *ObjectSuite) TestClear(c *C) {
6769
c.Assert(obj, IsNil)
6870
}
6971

72+
func (s *ObjectSuite) TestConcurrentAccess(c *C) {
73+
var wg sync.WaitGroup
74+
75+
for i := 0; i < 1000; i++ {
76+
wg.Add(1)
77+
go func(i int) {
78+
s.c.Put(newObject(fmt.Sprint(i), FileSize(i)))
79+
wg.Done()
80+
}(i)
81+
}
82+
83+
wg.Wait()
84+
}
85+
7086
type dummyObject struct {
7187
hash plumbing.Hash
7288
size FileSize

0 commit comments

Comments
 (0)