[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master-tx, updated. v0.9.11-213-gc7a7765

Lennart Poettering gitmailer-noreply at 0pointer.de
Mon Sep 8 07:25:25 PDT 2008


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master-tx branch has been updated
      from  6b034f5bfd4a69d5795f2292014f902fd450a8a4 (commit)

- Log -----------------------------------------------------------------
c7a7765... Merge branch 'master' into master-tx
821dc17... move autospawn lock to pulsecore/ since we don't need it in the client anymore
f216402... Add new option to disable remixing from/to LFE and set it to on by default
33d349d... include build and runtime host information in debug output
fb837f0... rework autospawning to allow to multiple parallel autospawning contexts
994ff98... connect to localhost via IP address instead of host name, to avoid needless NSS lookup
89ed507... if we are exiting due to cpu overload, say so via syslog, too
f52fb64... if we are exiting due to idleness, say so
a609e4a... check for errors returned by pa_context_connect()
3f6f13f... use pa_channel_map_compatible() where applicable
b56f344... a few minor clean-ups
3429072... introduce upper channel map definition limit PA_CHANNEL_MAP_DEF_MAX
ece297f... update map file
cb0c97d... add new API function pa_channel_map_compatible()
5a9a602... update map-file script to ignore gcc malloc attributes
4562849... update documentation and help texts for s32le/s32be sample types
12c5c62... Downgrade hrtimer warning to notice level
-----------------------------------------------------------------------

Summary of changes:
 man/pacat.1.xml.in                        |    6 +-
 man/pulse-daemon.conf.5.xml.in            |   16 ++-
 src/Makefile.am                           |    9 +-
 src/daemon/cpulimit.c                     |    2 +
 src/daemon/daemon-conf.c                  |   36 ++--
 src/daemon/daemon-conf.h                  |    1 +
 src/daemon/daemon.conf.in                 |    1 +
 src/daemon/main.c                         |   12 +-
 src/map-file                              |    2 +
 src/modules/module-alsa-sink.c            |    2 +-
 src/modules/module-alsa-source.c          |    2 +-
 src/pulse/channelmap.c                    |   22 ++-
 src/pulse/channelmap.h                    |    9 +-
 src/pulse/context.c                       |  318 ++++++++++-------------------
 src/pulse/internal.h                      |    3 -
 src/pulsecore/core-util.c                 |    8 +
 src/pulsecore/core-util.h                 |    1 +
 src/pulsecore/core.c                      |    2 +
 src/pulsecore/core.h                      |    1 +
 src/{pulse => pulsecore}/lock-autospawn.c |    0 
 src/{pulse => pulsecore}/lock-autospawn.h |    0 
 src/pulsecore/resampler.c                 |    8 +-
 src/pulsecore/resampler.h                 |    7 +-
 src/pulsecore/sink-input.c                |    3 +-
 src/pulsecore/source-output.c             |    3 +-
 src/tests/lock-autospawn-test.c           |    2 +-
 src/utils/pacat.c                         |    9 +-
 27 files changed, 223 insertions(+), 262 deletions(-)
 rename src/{pulse => pulsecore}/lock-autospawn.c (100%)
 rename src/{pulse => pulsecore}/lock-autospawn.h (100%)

-----------------------------------------------------------------------

commit 12c5c62dadad248f4a01a9973b6e99c99d0badad
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 00:38:52 2008 +0200

    Downgrade hrtimer warning to notice level

diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index e3f9a5f..6f0d783 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -1241,7 +1241,7 @@ int pa__init(pa_module*m) {
     }
 
     if (use_tsched && !pa_rtclock_hrtimer()) {
-        pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
         use_tsched = FALSE;
     }
 
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index 54ffde5..fca0500 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -1073,7 +1073,7 @@ int pa__init(pa_module*m) {
     }
 
     if (use_tsched && !pa_rtclock_hrtimer()) {
-        pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
         use_tsched = FALSE;
     }
 

commit 456284918ab04cde6c661839d706cb84baf3a887
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 00:39:36 2008 +0200

    update documentation and help texts for s32le/s32be sample types

diff --git a/man/pacat.1.xml.in b/man/pacat.1.xml.in
index 7b0d72b..68a3a12 100644
--- a/man/pacat.1.xml.in
+++ b/man/pacat.1.xml.in
@@ -108,9 +108,11 @@ USA.
 
       <optdesc><p>Capture or play back audio with the specified sample
       format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
-      <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+      <opt>s16be</opt>, <opt>s32le</opt>,
+      <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
       <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
-      the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+      the CPU the
+      formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
       <opt>float32ne</opt>, <opt>float32re</opt> (for native,
       resp. reverse endian) are available as aliases. Defaults to
       s16ne.</p></optdesc>
diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index 50e2455..c2eefaa 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -319,9 +319,11 @@ USA.
     <option>
       <p><opt>default-sample-format=</opt> The default sampling
       format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
-      <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+      <opt>s16be</opt>, <opt>s32le</opt>,
+      <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
       <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
-      the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+      the CPU the
+      formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
       <opt>float32ne</opt>, <opt>float32re</opt> (for native,
       resp. reverse endian) are available as aliases.</p>
     </option>
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index c1826d7..f42abc8 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -500,7 +500,7 @@ static void help(const char *argv0) {
            "      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
            "      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
            "      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-           "                                        float32be, ulaw, alaw (defaults to s16ne)\n"
+           "                                        float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
            "      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
            "                                        (defaults to 2)\n"
            "      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"

commit 5a9a6021f12ebfcdc071d07488723ab8c0adfd5f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:28:08 2008 +0200

    update map-file script to ignore gcc malloc attributes

diff --git a/src/Makefile.am b/src/Makefile.am
index a20c7c4..3ee5372 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1625,7 +1625,7 @@ update-ffmpeg:
 update-map-file:
 	( echo "PULSE_0 {" ; \
 	  echo "global:" ; \
-	  ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
+	  ctags -I PA_GCC_MALLOC,PA_GCC_ALLOC_SIZE2,PA_GCC_ALLOC_SIZE,PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
 	  echo "local:" ;  \
 	  echo "*;" ; \
 	  echo "};" ) > $(srcdir)/map-file

commit cb0c97dae7655eda60cabc06df0d1da4666392ec
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:29:07 2008 +0200

    add new API function pa_channel_map_compatible()

diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 1766e72..7a21998 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -560,3 +560,10 @@ int pa_channel_map_valid(const pa_channel_map *map) {
 
     return 1;
 }
+
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
+    pa_assert(map);
+    pa_assert(ss);
+
+    return map->channels == ss->channels;
+}
diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index f9086d1..035f9b1 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -214,6 +214,10 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GC
 /** Return non-zero of the specified channel map is considered valid */
 int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
 
+/** Return non-zero if the specified channel map is compatible with
+ * the specified sample spec. \since 0.9.12 */
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE;
+
 PA_C_DECL_END
 
 #endif

commit ece297f21b627dfb71e853a57dcacbd1bd5217bb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:29:24 2008 +0200

    update map file

diff --git a/src/map-file b/src/map-file
index b6d3b63..67a5ee3 100644
--- a/src/map-file
+++ b/src/map-file
@@ -9,6 +9,7 @@ pa_browser_unref;
 pa_bytes_per_second;
 pa_bytes_snprint;
 pa_bytes_to_usec;
+pa_channel_map_compatible;
 pa_channel_map_equal;
 pa_channel_map_init;
 pa_channel_map_init_auto;
@@ -98,6 +99,7 @@ pa_context_unref;
 pa_cvolume_avg;
 pa_cvolume_channels_equal_to;
 pa_cvolume_equal;
+pa_cvolume_max;
 pa_cvolume_remap;
 pa_cvolume_set;
 pa_cvolume_snprint;

commit 34290725043274ddc88aeb203892f3d8bb7bbecf
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:30:25 2008 +0200

    introduce upper channel map definition limit PA_CHANNEL_MAP_DEF_MAX

diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 7a21998..7df6d6d 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -198,6 +198,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
     pa_assert(m);
     pa_assert(channels > 0);
     pa_assert(channels <= PA_CHANNELS_MAX);
+    pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
 
     pa_channel_map_init(m);
 
@@ -391,7 +392,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
 
 
         default:
-            return NULL;
+            pa_assert_not_reached();
     }
 }
 
