File tree Expand file tree Collapse file tree 3 files changed +33
-6
lines changed Expand file tree Collapse file tree 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.
3333
3434- Build with OpenSSL < 1.1.1 (#194 )
3535- Add ` ExecuteAsync ` and ` ExecuteTyped ` to common connector interface (#62 )
36+ - Race conditions in methods of ` Future ` type (#195 )
3637
3738## [ 1.6.0] - 2022-06-01
3839
Original file line number Diff line number Diff line change @@ -129,38 +129,41 @@ func NewFuture() (fut *Future) {
129129// AppendPush appends the push response to the future.
130130// Note: it works only before SetResponse() or SetError()
131131func (fut * Future ) AppendPush (resp * Response ) {
132+ fut .mutex .Lock ()
133+ defer fut .mutex .Unlock ()
134+
132135 if fut .isDone () {
133136 return
134137 }
135138 resp .Code = PushCode
136- fut .mutex .Lock ()
137139 fut .pushes = append (fut .pushes , resp )
138- fut .mutex .Unlock ()
139140
140141 fut .ready <- struct {}{}
141142}
142143
143144// SetResponse sets a response for the future and finishes the future.
144145func (fut * Future ) SetResponse (resp * Response ) {
146+ fut .mutex .Lock ()
147+ defer fut .mutex .Unlock ()
148+
145149 if fut .isDone () {
146150 return
147151 }
148- fut .mutex .Lock ()
149152 fut .resp = resp
150- fut .mutex .Unlock ()
151153
152154 close (fut .ready )
153155 close (fut .done )
154156}
155157
156158// SetError sets an error for the future and finishes the future.
157159func (fut * Future ) SetError (err error ) {
160+ fut .mutex .Lock ()
161+ defer fut .mutex .Unlock ()
162+
158163 if fut .isDone () {
159164 return
160165 }
161- fut .mutex .Lock ()
162166 fut .err = err
163- fut .mutex .Unlock ()
164167
165168 close (fut .ready )
166169 close (fut .done )
Original file line number Diff line number Diff line change @@ -233,3 +233,26 @@ func TestFutureGetIteratorError(t *testing.T) {
233233 }
234234 }
235235}
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