@@ -182,6 +182,69 @@ func TestReadLoop_MalformedLineSkipped(t *testing.T) {
182182 }
183183}
184184
185+ func TestCommand_ResponseNotStarvedByFullEventQueue (t * testing.T ) {
186+ c , server := pipePair (t , defaultIPCBuf )
187+
188+ result := make (chan error , 1 )
189+ go func () {
190+ _ , err := c .command (context .Background (), "set_property" , "volume" , 55 )
191+ result <- err
192+ }()
193+
194+ scanner := bufio .NewScanner (server )
195+ if ! scanner .Scan () {
196+ t .Fatal ("scanner ended before reading request" )
197+ }
198+ var req ipcRequest
199+ if err := json .Unmarshal (scanner .Bytes (), & req ); err != nil {
200+ t .Fatalf ("decode request: %v" , err )
201+ }
202+
203+ // Simulate a noisy stream that fills the event queue before mpv's
204+ // command response arrives. The IPC reader must keep reading and route
205+ // the response instead of blocking forever on an undrained Events chan.
206+ writeErr := make (chan error , 1 )
207+ go func () {
208+ for i := 0 ; i < cap (c .events )+ 10 ; i ++ {
209+ line := fmt .Sprintf (`{"event":"property-change","id":9,"name":"demuxer-cache-state","data":{"fw-bytes":%d}}` + "\n " , i )
210+ if _ , err := server .Write ([]byte (line )); err != nil {
211+ writeErr <- fmt .Errorf ("write event %d: %w" , i , err )
212+ return
213+ }
214+ }
215+ resp , _ := json .Marshal (ipcResponse {RequestID : req .RequestID , Error : "success" })
216+ if _ , err := server .Write (append (resp , '\n' )); err != nil {
217+ writeErr <- fmt .Errorf ("write response: %w" , err )
218+ return
219+ }
220+ writeErr <- nil
221+ }()
222+
223+ select {
224+ case err := <- result :
225+ if err != nil {
226+ t .Fatalf ("command returned error: %v" , err )
227+ }
228+ if err := <- writeErr ; err != nil {
229+ t .Fatal (err )
230+ }
231+ case err := <- writeErr :
232+ if err != nil {
233+ t .Fatal (err )
234+ }
235+ select {
236+ case err := <- result :
237+ if err != nil {
238+ t .Fatalf ("command returned error: %v" , err )
239+ }
240+ case <- time .After (time .Second ):
241+ t .Fatal ("timeout waiting for command response after writes completed" )
242+ }
243+ case <- time .After (time .Second ):
244+ t .Fatal ("timeout waiting for command response; event backpressure likely starved responses" )
245+ }
246+ }
247+
185248func TestCommand_ContextCancellation (t * testing.T ) {
186249 c , _ := pipePair (t , defaultIPCBuf )
187250
0 commit comments