OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
9 "infra/gae/libs/wrapper" | |
10 "math/rand" | |
11 "sync" | 9 "sync" |
12 | 10 |
13 "golang.org/x/net/context" | 11 "golang.org/x/net/context" |
14 | 12 |
15 "appengine/datastore" | 13 "appengine/datastore" |
16 ) | 14 ) |
17 | 15 |
18 type memContextObj interface { | 16 type memContextObj interface { |
19 sync.Locker | 17 sync.Locker |
20 canApplyTxn(m memContextObj) bool | 18 canApplyTxn(m memContextObj) bool |
21 » applyTxn(rnd *rand.Rand, m memContextObj) | 19 » applyTxn(c context.Context, m memContextObj) |
22 | 20 |
23 endTxn() | 21 endTxn() |
24 mkTxn(*datastore.TransactionOptions) (memContextObj, error) | 22 mkTxn(*datastore.TransactionOptions) (memContextObj, error) |
25 } | 23 } |
26 | 24 |
27 type memContext []memContextObj | 25 type memContext []memContextObj |
28 | 26 |
29 var _ = memContextObj((memContext)(nil)) | 27 var _ = memContextObj((memContext)(nil)) |
30 | 28 |
31 func newMemContext() memContext { | 29 func newMemContext() memContext { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 func (m memContext) canApplyTxn(txnCtxObj memContextObj) bool { | 77 func (m memContext) canApplyTxn(txnCtxObj memContextObj) bool { |
80 txnCtx := txnCtxObj.(memContext) | 78 txnCtx := txnCtxObj.(memContext) |
81 for i := range m { | 79 for i := range m { |
82 if !m[i].canApplyTxn(txnCtx[i]) { | 80 if !m[i].canApplyTxn(txnCtx[i]) { |
83 return false | 81 return false |
84 } | 82 } |
85 } | 83 } |
86 return true | 84 return true |
87 } | 85 } |
88 | 86 |
89 func (m memContext) applyTxn(rnd *rand.Rand, txnCtxObj memContextObj) { | 87 func (m memContext) applyTxn(c context.Context, txnCtxObj memContextObj) { |
90 txnCtx := txnCtxObj.(memContext) | 88 txnCtx := txnCtxObj.(memContext) |
91 for i := range m { | 89 for i := range m { |
92 » » m[i].applyTxn(rnd, txnCtx[i]) | 90 » » m[i].applyTxn(c, txnCtx[i]) |
93 } | 91 } |
94 } | 92 } |
95 | 93 |
96 // Use adds implementations for the following gae/wrapper interfaces to the | 94 // Use adds implementations for the following gae/wrapper interfaces to the |
97 // context: | 95 // context: |
98 // * wrapper.Datastore | 96 // * wrapper.Datastore |
99 // * wrapper.TaskQueue | 97 // * wrapper.TaskQueue |
100 // * wrapper.Memcache | 98 // * wrapper.Memcache |
101 // * wrapper.GlobalInfo | 99 // * wrapper.GlobalInfo |
102 // | 100 // |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 }() | 153 }() |
156 | 154 |
157 if err = f(context.WithValue(d.c, memContextKey, txnMC)); err != nil { | 155 if err = f(context.WithValue(d.c, memContextKey, txnMC)); err != nil { |
158 return err | 156 return err |
159 } | 157 } |
160 | 158 |
161 txnMC.Lock() | 159 txnMC.Lock() |
162 defer txnMC.Unlock() | 160 defer txnMC.Unlock() |
163 | 161 |
164 if curMC.canApplyTxn(txnMC) { | 162 if curMC.canApplyTxn(txnMC) { |
165 » » curMC.applyTxn(wrapper.GetMathRand(d.c), txnMC) | 163 » » curMC.applyTxn(d.c, txnMC) |
166 } else { | 164 } else { |
167 return datastore.ErrConcurrentTransaction | 165 return datastore.ErrConcurrentTransaction |
168 } | 166 } |
169 return nil | 167 return nil |
170 } | 168 } |
OLD | NEW |