Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Aug 2007 10:21:50 -0700 (PDT)
From:      "Eugene M. Kim" <freebsd.org@ab.ote.we.lv>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/115692: rdesktop(1) hangs in a tight loop upon sound device close
Message-ID:  <200708211721.l7LHLoJn084887@seerajeane.astralblue.net>
Resent-Message-ID: <200708211730.l7LHU1MY008756@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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.&nbsp;
+ *
+ * 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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708211721.l7LHLoJn084887>