@@ -401,6 +402,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
     pa_assert(m);
     pa_assert(channels > 0);
     pa_assert(channels <= PA_CHANNELS_MAX);
+    pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
 
     pa_channel_map_init(m);
 
diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index 035f9b1..d2dd6f8 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -157,6 +157,9 @@ typedef enum pa_channel_map_def {
     PA_CHANNEL_MAP_OSS,
     /**< The default channel mapping used by OSS as defined in the OSS 4.0 API specs */
 
+    /**< Upper limit of valid channel mapping definitions */
+    PA_CHANNEL_MAP_DEF_MAX,
+
     PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
     /**< The default channel map */
 } pa_channel_map_def_t;
@@ -211,7 +214,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s);
 /** Compare two channel maps. Return 1 if both match. */
 int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
 
-/** Return non-zero of the specified channel map is considered valid */
+/** Return non-zero if the specified channel map is considered valid */
 int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
 
 /** Return non-zero if the specified channel map is compatible with

commit b56f344b97e9520828a76cf54d81663fa48cbd33
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:30:48 2008 +0200

    a few minor clean-ups

diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 7df6d6d..3730875 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -288,9 +288,6 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
         case PA_CHANNEL_MAP_AUX: {
             unsigned i;
 
-            if (channels >= PA_CHANNELS_MAX)
-                return NULL;
-
             for (i = 0; i < channels; i++)
                 m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
 
@@ -491,7 +488,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
     pa_assert(rmap);
     pa_assert(s);
 
-    memset(&map, 0, sizeof(map));
+    pa_channel_map_init(&map);
 
     if (strcmp(s, "stereo") == 0) {
         map.channels = 2;
@@ -554,11 +551,9 @@ int pa_channel_map_valid(const pa_channel_map *map) {
     if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
         return 0;
 
-    for (c = 0; c < map->channels; c++) {
-
-        if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
+    for (c = 0; c < map->channels; c++)
+        if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
             return 0;
-    }
 
     return 1;
 }

commit 3f6f13f90227d1adfe39b56671aa34745778f35d
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:31:17 2008 +0200

    use pa_channel_map_compatible() where applicable

diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index f42abc8..76aea36 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -695,7 +695,7 @@ int main(int argc, char *argv[]) {
         goto quit;
     }
 
-    if (channel_map_set && channel_map.channels != sample_spec.channels) {
+    if (channel_map_set && pa_channel_map_compatible(&channel_map, &sample_spec)) {
         fprintf(stderr, _("Channel map doesn't match sample specification\n"));
         goto quit;
     }

commit a609e4a700da10926fcb9c9633dee1342907de97
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 01:31:39 2008 +0200

    check for errors returned by pa_context_connect()

diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 76aea36..99df5b9 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -773,7 +773,10 @@ int main(int argc, char *argv[]) {
     pa_context_set_state_callback(context, context_state_callback, NULL);
 
     /* Connect the context */
-    pa_context_connect(context, server, 0, NULL);
+    if (pa_context_connect(context, server, 0, NULL) < 0) {
+        fprintf(stderr, _("pa_context_connect() failed: %s"), pa_strerror(pa_context_errno(context)));
+        goto quit;
+    }
 
     if (verbose) {
         struct timeval tv;

commit f52fb64313fd423cd085f7b53ce5663c0c17d382
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 03:17:48 2008 +0200

    if we are exiting due to idleness, say so

diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index b9f04b6..6f8a292 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -204,6 +204,7 @@ static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct time
     pa_core *c = userdata;
     pa_assert(c->exit_event == e);
 
+    pa_log_info("We are idle, quitting...");
     pa_core_exit(c, TRUE, 0);
 }
 

commit 89ed50750e46486ba06638f15f3bb32e92e5c903
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 03:18:36 2008 +0200

    if we are exiting due to cpu overload, say so via syslog, too

diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c
index 5955282..a909600 100644
--- a/src/daemon/cpulimit.c
+++ b/src/daemon/cpulimit.c
@@ -167,6 +167,8 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
     pa_assert(e == io_event);
     pa_assert(fd == the_pipe[0]);
 
+    pa_log("Recevied request to terminate due to CPU overload.");
+
     pa_read(the_pipe[0], &c, sizeof(c), NULL);
     m->quit(m, 1); /* Quit the main loop */
 }

commit 994ff984f04740e6817f3eb7b725e3825f3d290c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 03:20:33 2008 +0200

    connect to localhost via IP address instead of host name, to avoid needless NSS lookup

diff --git a/src/pulse/context.c b/src/pulse/context.c
index f1aa498..723980e 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -905,8 +905,9 @@ int pa_context_connect(
             pa_xfree(d);
         }
 
-        c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
-        c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
+        /* Add TCP/IP on the localhost */
+        c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
+        c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
 
         /* The system wide instance */
         c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);

commit fb837f0cac00d0207f84c9e68e1f7c2d6cd33a51
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 03:22:13 2008 +0200

    rework autospawning to allow to multiple parallel autospawning contexts

diff --git a/src/pulse/context.c b/src/pulse/context.c
index 723980e..154e5fa 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -54,7 +54,6 @@
 #include <pulse/utf8.h>
 #include <pulse/util.h>
 #include <pulse/i18n.h>
-#include <pulse/lock-autospawn.h>
 
 #include <pulsecore/winsock.h>
 #include <pulsecore/core-error.h>
@@ -98,26 +97,6 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
     [PA_COMMAND_EXTENSION] = pa_command_extension
 };
