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. + * + * 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>