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