-
-static void unlock_autospawn(pa_context *c) {
-    pa_assert(c);
-
-    if (c->autospawn_fd >= 0) {
-
-        if (c->autospawn_locked)
-            pa_autospawn_lock_release();
-
-        if (c->autospawn_event)
-            c->mainloop->io_free(c->autospawn_event);
-
-        pa_autospawn_lock_done(FALSE);
-    }
-
-    c->autospawn_locked = FALSE;
-    c->autospawn_fd = -1;
-    c->autospawn_event = NULL;
-}
-
 static void context_free(pa_context *c);
 
 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
@@ -180,9 +159,6 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
     c->do_shm = FALSE;
 
     c->do_autospawn = FALSE;
-    c->autospawn_fd = -1;
-    c->autospawn_locked = FALSE;
-    c->autospawn_event = NULL;
     memset(&c->spawn_api, 0, sizeof(c->spawn_api));
 
 #ifndef MSG_NOSIGNAL
@@ -252,8 +228,6 @@ static void context_free(pa_context *c) {
 
     context_unlink(c);
 
-    unlock_autospawn(c);
-
     if (c->record_streams)
         pa_dynarray_free(c->record_streams, NULL, NULL);
     if (c->playback_streams)
@@ -577,31 +551,89 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
     pa_context_unref(c);
 }
 
-static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+static char *get_old_legacy_runtime_dir(void) {
+    char *p, u[128];
+    struct stat st;
 
-#ifndef OS_IS_WIN32
+    if (!pa_get_user_name(u, sizeof(u)))
+        return NULL;
 
-static int context_connect_spawn(pa_context *c) {
-    pid_t pid;
-    int status, r;
-    int fds[2] = { -1, -1} ;
-    pa_iochannel *io;
+    p = pa_sprintf_malloc("/tmp/pulse-%s", u);
 
-    if (getuid() == 0)
-        return -1;
+    if (stat(p, &st) < 0) {
+        pa_xfree(p);
+        return NULL;
+    }
 
-    pa_context_ref(c);
+    if (st.st_uid != getuid()) {
+        pa_xfree(p);
+        return NULL;
+    }
 
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
-        pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno));
-        pa_context_fail(c, PA_ERR_INTERNAL);
-        goto fail;
+    return p;
+}
+
+static char *get_very_old_legacy_runtime_dir(void) {
+    char *p, h[128];
+    struct stat st;
+
+    if (!pa_get_home_dir(h, sizeof(h)))
+        return NULL;
+
+    p = pa_sprintf_malloc("%s/.pulse", h);
+
+    if (stat(p, &st) < 0) {
+        pa_xfree(p);
+        return NULL;
+    }
+
+    if (st.st_uid != getuid()) {
+        pa_xfree(p);
+        return NULL;
+    }
+
+    return p;
+}
+
+
+static pa_strlist *prepend_per_user(pa_strlist *l) {
+    char *ufn;
+    static char *legacy_dir;
+
+    /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
+    if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
+        char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+        l = pa_strlist_prepend(l, p);
+        pa_xfree(p);
+        pa_xfree(legacy_dir);
+    }
+
+    /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
+    if ((legacy_dir = get_old_legacy_runtime_dir())) {
+        char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+        l = pa_strlist_prepend(l, p);
+        pa_xfree(p);
+        pa_xfree(legacy_dir);
     }
 
-    pa_make_fd_cloexec(fds[0]);
+    /* The per-user instance */
+    if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
+        l = pa_strlist_prepend(l, ufn);
+        pa_xfree(ufn);
+    }
+
+    return l;
+}
 
