aboutsummaryrefslogtreecommitdiffstats
path: root/src/Main.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-11-02 14:06:05 +0100
committerMax Kellermann <max@duempel.org>2014-11-02 14:06:05 +0100
commit303d67aed2da79d4ddaa3a52093ed42ae9da064d (patch)
tree060580f4c17b5d30d1e78e584df03c795ce4e1d7 /src/Main.cxx
parent575fbad254a1ce67530bf2aedc9852c89c072c3f (diff)
parent6a7f6cdacd81877276563c42fdeacad3a8deface (diff)
downloadmpd-303d67aed2da79d4ddaa3a52093ed42ae9da064d.tar.gz
mpd-303d67aed2da79d4ddaa3a52093ed42ae9da064d.tar.xz
mpd-303d67aed2da79d4ddaa3a52093ed42ae9da064d.zip
Merge tag 'v0.19.2'
Diffstat (limited to '')
-rw-r--r--src/Main.cxx29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/Main.cxx b/src/Main.cxx
index d17590e44..2719c05e0 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -114,6 +114,10 @@
#include <ws2tcpip.h>
#endif
+#ifdef __APPLE__
+#include <dispatch/dispatch.h>
+#endif
+
#include <limits.h>
static constexpr unsigned DEFAULT_BUFFER_SIZE = 4096;
@@ -401,8 +405,6 @@ int main(int argc, char *argv[])
{
#ifdef WIN32
return win32_main(argc, argv);
-#elif __APPLE__
- return osx_main(argc, argv);
#else
return mpd_main(argc, argv);
#endif
@@ -410,6 +412,8 @@ int main(int argc, char *argv[])
#endif
+static int mpd_main_after_fork(struct options);
+
#ifdef ANDROID
static inline
#endif
@@ -513,6 +517,27 @@ int mpd_main(int argc, char *argv[])
daemonize_begin(options.daemon);
#endif
+#ifdef __APPLE__
+ /* Runs the OS X native event loop in the main thread, and runs
+ the rest of mpd_main on a new thread. This lets CoreAudio receive
+ route change notifications (e.g. plugging or unplugging headphones).
+ All hardware output on OS X ultimately uses CoreAudio internally.
+ This must be run after forking; if dispatch is called before forking,
+ the child process will have a broken internal dispatch state. */
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ exit(mpd_main_after_fork(options));
+ });
+ dispatch_main();
+ return EXIT_FAILURE; // unreachable, because dispatch_main never returns
+#else
+ return mpd_main_after_fork(options);
+#endif
+}
+
+static int mpd_main_after_fork(struct options options)
+{
+ Error error;
+
GlobalEvents::Initialize(*instance->event_loop);
GlobalEvents::Register(GlobalEvents::IDLE, idle_event_emitted);
#ifdef WIN32