Commit 52820e2 1 parent 420a6c1 commit 52820e2 Copy full SHA for 52820e2
File tree 2 files changed +42
-1
lines changed
2 files changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -37,6 +37,7 @@ import (
37
37
"errors"
38
38
"fmt"
39
39
"io"
40
+ "reflect"
40
41
"runtime"
41
42
"sync"
42
43
"time"
@@ -188,11 +189,22 @@ func (c *Context) addPlayingPlayer(p *playerImpl) {
188
189
defer c .m .Unlock ()
189
190
c .playingPlayers [p ] = struct {}{}
190
191
192
+ // (reflect.Type).Comparable() is enough here, as reflect.TypeOf should always return a dynamic (non-interface) type.
193
+ // If reflect.TypeOf returned an interface type, this check would be meaningless.
194
+ // See these for more details:
195
+ // * https://pkg.go.dev/reflect#TypeOf
196
+ // * https://pkg.go.dev/reflect#Type.Comparable
197
+ //
198
+ // (*reflect.Value).Comparable() is more intuitive but this was introduced in Go 1.20.
199
+ if ! reflect .TypeOf (p .sourceIdent ()).Comparable () {
200
+ return
201
+ }
202
+
191
203
// Check the source duplication
192
204
srcs := map [any ]struct {}{}
193
205
for p := range c .playingPlayers {
194
206
if _ , ok := srcs [p .sourceIdent ()]; ok {
195
- c .err = errors .New ("audio: a same source is used by multiple Player" )
207
+ c .err = errors .New ("audio: the same source must not be used by multiple Player objects " )
196
208
return
197
209
}
198
210
srcs [p .sourceIdent ()] = struct {}{}
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ package audio_test
16
16
17
17
import (
18
18
"bytes"
19
+ "io"
19
20
"os"
20
21
"runtime"
21
22
"testing"
@@ -147,4 +148,32 @@ func TestNonSeekableSource(t *testing.T) {
147
148
148
149
p .Play ()
149
150
p .Pause ()
151
+
152
+ if err := audio .UpdateForTesting (); err != nil {
153
+ t .Error (err )
154
+ }
155
+ }
156
+
157
+ type uncomparableSource []int
158
+
159
+ func (uncomparableSource ) Read (buf []byte ) (int , error ) {
160
+ return 0 , io .EOF
161
+ }
162
+
163
+ // Issue #3039
164
+ func TestUncomparableSource (t * testing.T ) {
165
+ setup ()
166
+ defer teardown ()
167
+
168
+ p , err := context .NewPlayer (uncomparableSource {})
169
+ if err != nil {
170
+ t .Fatal (err )
171
+ }
172
+
173
+ p .Play ()
174
+ p .Pause ()
175
+
176
+ if err := audio .UpdateForTesting (); err != nil {
177
+ t .Error (err )
178
+ }
150
179
}
You can’t perform that action at this time.
0 commit comments