-    pa_make_socket_low_delay(fds[0]);
-    pa_make_socket_low_delay(fds[1]);
+#ifndef OS_IS_WIN32
+
+static int context_autospawn(pa_context *c) {
+    pid_t pid;
+    int status, r;
+
+    pa_log_debug("Trying to autospawn...");
+
+    pa_context_ref(c);
 
     if (c->spawn_api.prefork)
         c->spawn_api.prefork();
@@ -617,31 +649,22 @@ static int context_connect_spawn(pa_context *c) {
     } else if (!pid) {
         /* Child */
 
-        char t[128];
         const char *state = NULL;
 #define MAX_ARGS 64
         const char * argv[MAX_ARGS+1];
         int n;
-        char *f;
-
-        pa_close_all(fds[1], -1);
-
-        f = pa_sprintf_malloc("%i", fds[1]);
-        pa_set_env("PULSE_PASSED_FD", f);
-        pa_xfree(f);
 
         if (c->spawn_api.atfork)
             c->spawn_api.atfork();
 
+        pa_close_all(-1);
+
         /* Setup argv */
 
         n = 0;
 
         argv[n++] = c->conf->daemon_binary;
-        argv[n++] = "--daemonize=yes";
-
-        pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
-        argv[n++] = strdup(t);
+        argv[n++] = "--start";
 
         while (n < MAX_ARGS) {
             char *a;
@@ -661,14 +684,13 @@ static int context_connect_spawn(pa_context *c) {
 
     /* Parent */
 
-    pa_assert_se(pa_close(fds[1]) == 0);
-    fds[1] = -1;
-
-    r = waitpid(pid, &status, 0);
-
     if (c->spawn_api.postfork)
         c->spawn_api.postfork();
 
+    do {
+        r = waitpid(pid, &status, 0);
+    } while (r < 0 && errno == EINTR);
+
     if (r < 0) {
         pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
         pa_context_fail(c, PA_ERR_INTERNAL);
@@ -678,21 +700,11 @@ static int context_connect_spawn(pa_context *c) {
         goto fail;
     }
 
-    c->is_local = TRUE;
-
-    unlock_autospawn(c);
-
-    io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
-    setup_context(c, io);
-
     pa_context_unref(c);
 
     return 0;
 
 fail:
-    pa_close_pipe(fds);
-
-    unlock_autospawn(c);
 
     pa_context_unref(c);
 
@@ -701,6 +713,8 @@ fail:
 
 #endif /* OS_IS_WIN32 */
 
+static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+
 static int try_next_connection(pa_context *c) {
     char *u = NULL;
     int r = -1;
@@ -718,8 +732,18 @@ static int try_next_connection(pa_context *c) {
 
 #ifndef OS_IS_WIN32
             if (c->do_autospawn) {
-                r = context_connect_spawn(c);
-                goto finish;
+
+                if ((r = context_autospawn(c)) < 0)
+                    goto finish;
+
+                /* Autospawn only once */
+                c->do_autospawn = FALSE;
+
+                /* Connect only to per-user sockets this time */
+                c->server_list = prepend_per_user(c->server_list);
+
+                /* Retry connection */
+                continue;
             }
 #endif
 
@@ -774,91 +798,12 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd
         goto finish;
     }
 
-    unlock_autospawn(c);
     setup_context(c, io);
 
 finish:
     pa_context_unref(c);
 }
 
-static void autospawn_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
-    pa_context *c = userdata;
-    int k;
-
-    pa_assert(a);
-    pa_assert(e);
-    pa_assert(fd >= 0);
-    pa_assert(events == PA_IO_EVENT_INPUT);
-    pa_assert(c);
-    pa_assert(e == c->autospawn_event);
-    pa_assert(fd == c->autospawn_fd);
-
-    pa_context_ref(c);
-
-    /* Check whether we can get the lock right now*/
-    if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
-        pa_context_fail(c, PA_ERR_ACCESS);
-        goto finish;
-    }
-
-    if (k > 0) {
-        /* So we got it, rock on! */
-        c->autospawn_locked = TRUE;
-        try_next_connection(c);
-
-        c->mainloop->io_free(c->autospawn_event);
-        c->autospawn_event = NULL;
-    }
-
-finish:
-
-    pa_context_unref(c);
-}
-
-static char *get_old_legacy_runtime_dir(void) {
-    char *p, u[128];
-    struct stat st;
-
-    if (!pa_get_user_name(u, sizeof(u)))
-        return NULL;
-
-    p = pa_sprintf_malloc("/tmp/pulse-%s", u);
-
-    if (stat(p, &st) < 0) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    if (st.st_uid != getuid()) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    return p;
-}
-
-static char *get_very_old_legacy_runtime_dir(void) {
-    char *p, h[128];
-    struct stat st;
-
-    if (!pa_get_home_dir(h, sizeof(h)))
-        return NULL;
-
-    p = pa_sprintf_malloc("%s/.pulse", h);
-
-    if (stat(p, &st) < 0) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    if (st.st_uid != getuid()) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    return p;
-}
-
 int pa_context_connect(
         pa_context *c,
         const char *server,
@@ -888,11 +833,11 @@ int pa_context_connect(
         }
 
     } else {
-        char *d, *ufn;
-        static char *legacy_dir;
+        char *d;
 
         /* Prepend in reverse order */
 
+        /* Follow the X display */
         if ((d = getenv("DISPLAY"))) {
             char *e;
             d = pa_xstrdup(d);
@@ -909,67 +854,23 @@ int pa_context_connect(
         c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
         c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
 
-        /* The system wide instance */
+        /* The system wide instance via PF_LOCAL */
         c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
 
-        /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
-        if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
-            char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
-            c->server_list = pa_strlist_prepend(c->server_list, p);
-            pa_xfree(p);
-            pa_xfree(legacy_dir);
-        }
+        /* The user instance via PF_LOCAL */
+        c->server_list = prepend_per_user(c->server_list);
 
-        /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
-        if ((legacy_dir = get_old_legacy_runtime_dir())) {
-            char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
-            c->server_list = pa_strlist_prepend(c->server_list, p);
-            pa_xfree(p);
-            pa_xfree(legacy_dir);
-        }
-
-        /* The per-user instance */
-        if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
-            c->server_list = pa_strlist_prepend(c->server_list, ufn);
-            pa_xfree(ufn);
-        }
-
-        /* Wrap the connection attempts in a single transaction for sane autospawn locking */
+        /* Set up autospawning */
         if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
-            int k;
-
-            pa_assert(c->autospawn_fd < 0);
-            pa_assert(!c->autospawn_locked);
 
-            /* Start the locking procedure */
-            if ((c->autospawn_fd = pa_autospawn_lock_init()) < 0) {
-                pa_context_fail(c, PA_ERR_ACCESS);
-                goto finish;
-            }
-
-            if (api)
-                c->spawn_api = *api;
-
-            c->do_autospawn = TRUE;
-
-            /* Check whether we can get the lock right now*/
-            if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
-                pa_context_fail(c, PA_ERR_ACCESS);
-                goto finish;
-            }
-
-            if (k > 0)
-                /* So we got it, rock on! */
-                c->autospawn_locked = TRUE;
+            if (getuid() == 0)
+                pa_log_debug("Not doing autospawn since we are root.");
             else {
-                /* Hmm, we didn't get it, so let's wait for it */
-                c->autospawn_event = c->mainloop->io_new(c->mainloop, c->autospawn_fd, PA_IO_EVENT_INPUT, autospawn_cb, c);
+                c->do_autospawn = TRUE;
 
-                pa_context_set_state(c, PA_CONTEXT_CONNECTING);
-                r = 0;
-                goto finish;
+                if (api)
+                    c->spawn_api = *api;
             }
-
         }
     }
 
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index 9167bf1..5fe4210 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -78,9 +78,6 @@ struct pa_context {
     pa_bool_t do_shm:1;
 
     pa_bool_t do_autospawn:1;
-    pa_bool_t autospawn_locked:1;
-    int autospawn_fd;
-    pa_io_event *autospawn_event;
     pa_spawn_api spawn_api;
 
     pa_strlist *server_list;

commit 33d349dcbbef0952e9e59ca105e08fdff5454803
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 15:42:39 2008 +0300

    include build and runtime host information in debug output

diff --git a/src/daemon/main.c b/src/daemon/main.c
index c8eda39..bb8af44 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -778,8 +778,15 @@ int main(int argc, char *argv[]) {
     pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
 
     pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
+    pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
     pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
 
+    s = pa_uname_string();
+    pa_log_debug(_("Running on host: %s"), s);
+    pa_xfree(s);
+
+    pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
+
 #ifdef HAVE_VALGRIND_MEMCHECK_H
     pa_log_debug(_("Compiled with Valgrind support: yes"));
 #else
@@ -792,8 +799,6 @@ int main(int argc, char *argv[]) {
     pa_log_debug(_("Optimized build: no"));
 #endif
 
-    pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
-
     if (!(s = pa_machine_id())) {
         pa_log(_("Failed to get machine ID"));
         goto finish;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index ad00f4f..3e5ea49 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -42,6 +42,7 @@
 #include <dirent.h>
 #include <regex.h>
 #include <langinfo.h>
+#include <sys/utsname.h>
 
 #ifdef HAVE_STRTOF_L
 #include <locale.h>
@@ -2445,5 +2446,12 @@ char *pa_machine_id(void) {
     /* If no hostname was set we use the POSIX hostid. It's usually
      * the IPv4 address.  Mit not be that stable. */
     return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
+}
+
+char *pa_uname_string(void) {
+    struct utsname u;
+
+    pa_assert_se(uname(&u) == 0);
 
+    return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
 }
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index c9e307f..df8ce3f 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -191,5 +191,6 @@ pa_bool_t pa_in_system_mode(void);
 #define pa_streq(a,b) (!strcmp((a),(b)))
 
 char *pa_machine_id(void);
+char *pa_uname_string(void);
 
 #endif

commit f2164023fd0fda8c1a456c5c2f144f8943c24db9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Sep 5 16:04:42 2008 +0300

    Add new option to disable remixing from/to LFE and set it to on by default

diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index c2eefaa..ed158df 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -106,6 +106,16 @@ USA.
     </option>
 
     <option>
+      <p><opt>disable-lfe-remixing=</opt> When upmixing or downmixing
+      ignore LFE channels. When this option is on the output LFE
+      channel will only get a signal when an input LFE channel is
+      available as well. If no input LFE channel is available the
+      output LFE channel will always be 0. If no output LFE channel is
+      available the signal on the input LFE channel will be
+      ignored.</p>
+    </option>
+
+    <option>
       <p><opt>use-pid-file=</opt> Create a PID file in
       <file>/tmp/pulse-$USER/pid</file>. Of this is enabled you may
       use commands like <opt>--kill</opt> or <opt>--check</opt>. If
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 40e0a17..77da3f7 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -76,6 +76,7 @@ static const pa_daemon_conf default_conf = {
     .log_level = PA_LOG_NOTICE,
     .resample_method = PA_RESAMPLER_AUTO,
     .disable_remixing = FALSE,
+    .disable_lfe_remixing = TRUE,
     .config_file = NULL,
     .use_pid_file = TRUE,
     .system_instance = FALSE,
@@ -426,6 +427,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
         { "default-fragment-size-msec", parse_fragment_size_msec, NULL },
         { "nice-level",                 parse_nice_level,         NULL },
         { "disable-remixing",           pa_config_parse_bool,     NULL },
+        { "disable-lfe-remixing",       pa_config_parse_bool,     NULL },
         { "load-default-script-file",   pa_config_parse_bool,     NULL },
 #ifdef HAVE_SYS_RESOURCE_H
         { "rlimit-fsize",               parse_rlimit,             NULL },
@@ -490,66 +492,67 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     table[24].data = c;
     table[25].data = c;
     table[26].data = &c->disable_remixing;
-    table[27].data = &c->load_default_script_file;
+    table[27].data = &c->disable_lfe_remixing;
+    table[28].data = &c->load_default_script_file;
 #ifdef HAVE_SYS_RESOURCE_H
-    table[28].data = &c->rlimit_fsize;
-    table[29].data = &c->rlimit_data;
-    table[30].data = &c->rlimit_stack;
-    table[31].data = &c->rlimit_as;
-    table[32].data = &c->rlimit_core;
-    table[33].data = &c->rlimit_nofile;
-    table[34].data = &c->rlimit_as;
+    table[29].data = &c->rlimit_fsize;
+    table[30].data = &c->rlimit_data;
+    table[31].data = &c->rlimit_stack;
+    table[32].data = &c->rlimit_as;
+    table[33].data = &c->rlimit_core;
+    table[34].data = &c->rlimit_nofile;
+    table[35].data = &c->rlimit_as;
 #ifdef RLIMIT_NPROC
-    table[35].data = &c->rlimit_nproc;
+    table[36].data = &c->rlimit_nproc;
 #endif
 
 #ifdef RLIMIT_MEMLOCK
 #ifndef RLIMIT_NPROC
 #error "Houston, we have a numbering problem!"
 #endif
-    table[36].data = &c->rlimit_memlock;
+    table[37].data = &c->rlimit_memlock;
 #endif
 
 #ifdef RLIMIT_LOCKS
 #ifndef RLIMIT_MEMLOCK
 #error "Houston, we have a numbering problem!"
 #endif
-    table[37].data = &c->rlimit_locks;
+    table[38].data = &c->rlimit_locks;
 #endif
 
 #ifdef RLIMIT_SIGPENDING
 #ifndef RLIMIT_LOCKS
 #error "Houston, we have a numbering problem!"
 #endif
-    table[38].data = &c->rlimit_sigpending;
+    table[39].data = &c->rlimit_sigpending;
 #endif
 
 #ifdef RLIMIT_MSGQUEUE
 #ifndef RLIMIT_SIGPENDING
 #error "Houston, we have a numbering problem!"
 #endif
-    table[39].data = &c->rlimit_msgqueue;
+    table[40].data = &c->rlimit_msgqueue;
 #endif
 
 #ifdef RLIMIT_NICE
 #ifndef RLIMIT_MSGQUEUE
 #error "Houston, we have a numbering problem!"
 #endif
-    table[40].data = &c->rlimit_nice;
+    table[41].data = &c->rlimit_nice;
 #endif
 
 #ifdef RLIMIT_RTPRIO
 #ifndef RLIMIT_NICE
 #error "Houston, we have a numbering problem!"
 #endif
-    table[41].data = &c->rlimit_rtprio;
+    table[42].data = &c->rlimit_rtprio;
 #endif
 
 #ifdef RLIMIT_RTTIME
 #ifndef RLIMIT_RTTIME
 #error "Houston, we have a numbering problem!"
 #endif
-    table[42].data = &c->rlimit_rttime;
+    table[43].data = &c->rlimit_rttime;
 #endif
 #endif
 
@@ -661,6 +664,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
     pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
     pa_strbuf_printf(s, "disable-remixing = %s\n", pa_yes_no(c->disable_remixing));
+    pa_strbuf_printf(s, "disable-lfe-remixing = %s\n", pa_yes_no(c->disable_lfe_remixing));
     pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
     pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
     pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index c42984f..309a142 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -66,6 +66,7 @@ typedef struct pa_daemon_conf {
         no_cpu_limit,
         disable_shm,
         disable_remixing,
+        disable_lfe_remixing,
         load_default_script_file,
         disallow_exit;
     int exit_idle_time,
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index 33b1d61..ea09fe0 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -47,6 +47,7 @@
 
 ; resample-method = speex-float-3
 ; disable-remixing = no
+; disable-lfe-remixing = yes
 
 ; no-cpu-limit = no
 
diff --git a/src/daemon/main.c b/src/daemon/main.c
index bb8af44..f91573b 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -869,6 +869,7 @@ int main(int argc, char *argv[]) {
     c->realtime_priority = conf->realtime_priority;
     c->realtime_scheduling = !!conf->realtime_scheduling;
     c->disable_remixing = !!conf->disable_remixing;
+    c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
     c->running_as_daemon = !!conf->daemonize;
     c->disallow_exit = conf->disallow_exit;
 
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index 6f8a292..bd956ae 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -138,6 +138,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
     c->realtime_scheduling = FALSE;
     c->realtime_priority = 5;
     c->disable_remixing = FALSE;
+    c->disable_lfe_remixing = FALSE;
 
     for (j = 0; j < PA_CORE_HOOK_MAX; j++)
         pa_hook_init(&c->hooks[j], c);
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index eb76841..fb4490f 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -124,6 +124,7 @@ struct pa_core {
     pa_bool_t running_as_daemon:1;
     pa_bool_t realtime_scheduling:1;
     pa_bool_t disable_remixing:1;
+    pa_bool_t disable_lfe_remixing:1;
 
     pa_resample_method_t resample_method;
     int realtime_priority;
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 45cd68c..0ae029b 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -716,7 +716,11 @@ static void calc_map_table(pa_resampler *r) {
                  * channels for LFE. */
 
                 for (ic = 0; ic < r->i_ss.channels; ic++) {
-                    r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+
+                    if (!(r->flags & PA_RESAMPLER_NO_LFE))
+                        r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+                    else
+                        r->map_table[oc][ic] = 0;
 
                     /* Please note that a channel connected to LFE
                      * doesn't really count as connected. */
@@ -851,7 +855,7 @@ static void calc_map_table(pa_resampler *r) {
             }
         }
 
-        if (ic_unconnected_lfe > 0) {
+        if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
 
             /* OK, so there is an unconnected LFE channel. Let's mix
              * it into all channels, with factor 0.375 */
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 5e302a9..87110cc 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -49,9 +49,10 @@ typedef enum pa_resample_method {
 } pa_resample_method_t;
 
 typedef enum pa_resample_flags {
-    PA_RESAMPLER_VARIABLE_RATE = 1,
-    PA_RESAMPLER_NO_REMAP = 2,  /* implies NO_REMIX */
-    PA_RESAMPLER_NO_REMIX = 4
+    PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
+    PA_RESAMPLER_NO_REMAP      = 0x0002U,  /* implies NO_REMIX */
+    PA_RESAMPLER_NO_REMIX      = 0x0004U,
+    PA_RESAMPLER_NO_LFE        = 0x0008U
 } pa_resample_flags_t;
 
 pa_resampler* pa_resampler_new(
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 7d80242..326a7e2 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -201,7 +201,8 @@ pa_sink_input* pa_sink_input_new(
                       data->resample_method,
                       ((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
                       ((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
-                      (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+                      (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+                      (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
             pa_log_warn("Unsupported resampling operation.");
             return NULL;
         }
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 5df950a..d76f6e4 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -171,7 +171,8 @@ pa_source_output* pa_source_output_new(
                       data->resample_method,
                       ((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
                       ((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
-                      (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+                      (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+                      (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
             pa_log_warn("Unsupported resampling operation.");
             return NULL;
         }

commit 821dc1797faa903618c7585d3c053fd7ae6e93db
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Sep 8 17:22:27 2008 +0300

    move autospawn lock to pulsecore/ since we don't need it in the client anymore

diff --git a/src/Makefile.am b/src/Makefile.am
index 3ee5372..1663d66 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -541,8 +541,7 @@ libpulse_la_SOURCES = \
 		pulse/xmalloc.c pulse/xmalloc.h \
 		pulse/proplist.c pulse/proplist.h \
 		pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
-		pulse/i18n.c pulse/i18n.h \
-		pulse/lock-autospawn.c pulse/lock-autospawn.h
+		pulse/i18n.c pulse/i18n.h
 
 # Internal stuff that is shared with libpulsecore
 libpulse_la_SOURCES += \
@@ -740,8 +739,7 @@ libpulsecore_la_SOURCES = \
 		pulse/volume.c pulse/volume.h \
 		pulse/xmalloc.c pulse/xmalloc.h \
 		pulse/proplist.c pulse/proplist.h \
-		pulse/i18n.c pulse/i18n.h \
-		pulse/lock-autospawn.c pulse/lock-autospawn.h
+		pulse/i18n.c pulse/i18n.h
 
 # Pure core stuff (some are shared in libpulse though).
 libpulsecore_la_SOURCES += \
@@ -811,6 +809,7 @@ libpulsecore_la_SOURCES += \
 		pulsecore/start-child.c pulsecore/start-child.h \
 		pulsecore/envelope.c pulsecore/envelope.h \
 		pulsecore/proplist-util.c pulsecore/proplist-util.h \
+		pulsecore/lock-autospawn.c pulsecore/lock-autospawn.h \
 		$(PA_THREAD_OBJS)
 
 if OS_IS_WIN32
diff --git a/src/daemon/main.c b/src/daemon/main.c
index f91573b..a9e8ed4 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -65,8 +65,8 @@
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 #include <pulse/i18n.h>
-#include <pulse/lock-autospawn.h>
 
+#include <pulsecore/lock-autospawn.h>
 #include <pulsecore/winsock.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core.h>
diff --git a/src/pulse/lock-autospawn.c b/src/pulse/lock-autospawn.c
deleted file mode 100644
index d36b669..0000000
--- a/src/pulse/lock-autospawn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <signal.h>
-#include <pthread.h>
-
-#include <pulse/i18n.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/mutex.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/core-util.h>
-
-#include "lock-autospawn.h"
-
-/* So, why do we have this complex code here with threads and pipes
- * and stuff? For two reasons: POSIX file locks are per-process, not
- * per-file descriptor. That means that two contexts within the same
- * process that try to create the autospawn lock might end up assuming
- * they both managed to lock the file. And then, POSIX locking
- * operations are synchronous. If two contexts run from the same event
- * loop it must be made sure that they do not block each other, but
- * that the locking operation can happen asynchronously. */
-
-#define AUTOSPAWN_LOCK "autospawn.lock"
-
-static pa_mutex *mutex;
-
-static unsigned n_ref = 0;
-static int lock_fd = -1;
-static pa_mutex *lock_fd_mutex = NULL;
-static pa_bool_t taken = FALSE;
-static pa_thread *thread;
-static int pipe_fd[2] = { -1, -1 };
-
-static void destroy_mutex(void) PA_GCC_DESTRUCTOR;
-
-static int ref(void) {
-
-    if (n_ref > 0) {
-
-        pa_assert(pipe_fd[0] >= 0);
-        pa_assert(pipe_fd[1] >= 0);
-
-        n_ref++;
-
-        return 0;
-    }
-
-    pa_assert(lock_fd < 0);
-    pa_assert(!lock_fd_mutex);
-    pa_assert(!taken);
-    pa_assert(!thread);
-    pa_assert(pipe_fd[0] < 0);
-    pa_assert(pipe_fd[1] < 0);
-
-    if (pipe(pipe_fd) < 0)
-        return -1;
-
-    lock_fd_mutex = pa_mutex_new(FALSE, FALSE);
-
-    pa_make_fd_cloexec(pipe_fd[0]);
-    pa_make_fd_cloexec(pipe_fd[1]);
-
-    pa_make_fd_nonblock(pipe_fd[1]);
-    pa_make_fd_nonblock(pipe_fd[0]);
-
-    n_ref = 1;
-    return 0;
-}
-
-static void unref(pa_bool_t after_fork) {
-
-    pa_assert(n_ref > 0);
-    pa_assert(pipe_fd[0] >= 0);
-    pa_assert(pipe_fd[1] >= 0);
-    pa_assert(lock_fd_mutex);
-
-    n_ref--;
-
-    if (n_ref > 0)
-        return;
-
-    pa_assert(!taken);
-
-    if (thread) {
-        pa_thread_free(thread);
-        thread = NULL;
-    }
-
-    pa_mutex_lock(lock_fd_mutex);
-    if (lock_fd >= 0) {
-
-        if (after_fork)
-            pa_close(lock_fd);
-        else {
-            char *lf;
-
-            if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
-                pa_log_warn(_("Cannot access autospawn lock."));
-
-            pa_unlock_lockfile(lf, lock_fd);
-            pa_xfree(lf);
-
-            lock_fd = -1;
-        }
-    }
-    pa_mutex_unlock(lock_fd_mutex);
-
-    pa_mutex_free(lock_fd_mutex);
-    lock_fd_mutex = NULL;
-
-    pa_close(pipe_fd[0]);
-    pa_close(pipe_fd[1]);
-    pipe_fd[0] = pipe_fd[1] = -1;
-}
-
-static void ping(void) {
-    ssize_t s;
-
-    pa_assert(pipe_fd[1] >= 0);
-
-    for (;;) {
-        char x = 'x';
-
-        if ((s = write(pipe_fd[1], &x, 1)) == 1)
-            break;
-
-        pa_assert(s < 0);
-
-        if (errno == EAGAIN)
-            break;
-
-        pa_assert(errno == EINTR);
-    }
-}
-
-static void wait_for_ping(void) {
-    ssize_t s;
-    char x;
-    struct pollfd pfd;
-    int k;
-
-    pa_assert(pipe_fd[0] >= 0);
-
-    memset(&pfd, 0, sizeof(pfd));
-    pfd.fd = pipe_fd[0];
-    pfd.events = POLLIN;
-
-    if ((k = poll(&pfd, 1, -1)) != 1) {
-        pa_assert(k < 0);
-        pa_assert(errno == EINTR);
-    } else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
-        pa_assert(s < 0);
-        pa_assert(errno == EAGAIN);
-    }
-}
-
-static void empty_pipe(void) {
-    char x[16];
-    ssize_t s;
-
-    pa_assert(pipe_fd[0] >= 0);
-
-    if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
-        pa_assert(s < 0);
-        pa_assert(errno == EAGAIN);
-    }
-}
-
-static void thread_func(void *u) {
-    int fd;
-    char *lf;
-    sigset_t fullset;
-
-    /* No signals in this thread please */
-    sigfillset(&fullset);
-    pthread_sigmask(SIG_BLOCK, &fullset, NULL);
-
-    if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
-        pa_log_warn(_("Cannot access autospawn lock."));
-        goto finish;
-    }
-
-    if ((fd = pa_lock_lockfile(lf)) < 0)
-        goto finish;
-
-    pa_mutex_lock(lock_fd_mutex);
-    pa_assert(lock_fd < 0);
-    lock_fd = fd;
-    pa_mutex_unlock(lock_fd_mutex);
-
-finish:
-    pa_xfree(lf);
-
-    ping();
-}
-
-static int start_thread(void) {
-
-    if (!thread)
-        if (!(thread = pa_thread_new(thread_func, NULL)))
-            return -1;
-
-    return 0;
-}
-
-static void create_mutex(void) {
-    PA_ONCE_BEGIN {
-        mutex = pa_mutex_new(FALSE, FALSE);
-    } PA_ONCE_END;
-}
-
-static void destroy_mutex(void) {
-
-    if (mutex)
-        pa_mutex_free(mutex);
-}
-
-
-int pa_autospawn_lock_init(void) {
-    int ret = -1;
-
-    create_mutex();
-    pa_mutex_lock(mutex);
-
-    if (ref() < 0)
-        ret = -1;
-    else
-        ret = pipe_fd[0];
-
-    pa_mutex_unlock(mutex);
-
-    return ret;
-}
-
-int pa_autospawn_lock_acquire(pa_bool_t block) {
-    int ret = -1;
-
-    create_mutex();
-    pa_mutex_lock(mutex);
-    pa_assert(n_ref >= 1);
-
-    pa_mutex_lock(lock_fd_mutex);
-
-    for (;;) {
-
-        empty_pipe();
-
-        if (lock_fd >= 0 && !taken) {
-            taken = TRUE;
-            ret = 1;
-            break;
-        }
-
-        if (lock_fd < 0)
-            if (start_thread() < 0)
-                break;
-
-        if (!block) {
-            ret = 0;
-            break;
-        }
-
-        pa_mutex_unlock(lock_fd_mutex);
-        pa_mutex_unlock(mutex);
-
-        wait_for_ping();
-
-        pa_mutex_lock(mutex);
-        pa_mutex_lock(lock_fd_mutex);
-    }
-
-    pa_mutex_unlock(lock_fd_mutex);
-
-    pa_mutex_unlock(mutex);
-
-    return ret;
-}
-
-void pa_autospawn_lock_release(void) {
-
-    create_mutex();
-    pa_mutex_lock(mutex);
-    pa_assert(n_ref >= 1);
-
-    pa_assert(taken);
-    taken = FALSE;
-
-    ping();
-
-    pa_mutex_unlock(mutex);
-}
-
-void pa_autospawn_lock_done(pa_bool_t after_fork) {
-
-    create_mutex();
-    pa_mutex_lock(mutex);
-    pa_assert(n_ref >= 1);
-
-    unref(after_fork);
-
-    pa_mutex_unlock(mutex);
-}
diff --git a/src/pulse/lock-autospawn.h b/src/pulse/lock-autospawn.h
deleted file mode 100644
index c04c4bd..0000000
--- a/src/pulse/lock-autospawn.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef foopulselockautospawnhfoo
-#define foopulselockautospawnhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.1 of the
-  License, or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulsecore/macro.h>
-
-int pa_autospawn_lock_init(void);
-int pa_autospawn_lock_acquire(pa_bool_t block);
-void pa_autospawn_lock_release(void);
-void pa_autospawn_lock_done(pa_bool_t after_fork);
-
-#endif
diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c
new file mode 100644
index 0000000..d36b669
--- /dev/null
+++ b/src/pulsecore/lock-autospawn.c
@@ -0,0 +1,330 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/poll.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include <pulse/i18n.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/mutex.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/core-util.h>
+
+#include "lock-autospawn.h"
+
+/* So, why do we have this complex code here with threads and pipes
+ * and stuff? For two reasons: POSIX file locks are per-process, not
+ * per-file descriptor. That means that two contexts within the same
+ * process that try to create the autospawn lock might end up assuming
+ * they both managed to lock the file. And then, POSIX locking
+ * operations are synchronous. If two contexts run from the same event
+ * loop it must be made sure that they do not block each other, but
+ * that the locking operation can happen asynchronously. */
+
+#define AUTOSPAWN_LOCK "autospawn.lock"
+
+static pa_mutex *mutex;
+
+static unsigned n_ref = 0;
+static int lock_fd = -1;
+static pa_mutex *lock_fd_mutex = NULL;
+static pa_bool_t taken = FALSE;
+static pa_thread *thread;
+static int pipe_fd[2] = { -1, -1 };
+
+static void destroy_mutex(void) PA_GCC_DESTRUCTOR;
+
+static int ref(void) {
+
+    if (n_ref > 0) {
+
+        pa_assert(pipe_fd[0] >= 0);
+        pa_assert(pipe_fd[1] >= 0);
+
+        n_ref++;
+
+        return 0;
+    }
+
+    pa_assert(lock_fd < 0);
+    pa_assert(!lock_fd_mutex);
+    pa_assert(!taken);
+    pa_assert(!thread);
+    pa_assert(pipe_fd[0] < 0);
+    pa_assert(pipe_fd[1] < 0);
+
+    if (pipe(pipe_fd) < 0)
+        return -1;
+
+    lock_fd_mutex = pa_mutex_new(FALSE, FALSE);
+
+    pa_make_fd_cloexec(pipe_fd[0]);
+    pa_make_fd_cloexec(pipe_fd[1]);
+
+    pa_make_fd_nonblock(pipe_fd[1]);
+    pa_make_fd_nonblock(pipe_fd[0]);
+
+    n_ref = 1;
+    return 0;
+}
+
+static void unref(pa_bool_t after_fork) {
+
+    pa_assert(n_ref > 0);
+    pa_assert(pipe_fd[0] >= 0);
+    pa_assert(pipe_fd[1] >= 0);
+    pa_assert(lock_fd_mutex);
+
+    n_ref--;
+
+    if (n_ref > 0)
+        return;
+
+    pa_assert(!taken);
+
+    if (thread) {
+        pa_thread_free(thread);
+        thread = NULL;
+    }
+
+    pa_mutex_lock(lock_fd_mutex);
+    if (lock_fd >= 0) {
+
+        if (after_fork)
+            pa_close(lock_fd);
+        else {
+            char *lf;
+
+            if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
+                pa_log_warn(_("Cannot access autospawn lock."));
+
+            pa_unlock_lockfile(lf, lock_fd);
+            pa_xfree(lf);
+
+            lock_fd = -1;
+        }
+    }
+    pa_mutex_unlock(lock_fd_mutex);
+
+    pa_mutex_free(lock_fd_mutex);
+    lock_fd_mutex = NULL;
+
+    pa_close(pipe_fd[0]);
+    pa_close(pipe_fd[1]);
+    pipe_fd[0] = pipe_fd[1] = -1;
+}
+
+static void ping(void) {
+    ssize_t s;
+
+    pa_assert(pipe_fd[1] >= 0);
+
+    for (;;) {
+        char x = 'x';
+
+        if ((s = write(pipe_fd[1], &x, 1)) == 1)
+            break;
+
+        pa_assert(s < 0);
+
+        if (errno == EAGAIN)
+            break;
+
+        pa_assert(errno == EINTR);
+    }
+}
+
+static void wait_for_ping(void) {
+    ssize_t s;
+    char x;
+    struct pollfd pfd;
+    int k;
+
+    pa_assert(pipe_fd[0] >= 0);
+
+    memset(&pfd, 0, sizeof(pfd));
+    pfd.fd = pipe_fd[0];
+    pfd.events = POLLIN;
+
+    if ((k = poll(&pfd, 1, -1)) != 1) {
+        pa_assert(k < 0);
+        pa_assert(errno == EINTR);
+    } else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
+        pa_assert(s < 0);
+        pa_assert(errno == EAGAIN);
+    }
+}
+
+static void empty_pipe(void) {
+    char x[16];
+    ssize_t s;
+
+    pa_assert(pipe_fd[0] >= 0);
+
+    if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
+        pa_assert(s < 0);
+        pa_assert(errno == EAGAIN);
+    }
+}
+
+static void thread_func(void *u) {
+    int fd;
+    char *lf;
+    sigset_t fullset;
+
+    /* No signals in this thread please */
+    sigfillset(&fullset);
+    pthread_sigmask(SIG_BLOCK, &fullset, NULL);
+
+    if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
+        pa_log_warn(_("Cannot access autospawn lock."));
+        goto finish;
+    }
+
+    if ((fd = pa_lock_lockfile(lf)) < 0)
+        goto finish;
+
+    pa_mutex_lock(lock_fd_mutex);
+    pa_assert(lock_fd < 0);
+    lock_fd = fd;
+    pa_mutex_unlock(lock_fd_mutex);
+
+finish:
+    pa_xfree(lf);
+
+    ping();
+}
+
+static int start_thread(void) {
+
+    if (!thread)
+        if (!(thread = pa_thread_new(thread_func, NULL)))
+            return -1;
+
+    return 0;
+}
+
+static void create_mutex(void) {
+    PA_ONCE_BEGIN {
+        mutex = pa_mutex_new(FALSE, FALSE);
+    } PA_ONCE_END;
+}
+
+static void destroy_mutex(void) {
+
+    if (mutex)
+        pa_mutex_free(mutex);
+}
+
+
+int pa_autospawn_lock_init(void) {
+    int ret = -1;
+
+    create_mutex();
+    pa_mutex_lock(mutex);
+
+    if (ref() < 0)
+        ret = -1;
+    else
+        ret = pipe_fd[0];
+
+    pa_mutex_unlock(mutex);
+
+    return ret;
+}
+
+int pa_autospawn_lock_acquire(pa_bool_t block) {
+    int ret = -1;
+
+    create_mutex();
+    pa_mutex_lock(mutex);
+    pa_assert(n_ref >= 1);
+
+    pa_mutex_lock(lock_fd_mutex);
+
+    for (;;) {
+
+        empty_pipe();
+
+        if (lock_fd >= 0 && !taken) {
+            taken = TRUE;
+            ret = 1;
+            break;
+        }
+
+        if (lock_fd < 0)
+            if (start_thread() < 0)
+                break;
+
+        if (!block) {
+            ret = 0;
+            break;
+        }
+
+        pa_mutex_unlock(lock_fd_mutex);
+        pa_mutex_unlock(mutex);
+
+        wait_for_ping();
+
+        pa_mutex_lock(mutex);
+        pa_mutex_lock(lock_fd_mutex);
+    }
+
+    pa_mutex_unlock(lock_fd_mutex);
+
+    pa_mutex_unlock(mutex);
+
+    return ret;
+}
+
+void pa_autospawn_lock_release(void) {
+
+    create_mutex();
+    pa_mutex_lock(mutex);
+    pa_assert(n_ref >= 1);
+
+    pa_assert(taken);
+    taken = FALSE;
+
+    ping();
+
+    pa_mutex_unlock(mutex);
+}
+
+void pa_autospawn_lock_done(pa_bool_t after_fork) {
+
+    create_mutex();
+    pa_mutex_lock(mutex);
+    pa_assert(n_ref >= 1);
+
+    unref(after_fork);
+
+    pa_mutex_unlock(mutex);
+}
diff --git a/src/pulsecore/lock-autospawn.h b/src/pulsecore/lock-autospawn.h
new file mode 100644
index 0000000..c04c4bd
--- /dev/null
+++ b/src/pulsecore/lock-autospawn.h
@@ -0,0 +1,32 @@
+#ifndef foopulselockautospawnhfoo
+#define foopulselockautospawnhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/macro.h>
+
+int pa_autospawn_lock_init(void);
+int pa_autospawn_lock_acquire(pa_bool_t block);
+void pa_autospawn_lock_release(void);
+void pa_autospawn_lock_done(pa_bool_t after_fork);
+
+#endif
diff --git a/src/tests/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c
index cb3dc87..80cfda6 100644
--- a/src/tests/lock-autospawn-test.c
+++ b/src/tests/lock-autospawn-test.c
@@ -28,7 +28,7 @@
 
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
-#include <pulse/lock-autospawn.h>
+#include <pulsecore/lock-autospawn.h>
 #include <pulse/util.h>
 
 static void thread_func(void*k) {

commit c7a77657ffe00b6d52a0c7e3d29f4fcf8537af5f
Merge: 6b034f5... 821dc17...
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Sep 8 17:25:16 2008 +0300

    Merge branch 'master' into master-tx


-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list