File tree 3 files changed +33
-6
lines changed
3 files changed +33
-6
lines changed Original file line number Diff line number Diff line change @@ -33,6 +33,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
33
33
34
34
- Build with OpenSSL < 1.1.1 (#194 )
35
35
- Add ` ExecuteAsync ` and ` ExecuteTyped ` to common connector interface (#62 )
36
+ - Race conditions in methods of ` Future ` type (#195 )
36
37
37
38
## [ 1.6.0] - 2022-06-01
38
39
Original file line number Diff line number Diff line change @@ -129,38 +129,41 @@ func NewFuture() (fut *Future) {
129
129
// AppendPush appends the push response to the future.
130
130
// Note: it works only before SetResponse() or SetError()
131
131
func (fut * Future ) AppendPush (resp * Response ) {
132
+ fut .mutex .Lock ()
133
+ defer fut .mutex .Unlock ()
134
+
132
135
if fut .isDone () {
133
136
return
134
137
}
135
138
resp .Code = PushCode
136
- fut .mutex .Lock ()
137
139
fut .pushes = append (fut .pushes , resp )
138
- fut .mutex .Unlock ()
139
140
140
141
fut .ready <- struct {}{}
141
142
}
142
143
143
144
// SetResponse sets a response for the future and finishes the future.
144
145
func (fut * Future ) SetResponse (resp * Response ) {
146
+ fut .mutex .Lock ()
147
+ defer fut .mutex .Unlock ()
148
+
145
149
if fut .isDone () {
146
150
return
147
151
}
148
- fut .mutex .Lock ()
149
152
fut .resp = resp
150
- fut .mutex .Unlock ()
151
153
152
154
close (fut .ready )
153
155
close (fut .done )
154
156
}
155
157
156
158
// SetError sets an error for the future and finishes the future.
157
159
func (fut * Future ) SetError (err error ) {
160
+ fut .mutex .Lock ()
161
+ defer fut .mutex .Unlock ()
162
+
158
163
if fut .isDone () {
159
164
return
160
165
}
161
- fut .mutex .Lock ()
162
166
fut .err = err
163
- fut .mutex .Unlock ()
164
167
165
168
close (fut .ready )
166
169
close (fut .done )
Original file line number Diff line number Diff line change @@ -233,3 +233,26 @@ func TestFutureGetIteratorError(t *testing.T) {
233
233
}
234
234
}
235
235
}
236
+
237
+ func TestFutureSetStateRaceCondition (t * testing.T ) {
238
+ err := errors .New ("any error" )
239
+ resp := & Response {}
240
+ respAppend := & Response {}
241
+
242
+ for i := 0 ; i < 1000 ; i ++ {
243
+ fut := NewFuture ()
244
+ for j := 0 ; j < 9 ; j ++ {
245
+ go func (opt int ) {
246
+ if opt % 3 == 0 {
247
+ fut .AppendPush (respAppend )
248
+ } else if opt % 3 == 1 {
249
+ fut .SetError (err )
250
+ } else {
251
+ fut .SetResponse (resp )
252
+ }
253
+ }(j )
254
+ }
255
+ }
256
+ // It may be false-positive, but very rarely - it's ok for such very
257
+ // simple race conditions tests.
258
+ }
You can’t perform that action at this time.
0 commit comments