ports/115692: rdesktop(1) hangs in a tight loop upon sound device close

Eugene M. Kim freebsd.org at ab.ote.we.lv
Tue Aug 21 17:30:02 UTC 2007


>Number:         115692
>Category:       ports
>Synopsis:       rdesktop(1) hangs in a tight loop upon sound device close
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 21 17:30:01 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Eugene M. Kim
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
AstralBlue
>Environment:
System: FreeBSD seerajeane.astralblue.net 7.0-CURRENT FreeBSD 7.0-CURRENT #1: Sat Jul 28 09:00:00 PDT 2007 ab at seerajeane.astralblue.net:/home/FreeBSD/build/MAIN/obj/home/FreeBSD/build/MAIN/src/sys/PL-SEERAJEANE i386
>Description:
Upon server-initiated closure of the sound device, rdesktop(1) hangs in
a tight loop if the sound packet buffer is not empty.  This usually
occurs after a long playback, and is indicated by an endless stream of
"ERROR: select: Bad file descriptor" messages on stderr.
>How-To-Repeat:
Run rdesktop with -r sound:local, and play an MP3 file for about 30
seconds then stop playback.
>Fix:
Apply the following patch, which forcibly empties the sound packet buffer
after closing the sound device.
--- patch-rdpsnd_oss.c begins here ---
--- rdpsnd_oss.c	2007-08-20 23:20:40.000000000 -0700
+++ rdpsnd_oss.c.new	2007-08-20 23:21:51.000000000 -0700
@@ -51,6 +51,35 @@
 } packet_queue[MAX_QUEUE];
 static unsigned int queue_hi, queue_lo;
 
+/** Frees the first audio packet in the queue (that is, packet_queue[queue_lo]),
+ * sending a completion notification back to the server.
+ *
+ * @return True if the packet queue has become empty; False otherwise. 
+ *
+ * If the packet queue is not empty, queue_lo will point at the next packet to
+ * play.
+ */
+static BOOL
+packet_done(void)
+{
+	struct audio_packet *packet = &packet_queue[queue_lo++];
+	queue_lo %= MAX_QUEUE;
+	rdpsnd_send_completion(packet->tick, packet->index);
+	free(packet->s.data);
+	return (queue_lo == queue_hi);
+}
+
+/** Discards all audio packets queued, sending completion notifications back to
+ * the server as necessary.
+ */
+static void
+clear_queue(void)
+{
+	while (queue_lo != queue_hi)
+		packet_done();
+	g_dsp_busy = False;
+}
+
 BOOL
 wave_out_open(void)
 {
@@ -74,6 +103,7 @@
 wave_out_close(void)
 {
 	close(g_dsp_fd);
+	clear_queue();
 }
 
 BOOL
@@ -277,9 +307,7 @@
 
 		if (elapsed >= (duration * 85) / 100)
 		{
-			rdpsnd_send_completion(packet->tick, packet->index);
-			free(out->data);
-			queue_lo = (queue_lo + 1) % MAX_QUEUE;
+			packet_done();
 			started = False;
 		}
 		else
--- patch-rdpsnd_oss.c ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list