mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
This commit is contained in:
commit
374efbded4
56 changed files with 1035 additions and 942 deletions
54
configure.ac
54
configure.ac
|
|
@ -1152,44 +1152,6 @@ AC_SUBST(DBUS_LIBS)
|
|||
AC_SUBST(HAVE_DBUS)
|
||||
AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1])
|
||||
|
||||
#### PolicyKit support (optional) ####
|
||||
|
||||
AC_ARG_ENABLE([polkit],
|
||||
AS_HELP_STRING([--disable-polkit],[Disable optional PolicyKit support]),
|
||||
[
|
||||
case "${enableval}" in
|
||||
yes) polkit=yes ;;
|
||||
no) polkit=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-polkit) ;;
|
||||
esac
|
||||
],
|
||||
[polkit=auto])
|
||||
|
||||
if test "x${polkit}" != xno ; then
|
||||
|
||||
PKG_CHECK_MODULES(POLKIT, [ polkit-dbus >= 0.7 ],
|
||||
[
|
||||
HAVE_POLKIT=1
|
||||
AC_DEFINE([HAVE_POLKIT], 1, [Have PolicyKit])
|
||||
policydir=`pkg-config polkit-dbus --variable prefix`/share/PolicyKit/policy/
|
||||
AC_SUBST(policydir)
|
||||
],
|
||||
[
|
||||
HAVE_POLKIT=0
|
||||
if test "x$polkit" = xyes ; then
|
||||
AC_MSG_ERROR([*** PolicyKit support not found])
|
||||
fi
|
||||
])
|
||||
else
|
||||
HAVE_POLKIT=0
|
||||
fi
|
||||
|
||||
AC_SUBST(POLKIT_CFLAGS)
|
||||
AC_SUBST(POLKIT_LIBS)
|
||||
AC_SUBST(HAVE_POLKIT)
|
||||
AM_CONDITIONAL([HAVE_POLKIT], [test "x$HAVE_POLKIT" = x1])
|
||||
|
||||
|
||||
### IPv6 connection support (optional) ###
|
||||
|
||||
AC_ARG_ENABLE([ipv6],
|
||||
|
|
@ -1276,15 +1238,6 @@ fi
|
|||
AC_SUBST(PA_SYSTEM_GROUP)
|
||||
AC_DEFINE_UNQUOTED(PA_SYSTEM_GROUP,"$PA_SYSTEM_GROUP", [Group for the PulseAudio system daemon])
|
||||
|
||||
AC_ARG_WITH(realtime_group,AS_HELP_STRING([--with-realtime-group=<group>],[Group for users that are allowed to start the PulseAudio daemon with realtime scheduling (realtime)]))
|
||||
if test -z "$with_realtime_group" ; then
|
||||
PA_REALTIME_GROUP=pulse-rt
|
||||
else
|
||||
PA_REALTIME_GROUP=$with_realtime_group
|
||||
fi
|
||||
AC_SUBST(PA_REALTIME_GROUP)
|
||||
AC_DEFINE_UNQUOTED(PA_REALTIME_GROUP,"$PA_REALTIME_GROUP", [Realtime group])
|
||||
|
||||
AC_ARG_WITH(access_group,AS_HELP_STRING([--with-access-group=<group>],[Group which is allowed access to a system-wide PulseAudio daemon (pulse-access)]))
|
||||
if test -z "$with_access_group" ; then
|
||||
PA_ACCESS_GROUP=pulse-access
|
||||
|
|
@ -1461,11 +1414,6 @@ if test "x${HAVE_BLUEZ}" = "x1" ; then
|
|||
ENABLE_BLUEZ=yes
|
||||
fi
|
||||
|
||||
ENABLE_POLKIT=no
|
||||
if test "x${HAVE_POLKIT}" = "x1" ; then
|
||||
ENABLE_POLKIT=yes
|
||||
fi
|
||||
|
||||
ENABLE_GDBM=no
|
||||
if test "x${HAVE_GDBM}" = "x1" ; then
|
||||
ENABLE_GDBM=yes
|
||||
|
|
@ -1519,7 +1467,6 @@ echo "
|
|||
Enable BlueZ: ${ENABLE_BLUEZ}
|
||||
Enable TCP Wrappers: ${ENABLE_TCPWRAP}
|
||||
Enable libsamplerate: ${ENABLE_LIBSAMPLERATE}
|
||||
Enable PolicyKit: ${ENABLE_POLKIT}
|
||||
Enable IPv6: ${ENABLE_IPV6}
|
||||
Enable OpenSSL (for Airtunes): ${ENABLE_OPENSSL}
|
||||
Enable tdb: ${ENABLE_TDB}
|
||||
|
|
@ -1527,7 +1474,6 @@ echo "
|
|||
|
||||
System User: ${PA_SYSTEM_USER}
|
||||
System Group: ${PA_SYSTEM_GROUP}
|
||||
Realtime Group: ${PA_REALTIME_GROUP}
|
||||
Access Group: ${PA_ACCESS_GROUP}
|
||||
Enable per-user EsounD socket: ${ENABLE_PER_USER_ESOUND_SOCKET}
|
||||
Force preopen: ${FORCE_PREOPEN}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ pulsecoreincludedir=$(includedir)/pulsecore
|
|||
pulseconfdir=$(sysconfdir)/pulse
|
||||
pulselibexecdir=$(libexecdir)/pulse
|
||||
xdgautostartdir=$(sysconfdir)/xdg/autostart
|
||||
alsaprofilesetsdir=$(datadir)/alsa-mixer/profile-sets
|
||||
alsapathsdir=$(datadir)/alsa-mixer/paths
|
||||
alsaprofilesetsdir=$(datadir)/pulseaudio/alsa-mixer/profile-sets
|
||||
alsapathsdir=$(datadir)/pulseaudio/alsa-mixer/paths
|
||||
udevrulesdir=/lib/udev/rules.d
|
||||
|
||||
###################################
|
||||
|
|
@ -114,10 +114,10 @@ EXTRA_DIST = \
|
|||
modules/module-defs.h.m4 \
|
||||
daemon/pulseaudio.desktop.in \
|
||||
map-file \
|
||||
daemon/org.pulseaudio.policy.in \
|
||||
modules/alsa/mixer/profile-sets/default.conf \
|
||||
modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \
|
||||
modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf \
|
||||
modules/alsa/mixer/profile-sets/78-pulseaudio.rules \
|
||||
modules/alsa/mixer/profile-sets/90-pulseaudio.rules \
|
||||
modules/alsa/mixer/paths/analog-input-aux.conf \
|
||||
modules/alsa/mixer/paths/analog-input.conf \
|
||||
modules/alsa/mixer/paths/analog-input.conf.common \
|
||||
|
|
@ -183,16 +183,6 @@ else
|
|||
pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -dlopen force $(foreach f,$(PREOPEN_LIBS),-dlopen $(f))
|
||||
endif
|
||||
|
||||
if HAVE_POLKIT
|
||||
policy_in_files = daemon/org.pulseaudio.policy.in
|
||||
policy_DATA = $(policy_in_files:.policy.in=.policy)
|
||||
@INTLTOOL_POLICY_RULE@
|
||||
|
||||
pulseaudio_SOURCES += daemon/polkit.c daemon/polkit.h
|
||||
pulseaudio_CFLAGS += $(POLKIT_CFLAGS)
|
||||
pulseaudio_LDADD += $(POLKIT_LIBS)
|
||||
endif
|
||||
|
||||
###################################
|
||||
# Utility programs #
|
||||
###################################
|
||||
|
|
@ -572,6 +562,7 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
|
|||
pulsecore/conf-parser.c pulsecore/conf-parser.h \
|
||||
pulsecore/core-error.c pulsecore/core-error.h \
|
||||
pulsecore/core-util.c pulsecore/core-util.h \
|
||||
pulsecore/rtkit.c pulsecore/rtkit.h \
|
||||
pulsecore/creds.h \
|
||||
pulsecore/dynarray.c pulsecore/dynarray.h \
|
||||
pulsecore/endianmacros.h \
|
||||
|
|
@ -820,7 +811,6 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
|
|||
pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
|
||||
pulsecore/resampler.c pulsecore/resampler.h \
|
||||
pulsecore/rtpoll.c pulsecore/rtpoll.h \
|
||||
pulsecore/rtsig.c pulsecore/rtsig.h \
|
||||
pulsecore/sample-util.c pulsecore/sample-util.h \
|
||||
pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
|
||||
pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
|
||||
|
|
@ -1050,10 +1040,11 @@ modlibexec_LTLIBRARIES += \
|
|||
|
||||
alsaprofilesets_DATA = \
|
||||
modules/alsa/mixer/profile-sets/default.conf \
|
||||
modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \
|
||||
modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf
|
||||
|
||||
udevrules_DATA = \
|
||||
modules/alsa/mixer/profile-sets/78-pulseaudio.rules
|
||||
modules/alsa/mixer/profile-sets/90-pulseaudio.rules
|
||||
|
||||
alsapaths_DATA = \
|
||||
modules/alsa/mixer/paths/analog-input-aux.conf \
|
||||
|
|
@ -1660,11 +1651,7 @@ module_rygel_media_server_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
|
|||
# Some minor stuff #
|
||||
###################################
|
||||
|
||||
suid: pulseaudio .libs/lt-pulseaudio
|
||||
chown root $^
|
||||
chmod u+s $^
|
||||
|
||||
CLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11 daemon/pulseaudio.desktop daemon/org.pulseaudio.policy
|
||||
CLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11 daemon/pulseaudio.desktop
|
||||
|
||||
esdcompat: daemon/esdcompat.in Makefile
|
||||
sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
|
||||
|
|
@ -1741,6 +1728,11 @@ update-reserve:
|
|||
wget -O modules/$$i http://git.0pointer.de/\?p=reserve.git\;a=blob_plain\;f=$$i\;hb=master ; \
|
||||
done
|
||||
|
||||
update-rtkit:
|
||||
for i in rtkit.c rtkit.h ; do \
|
||||
wget -O pulsecore/$$i http://git.0pointer.de/\?p=rtkit.git\;a=blob_plain\;f=$$i\;hb=master ; \
|
||||
done
|
||||
|
||||
# Automatically generate linker version script. We use the same one for all public .sos
|
||||
update-map-file:
|
||||
( echo "PULSE_0 {" ; \
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#ifdef HAVE_SYS_CAPABILITY_H
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
|
@ -51,12 +52,13 @@ int setresgid(gid_t r, gid_t e, gid_t s);
|
|||
int setresuid(uid_t r, uid_t e, uid_t s);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
|
||||
/* Drop root rights when called SUID root */
|
||||
void pa_drop_root(void) {
|
||||
uid_t uid = getuid();
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
uid_t uid;
|
||||
|
||||
uid = getuid();
|
||||
if (uid == 0 || geteuid() != 0)
|
||||
return;
|
||||
|
||||
|
|
@ -73,90 +75,19 @@ void pa_drop_root(void) {
|
|||
|
||||
pa_assert_se(getuid() == uid);
|
||||
pa_assert_se(geteuid() == uid);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void pa_drop_root(void) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_SYS_PRCTL_H)
|
||||
|
||||
/* Limit permitted capabilities set to CAPSYS_NICE */
|
||||
void pa_limit_caps(void) {
|
||||
cap_t caps;
|
||||
cap_value_t nice_cap = CAP_SYS_NICE;
|
||||
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET) == 0);
|
||||
pa_assert_se(cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET) == 0);
|
||||
|
||||
if (cap_set_proc(caps) < 0)
|
||||
/* Hmm, so we couldn't limit our caps, which probably means we
|
||||
* hadn't any in the first place, so let's just make sure of
|
||||
* that */
|
||||
pa_drop_caps();
|
||||
else
|
||||
pa_log_info(_("Limited capabilities successfully to CAP_SYS_NICE."));
|
||||
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
pa_assert_se(prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == 0);
|
||||
}
|
||||
|
||||
/* Drop all capabilities, effectively becoming a normal user */
|
||||
void pa_drop_caps(void) {
|
||||
cap_t caps;
|
||||
|
||||
#ifndef __OPTIMIZE__
|
||||
/* Valgrind doesn't not know set_caps, so we bypass it here -- but
|
||||
* only in development builds.*/
|
||||
|
||||
if (pa_in_valgrind() && !pa_have_caps())
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
pa_assert_se(prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == 0);
|
||||
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_proc(caps) == 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
pa_assert_se(!pa_have_caps());
|
||||
}
|
||||
|
||||
pa_bool_t pa_have_caps(void) {
|
||||
cap_t caps;
|
||||
cap_flag_value_t flag = CAP_CLEAR;
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
pa_assert_se(caps = cap_get_proc());
|
||||
#else
|
||||
if (!(caps = cap_get_proc()))
|
||||
return FALSE;
|
||||
#endif
|
||||
pa_assert_se(cap_get_flag(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
|
||||
return flag == CAP_SET;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* NOOPs in case capabilities are not available. */
|
||||
void pa_limit_caps(void) {
|
||||
}
|
||||
|
||||
void pa_drop_caps(void) {
|
||||
pa_drop_root();
|
||||
}
|
||||
|
||||
pa_bool_t pa_have_caps(void) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_CAPABILITY_H
|
||||
{
|
||||
cap_t caps;
|
||||
pa_assert_se(caps = cap_init());
|
||||
pa_assert_se(cap_clear(caps) == 0);
|
||||
pa_assert_se(cap_set_proc(caps) == 0);
|
||||
pa_assert_se(cap_free(caps) == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,5 @@
|
|||
#include <pulsecore/macro.h>
|
||||
|
||||
void pa_drop_root(void);
|
||||
void pa_drop_caps(void);
|
||||
void pa_limit_caps(void);
|
||||
pa_bool_t pa_have_caps(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ static const pa_daemon_conf default_conf = {
|
|||
.fail = TRUE,
|
||||
.high_priority = TRUE,
|
||||
.nice_level = -11,
|
||||
.realtime_scheduling = FALSE,
|
||||
.realtime_scheduling = TRUE,
|
||||
.realtime_priority = 5, /* Half of JACK's default rtprio */
|
||||
.disallow_module_loading = FALSE,
|
||||
.disallow_exit = FALSE,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
; high-priority = yes
|
||||
; nice-level = -11
|
||||
|
||||
; realtime-scheduling = no
|
||||
; realtime-scheduling = yes
|
||||
; realtime-priority = 5
|
||||
|
||||
; exit-idle-time = 20
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@
|
|||
#include <pulsecore/pid.h>
|
||||
#include <pulsecore/namereg.h>
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/rtsig.h>
|
||||
#include <pulsecore/rtclock.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/mutex.h>
|
||||
|
|
@ -102,7 +101,6 @@
|
|||
#include "dumpmodules.h"
|
||||
#include "caps.h"
|
||||
#include "ltdl-bind-now.h"
|
||||
#include "polkit.h"
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
/* Only one instance of these variables */
|
||||
|
|
@ -381,9 +379,7 @@ int main(int argc, char *argv[]) {
|
|||
pa_mainloop *mainloop = NULL;
|
||||
char *s;
|
||||
int r = 0, retval = 1, d = 0;
|
||||
pa_bool_t suid_root, real_root;
|
||||
pa_bool_t valid_pid_file = FALSE;
|
||||
gid_t gid = (gid_t) -1;
|
||||
pa_bool_t ltdl_init = FALSE;
|
||||
int passed_fd = -1;
|
||||
const char *e;
|
||||
|
|
@ -426,30 +422,6 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
real_root = getuid() == 0;
|
||||
suid_root = !real_root && geteuid() == 0;
|
||||
#else
|
||||
real_root = FALSE;
|
||||
suid_root = FALSE;
|
||||
#endif
|
||||
|
||||
if (!real_root) {
|
||||
/* Drop all capabilities except CAP_SYS_NICE */
|
||||
pa_limit_caps();
|
||||
|
||||
/* Drop privileges, but keep CAP_SYS_NICE */
|
||||
pa_drop_root();
|
||||
|
||||
/* After dropping root, the effective set is reset, hence,
|
||||
* let's raise it again */
|
||||
pa_limit_caps();
|
||||
|
||||
/* When capabilities are not supported we will not be able to
|
||||
* acquire RT sched anymore. But yes, that's the way it is. It
|
||||
* is just too risky tun let PA run as root all the time. */
|
||||
}
|
||||
|
||||
if ((e = getenv("PULSE_PASSED_FD"))) {
|
||||
passed_fd = atoi(e);
|
||||
|
||||
|
|
@ -457,15 +429,14 @@ int main(int argc, char *argv[]) {
|
|||
passed_fd = -1;
|
||||
}
|
||||
|
||||
/* We might be autospawned, in which case have no idea in which
|
||||
* context we have been started. Let's cleanup our execution
|
||||
* context as good as possible */
|
||||
pa_drop_root();
|
||||
pa_close_all(passed_fd, -1);
|
||||
|
||||
pa_reset_sigs(-1);
|
||||
pa_unblock_sigs(-1);
|
||||
|
||||
/* At this point, we are a normal user, possibly with CAP_NICE if
|
||||
* we were started SUID. If we are started as normal root, than we
|
||||
* still are normal root. */
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
pa_init_i18n();
|
||||
|
||||
|
|
@ -490,150 +461,6 @@ int main(int argc, char *argv[]) {
|
|||
pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
|
||||
pa_log_set_show_backtrace(conf->log_backtrace);
|
||||
|
||||
pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
|
||||
|
||||
if (!real_root && pa_have_caps()) {
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
struct rlimit rl;
|
||||
#endif
|
||||
pa_bool_t allow_high_priority = FALSE, allow_realtime = FALSE;
|
||||
|
||||
/* Let's better not enable high prio or RT by default */
|
||||
|
||||
if (conf->high_priority && !allow_high_priority) {
|
||||
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
|
||||
pa_log_info(_("We're in the group '%s', allowing high-priority scheduling."), PA_REALTIME_GROUP);
|
||||
allow_high_priority = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !allow_realtime) {
|
||||
if (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) > 0) {
|
||||
pa_log_info(_("We're in the group '%s', allowing real-time scheduling."), PA_REALTIME_GROUP);
|
||||
allow_realtime = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLKIT
|
||||
if (conf->high_priority && !allow_high_priority) {
|
||||
if (pa_polkit_check("org.pulseaudio.acquire-high-priority") > 0) {
|
||||
pa_log_info(_("PolicyKit grants us acquire-high-priority privilege."));
|
||||
allow_high_priority = TRUE;
|
||||
} else
|
||||
pa_log_info(_("PolicyKit refuses acquire-high-priority privilege."));
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !allow_realtime) {
|
||||
if (pa_polkit_check("org.pulseaudio.acquire-real-time") > 0) {
|
||||
pa_log_info(_("PolicyKit grants us acquire-real-time privilege."));
|
||||
allow_realtime = TRUE;
|
||||
} else
|
||||
pa_log_info(_("PolicyKit refuses acquire-real-time privilege."));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!allow_high_priority && !allow_realtime) {
|
||||
|
||||
/* OK, there's no further need to keep CAP_NICE. Hence
|
||||
* let's give it up early */
|
||||
|
||||
pa_drop_caps();
|
||||
}
|
||||
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
|
||||
if (rl.rlim_cur > 0) {
|
||||
pa_log_info("RLIMIT_RTPRIO is set to %u, allowing real-time scheduling.", (unsigned) rl.rlim_cur);
|
||||
allow_realtime = TRUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef RLIMIT_NICE
|
||||
if (getrlimit(RLIMIT_NICE, &rl) >= 0)
|
||||
if (rl.rlim_cur > 20 ) {
|
||||
pa_log_info("RLIMIT_NICE is set to %u, allowing high-priority scheduling.", (unsigned) rl.rlim_cur);
|
||||
allow_high_priority = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((conf->high_priority && !allow_high_priority) ||
|
||||
(conf->realtime_scheduling && !allow_realtime))
|
||||
pa_log_info(_("Called SUID root and real-time and/or high-priority scheduling was requested in the configuration. However, we lack the necessary privileges:\n"
|
||||
"We are not in group '%s', PolicyKit refuse to grant us the requested privileges and we have no increase RLIMIT_NICE/RLIMIT_RTPRIO resource limits.\n"
|
||||
"For enabling real-time/high-priority scheduling please acquire the appropriate PolicyKit privileges, or become a member of '%s', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."),
|
||||
PA_REALTIME_GROUP, PA_REALTIME_GROUP);
|
||||
|
||||
|
||||
if (!allow_realtime)
|
||||
conf->realtime_scheduling = FALSE;
|
||||
|
||||
if (!allow_high_priority)
|
||||
conf->high_priority = FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
/* Reset resource limits. If we are run as root (for system mode)
|
||||
* this might end up increasing the limits, which is intended
|
||||
* behaviour. For all other cases, i.e. started as normal user, or
|
||||
* SUID root at this point we should have no CAP_SYS_RESOURCE and
|
||||
* increasing the limits thus should fail. Which is, too, intended
|
||||
* behaviour */
|
||||
|
||||
set_all_rlimits(conf);
|
||||
#endif
|
||||
|
||||
if (conf->high_priority && !pa_can_high_priority()) {
|
||||
pa_log_info(_("High-priority scheduling enabled in configuration but not allowed by policy."));
|
||||
conf->high_priority = FALSE;
|
||||
}
|
||||
|
||||
if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
|
||||
pa_raise_priority(conf->nice_level);
|
||||
|
||||
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
|
||||
|
||||
if (!real_root && pa_have_caps()) {
|
||||
pa_bool_t drop;
|
||||
|
||||
drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
|
||||
|
||||
#ifdef RLIMIT_RTPRIO
|
||||
if (!drop) {
|
||||
struct rlimit rl;
|
||||
/* At this point we still have CAP_NICE if we were loaded
|
||||
* SUID root. If possible let's acquire RLIMIT_RTPRIO
|
||||
* instead and give CAP_NICE up. */
|
||||
|
||||
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
|
||||
|
||||
if (rl.rlim_cur >= 9)
|
||||
drop = TRUE;
|
||||
else {
|
||||
rl.rlim_max = rl.rlim_cur = 9;
|
||||
|
||||
if (setrlimit(RLIMIT_RTPRIO, &rl) >= 0) {
|
||||
pa_log_info(_("Successfully increased RLIMIT_RTPRIO"));
|
||||
drop = TRUE;
|
||||
} else
|
||||
pa_log_warn(_("RLIMIT_RTPRIO failed: %s"), pa_cstrerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (drop) {
|
||||
pa_log_info(_("Giving up CAP_NICE"));
|
||||
pa_drop_caps();
|
||||
suid_root = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->realtime_scheduling && !pa_can_realtime()) {
|
||||
pa_log_info(_("Real-time scheduling enabled in configuration but not allowed by policy."));
|
||||
conf->realtime_scheduling = FALSE;
|
||||
}
|
||||
|
||||
pa_log_debug("Can realtime: %s, can high-priority: %s", pa_yes_no(pa_can_realtime()), pa_yes_no(pa_can_high_priority()));
|
||||
|
||||
LTDL_SET_PRELOADED_SYMBOLS();
|
||||
pa_ltdl_init();
|
||||
ltdl_init = TRUE;
|
||||
|
|
@ -718,9 +545,9 @@ int main(int argc, char *argv[]) {
|
|||
pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
|
||||
}
|
||||
|
||||
if (real_root && !conf->system_instance)
|
||||
if (getuid() == 0 && !conf->system_instance)
|
||||
pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
|
||||
else if (!real_root && conf->system_instance) {
|
||||
else if (getuid() != 0 && conf->system_instance) {
|
||||
pa_log(_("Root privileges required."));
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -866,6 +693,13 @@ int main(int argc, char *argv[]) {
|
|||
pa_assert_se(chdir("/") == 0);
|
||||
umask(0022);
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
set_all_rlimits(conf);
|
||||
#endif
|
||||
pa_rtclock_hrtimer_enable();
|
||||
|
||||
pa_raise_priority(conf->nice_level);
|
||||
|
||||
if (conf->system_instance)
|
||||
if (change_user() < 0)
|
||||
goto finish;
|
||||
|
|
@ -914,8 +748,8 @@ int main(int argc, char *argv[]) {
|
|||
pa_xfree(s);
|
||||
|
||||
if ((s = pa_session_id())) {
|
||||
pa_log_info(_("Session ID is %s."), s);
|
||||
pa_xfree(s);
|
||||
pa_log_info(_("Session ID is %s."), s);
|
||||
pa_xfree(s);
|
||||
}
|
||||
|
||||
if (!(s = pa_get_runtime_dir()))
|
||||
|
|
@ -962,13 +796,6 @@ int main(int argc, char *argv[]) {
|
|||
else
|
||||
pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"));
|
||||
|
||||
pa_rtclock_hrtimer_enable();
|
||||
|
||||
#ifdef SIGRTMIN
|
||||
/* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */
|
||||
pa_rtsig_configure(SIGRTMIN, SIGRTMAX-1);
|
||||
#endif
|
||||
|
||||
if (conf->lock_memory) {
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
if (mlockall(MCL_FUTURE) < 0)
|
||||
|
|
|
|||
|
|
@ -479,6 +479,7 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
snd_mixer_elem_t *me;
|
||||
snd_mixer_selem_channel_id_t c;
|
||||
pa_channel_position_mask_t mask = 0;
|
||||
pa_volume_t max_channel_volume = PA_VOLUME_MUTED;
|
||||
unsigned k;
|
||||
|
||||
pa_assert(m);
|
||||
|
|
@ -545,6 +546,9 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
f = from_alsa_volume(value, e->min_volume, e->max_volume);
|
||||
}
|
||||
|
||||
if (f > max_channel_volume)
|
||||
max_channel_volume = f;
|
||||
|
||||
for (k = 0; k < cm->channels; k++)
|
||||
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
|
||||
if (v->values[k] < f)
|
||||
|
|
@ -555,7 +559,7 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
|
||||
for (k = 0; k < cm->channels; k++)
|
||||
if (!(mask & PA_CHANNEL_POSITION_MASK(cm->map[k])))
|
||||
v->values[k] = PA_VOLUME_NORM;
|
||||
v->values[k] = max_channel_volume;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -677,6 +681,7 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
snd_mixer_elem_t *me;
|
||||
snd_mixer_selem_channel_id_t c;
|
||||
pa_channel_position_mask_t mask = 0;
|
||||
pa_volume_t max_channel_volume = PA_VOLUME_MUTED;
|
||||
unsigned k;
|
||||
|
||||
pa_assert(m);
|
||||
|
|
@ -696,11 +701,21 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
|
||||
int r;
|
||||
pa_volume_t f = PA_VOLUME_MUTED;
|
||||
pa_bool_t found = FALSE;
|
||||
|
||||
for (k = 0; k < cm->channels; k++)
|
||||
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
|
||||
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k])) {
|
||||
found = TRUE;
|
||||
if (v->values[k] > f)
|
||||
f = v->values[k];
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
/* Hmm, so this channel does not exist in the volume
|
||||
* struct, so let's bind it to the overall max of the
|
||||
* volume. */
|
||||
f = pa_cvolume_max(v);
|
||||
}
|
||||
|
||||
if (e->has_dB) {
|
||||
long value = to_alsa_dB(f);
|
||||
|
|
@ -756,6 +771,9 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
f = from_alsa_volume(value, e->min_volume, e->max_volume);
|
||||
}
|
||||
|
||||
if (f > max_channel_volume)
|
||||
max_channel_volume = f;
|
||||
|
||||
for (k = 0; k < cm->channels; k++)
|
||||
if (e->masks[c][e->n_channels-1] & PA_CHANNEL_POSITION_MASK(cm->map[k]))
|
||||
if (rv.values[k] < f)
|
||||
|
|
@ -766,7 +784,7 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
|
|||
|
||||
for (k = 0; k < cm->channels; k++)
|
||||
if (!(mask & PA_CHANNEL_POSITION_MASK(cm->map[k])))
|
||||
rv.values[k] = PA_VOLUME_NORM;
|
||||
rv.values[k] = max_channel_volume;
|
||||
|
||||
*v = rv;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -838,7 +838,6 @@ static int unsuspend(struct userdata *u) {
|
|||
|
||||
pa_log_info("Trying resume...");
|
||||
|
||||
snd_config_update_free_global();
|
||||
if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK,
|
||||
/*SND_PCM_NONBLOCK|*/
|
||||
SND_PCM_NO_AUTO_RESAMPLE|
|
||||
|
|
@ -1213,7 +1212,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -787,8 +787,6 @@ static int unsuspend(struct userdata *u) {
|
|||
|
||||
pa_log_info("Trying resume...");
|
||||
|
||||
snd_config_update_free_global();
|
||||
|
||||
if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
|
||||
/*SND_PCM_NONBLOCK|*/
|
||||
SND_PCM_NO_AUTO_RESAMPLE|
|
||||
|
|
@ -1096,7 +1094,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -735,20 +735,22 @@ static void alsa_error_handler(const char *file, int line, const char *function,
|
|||
|
||||
static pa_atomic_t n_error_handler_installed = PA_ATOMIC_INIT(0);
|
||||
|
||||
void pa_alsa_redirect_errors_inc(void) {
|
||||
void pa_alsa_refcnt_inc(void) {
|
||||
/* This is not really thread safe, but we do our best */
|
||||
|
||||
if (pa_atomic_inc(&n_error_handler_installed) == 0)
|
||||
snd_lib_error_set_handler(alsa_error_handler);
|
||||
}
|
||||
|
||||
void pa_alsa_redirect_errors_dec(void) {
|
||||
void pa_alsa_refcnt_dec(void) {
|
||||
int r;
|
||||
|
||||
pa_assert_se((r = pa_atomic_dec(&n_error_handler_installed)) >= 1);
|
||||
|
||||
if (r == 1)
|
||||
if (r == 1) {
|
||||
snd_lib_error_set_handler(NULL);
|
||||
snd_config_update_free_global();
|
||||
}
|
||||
}
|
||||
|
||||
pa_bool_t pa_alsa_init_description(pa_proplist *p) {
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@ snd_pcm_t *pa_alsa_open_by_template(
|
|||
void pa_alsa_dump(pa_log_level_t level, snd_pcm_t *pcm);
|
||||
void pa_alsa_dump_status(snd_pcm_t *pcm);
|
||||
|
||||
void pa_alsa_redirect_errors_inc(void);
|
||||
void pa_alsa_redirect_errors_dec(void);
|
||||
void pa_alsa_refcnt_inc(void);
|
||||
void pa_alsa_refcnt_dec(void);
|
||||
|
||||
void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info);
|
||||
void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices, where we have an Aux element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where an 'Aux' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 90
|
||||
|
|
@ -29,4 +47,16 @@ override-map.2 = all-left,all-right
|
|||
switch = off
|
||||
volume = off
|
||||
|
||||
[Element Mic/Line]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
[Element TV Tuner]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
[Element FM]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
.include analog-input.conf.common
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices where we have an FM element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where an 'FM' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 70
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices, where we have a Line element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where a 'Line' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 90
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices where we have a Mic/Lineb element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where a 'Mic/Line' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 90
|
||||
|
|
@ -42,3 +60,4 @@ switch = off
|
|||
volume = off
|
||||
|
||||
.include analog-input.conf.common
|
||||
.include analog-input-mic.conf.common
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices where we have a Mic element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where a 'Mic' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 100
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Common element for all microphone inputs
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
;;; 'Mic Select'
|
||||
|
||||
[Element Mic Select]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices, where we have a TV Tuner element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where a 'TV Tuner' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 70
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# For devices, where we have a Video element
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; For devices where a 'Video' element exists
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 70
|
||||
|
|
@ -28,4 +46,16 @@ volume = merge
|
|||
override-map.1 = all
|
||||
override-map.2 = all-left,all-right
|
||||
|
||||
[Element Mic/Line]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
[Element TV Tuner]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
[Element FM]
|
||||
switch = off
|
||||
volume = off
|
||||
|
||||
.include analog-input.conf.common
|
||||
|
|
|
|||
|
|
@ -1,4 +1,23 @@
|
|||
# A fallback for devices that lack seperate Mic/Line/Aux/Video elements
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; A fallback for devices that lack seperate Mic/Line/Aux/Video/TV
|
||||
; Tuner/FM elements
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 100
|
||||
|
|
|
|||
|
|
@ -1,30 +1,48 @@
|
|||
# Mixer path for PulseAudio's ALSA backend. If multiple options by the
|
||||
# same id are discovered they will be suffixed with a number to
|
||||
# distuingish them, in the same order they appear here.
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# Source selection should use the following names:
|
||||
# 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.
|
||||
#
|
||||
# input -- If we don't know the exact kind of input
|
||||
# input-microphone
|
||||
# input-microphone-internal
|
||||
# input-microphone-external
|
||||
# input-linein
|
||||
# input-video
|
||||
# input-radio
|
||||
# input-docking-microphone
|
||||
# input-docking-linein
|
||||
# input-docking
|
||||
#
|
||||
# We explicitly don't want to wrap the following sources:
|
||||
#
|
||||
# CD
|
||||
# Synth/MIDI
|
||||
# Phone
|
||||
# Mix
|
||||
# Digital/SPDIF
|
||||
# Master
|
||||
# PC Speaker
|
||||
# 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.
|
||||
|
||||
; Mixer path for PulseAudio's ALSA backend, common elements for all
|
||||
; input paths. If multiple options by the same id are discovered they
|
||||
; will be suffixed with a number to distuingish them, in the same
|
||||
; order they appear here.
|
||||
;
|
||||
; Source selection should use the following names:
|
||||
;
|
||||
; input -- If we don't know the exact kind of input
|
||||
; input-microphone
|
||||
; input-microphone-internal
|
||||
; input-microphone-external
|
||||
; input-linein
|
||||
; input-video
|
||||
; input-radio
|
||||
; input-docking-microphone
|
||||
; input-docking-linein
|
||||
; input-docking
|
||||
;
|
||||
; We explicitly don't want to wrap the following sources:
|
||||
;
|
||||
; CD
|
||||
; Synth/MIDI
|
||||
; Phone
|
||||
; Mix
|
||||
; Digital/SPDIF
|
||||
; Master
|
||||
; PC Speaker
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
;;; 'Input Source Select'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# Path for mixers that have a Headphone slider
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Path for mixers that have a 'Headphone' control
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 90
|
||||
|
|
|
|||
|
|
@ -1,5 +1,23 @@
|
|||
# Intended for usage in laptops that have a seperate LFE speaker
|
||||
# connected to the Master mono connector
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Intended for usage in laptops that have a seperate LFE speaker
|
||||
; connected to the Master mono connector
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 40
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# Intended for usage on boards that have a seperate Mono output plug.
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Intended for usage on boards that have a seperate Mono output plug.
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 50
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
# Intended for the 'default' output
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Intended for the 'default' output
|
||||
;
|
||||
; See analog-output.conf.common for an explanation on the directives
|
||||
|
||||
[General]
|
||||
priority = 100
|
||||
|
|
|
|||
|
|
@ -1,26 +1,97 @@
|
|||
# Common part of all paths
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
# [General]
|
||||
# priority = ...
|
||||
# description = ...
|
||||
#
|
||||
# [Option ...:...]
|
||||
# name = ...
|
||||
# priority = ...
|
||||
#
|
||||
# [Element ...]
|
||||
# required = ignore | switch | volume | enumeration | any
|
||||
# required-absent = ignore | switch | volume
|
||||
#
|
||||
# switch = ignore | mute | off | on | select
|
||||
# volume = ignore | merge | off | zero
|
||||
# enumeration = ignore | select
|
||||
#
|
||||
# direction = playback | capture
|
||||
# direction-try-other = no | yes
|
||||
#
|
||||
# override-map.1 = ...
|
||||
# override-map.2 = ...
|
||||
; Common part of all paths
|
||||
|
||||
; So here's generally how mixer paths are used by PA: PA goes through
|
||||
; a mixer path file from top to bottom and checks if a mixer element
|
||||
; described therein exists. If so it is added to the list of mixer
|
||||
; elements PA will control, keeping the order it read them in. If a
|
||||
; mixer element described here has set the required= or
|
||||
; required-absent= directives a path might not be accepted as valid
|
||||
; and is ignored in its entirety (see below). However usually if a
|
||||
; element listed here is missing this one element is ignored but not
|
||||
; the entire path.
|
||||
;
|
||||
; When a device shall be muted/unmuted *all* elements listed in a path
|
||||
; file with "switch = mute" will be toggled.
|
||||
;
|
||||
; When a device shall change its volume, PA will got through the list
|
||||
; of all elements with "volume = merge" and set the volume on the
|
||||
; first element. If that element does not support dB volumes, this is
|
||||
; where the story ends. If it does support dB volumes, PA divides the
|
||||
; requested volume by the volume that was set on this element, and
|
||||
; then go on to the next element with "volume = merge" and then set
|
||||
; that there, and so on. That way the first volume element in the
|
||||
; path will be the one that does the 'biggest' part of the overall
|
||||
; volume adjustment, with the remaining elements usually being set to
|
||||
; some value next to 0dB. This logic makes sure we get the full range
|
||||
; over all volume sliders and a very high granularity of volumes
|
||||
; already in hardware.
|
||||
;
|
||||
; All switches and enumerations set to "select" are exposed via the
|
||||
; "port" functionality of sinks/sources. Basically every possible
|
||||
; switch setting and every possible enumeration setting will be
|
||||
; combined and made into a "port". So make sure you don't list too
|
||||
; many switches/enums for exposing, because the number of ports might
|
||||
; rise exponentially.
|
||||
;
|
||||
; Only one path can be selected at a time. All paths that are valid
|
||||
; for an audio device will be exposed as "port" for the sink/source.
|
||||
|
||||
|
||||
; [General]
|
||||
; priority = ... # Priority for this path
|
||||
; description = ...
|
||||
;
|
||||
; [Option ...:...] # For each option of an enumeration or switch element
|
||||
; # that shall be exposed as a sink/source port. Needs to
|
||||
; # be named after the Element, followed by a colon, followed
|
||||
; # by the option name, resp. on/off if the element is a switch.
|
||||
; name = ... # Logical name to use in the path identifier
|
||||
; priority = ... # Priority if this is made into a device port
|
||||
;
|
||||
; [Element ...] # For each element that we shall control
|
||||
; required = ignore | switch | volume | enumeration | any # If set, require this element to be of this kind and available,
|
||||
; # otherwise don't consider this path valid for the card
|
||||
; required-absent = ignore | switch | volume # If set, require this element to not be of this kind and not
|
||||
; # available, otherwise don't consider this path valid for the card
|
||||
;
|
||||
; switch = ignore | mute | off | on | select # What to do with this switch: ignore it, make it follow mute status,
|
||||
; # always set it to off, always to on, or make it selectable as port.
|
||||
; # If set to 'select' you need to define an Option section for on
|
||||
; # and off
|
||||
; volume = ignore | merge | off | zero # What to do with this volume: ignore it, merge it into the device
|
||||
; # volume slider, always set it to the lowest value possible, or always
|
||||
; # set it to 0 dB (for whatever that means)
|
||||
; enumeration = ignore | select # What to do with this enumeration, ignore it or make it selectable
|
||||
; # via device ports. If set to 'select' you need to define an Option section
|
||||
; # for each of the items you want to expose
|
||||
; direction = playback | capture # Is this relevant only for playback or capture? If not set this will implicitly be
|
||||
; # set the direction of the PCM device is opened as. Generally this doesn't need to be set
|
||||
; # unless you have a broken driver that has playback controls marked for capture or vice
|
||||
; # versa
|
||||
; direction-try-other = no | yes # If the element does not supported what is requested, try the other direction, too?
|
||||
;
|
||||
; override-map.1 = ... # Override the channel mask of the mixer control if the control only exposes a single channel
|
||||
; override-map.2 = ... # Override the channel masks of the mixer control if the control only exposes two channels
|
||||
; # Override maps should list for each element channel which high-level channels it controls via a
|
||||
; # channel mask. A channel mask may either be the name of a single channel, or the words "all-left",
|
||||
; # "all-right", "all-center", "all-front", "all-rear", and "all" to encode a specific subset of
|
||||
; # channels in a mask
|
||||
|
||||
[Element PCM]
|
||||
switch = mute
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
# do not edit this file, it will be overwritten on update
|
||||
|
||||
SUBSYSTEM!="sound", GOTO="pulseaudio_end"
|
||||
ACTION!="change", GOTO="pulseaudio_end"
|
||||
KERNEL!="card*", GOTO="pulseaudio_end"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1978", ENV{PULSE_PROFILE_SET}="native-instruments-audio8dj.conf"
|
||||
|
||||
LABEL="pulseaudio_end"
|
||||
26
src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
Normal file
26
src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# do not edit this file, it will be overwritten on update
|
||||
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
SUBSYSTEM!="sound", GOTO="pulseaudio_end"
|
||||
ACTION!="change", GOTO="pulseaudio_end"
|
||||
KERNEL!="card*", GOTO="pulseaudio_end"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1978", ENV{PULSE_PROFILE_SET}="native-instruments-audio8dj.conf"
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="0839", ENV{PULSE_PROFILE_SET}="native-instruments-audio4dj.conf"
|
||||
|
||||
LABEL="pulseaudio_end"
|
||||
|
|
@ -1,22 +1,60 @@
|
|||
# Profile definitions for PulseAudio's ALSA backend
|
||||
# This file is part of PulseAudio.
|
||||
#
|
||||
# [Mapping id]
|
||||
# device-strings = ...
|
||||
# channel-map = ...
|
||||
# description = ...
|
||||
# paths-input = ...
|
||||
# paths-output = ...
|
||||
# element-input = ...
|
||||
# element-output = ...
|
||||
# priority = ...
|
||||
# direction = any | input | output
|
||||
# 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.
|
||||
#
|
||||
# [Profile id]
|
||||
# input-mappings = ...
|
||||
# output-mappings = ...
|
||||
# description = ...
|
||||
# priority = ...
|
||||
# skip-probe = no | yes
|
||||
# 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.
|
||||
|
||||
; Default profile definitions for the ALSA backend of PulseAudio. This
|
||||
; is used as fallback for all cards that have no special mapping
|
||||
; assigned. (and should be good enough for the vast majority of
|
||||
; cards). Use the udev property PULSE_PROFILE_SET to assign a
|
||||
; different profile set than this one to a device. So what is this
|
||||
; about? Simply, what we do here is map ALSA devices to how they are
|
||||
; exposed in PA. We say which ALSA device string to use to open a
|
||||
; device, which channel mapping to use then, and which mixer path to
|
||||
; use. This is encoded in a 'mapping'. Multiple of these mappings can
|
||||
; be bound together in a 'profile' which is then directly exposed in
|
||||
; the UI as a card profile. Each mapping assigned to a profile will
|
||||
; result in one sink/source to be created if the profile is selected
|
||||
; for the card.
|
||||
|
||||
; [General]
|
||||
; auto-profiles = no | yes # Instead of defining all profiles manually, autogenerate
|
||||
; # them by combining every input mapping with every output mapping.
|
||||
;
|
||||
; [Mapping id]
|
||||
; device-strings = ... # ALSA device string. %f will be replaced by the card identifier.
|
||||
; channel-map = ... # Channel mapping to use for this device
|
||||
; description = ...
|
||||
; paths-input = ... # A list of mixer paths to use. Every path in this list will be probed.
|
||||
; # If multiple are found to be working they will be available as device ports
|
||||
; paths-output = ...
|
||||
; element-input = ... # Instead of configuring a full mixer path simply configure a single
|
||||
; # mixer element for volume/mute handling
|
||||
; element-output = ...
|
||||
; priority = ...
|
||||
; direction = any | input | output # Only useful for?
|
||||
;
|
||||
; [Profile id]
|
||||
; input-mappings = ... # Lists mappings for sources on this profile, those mapping must be
|
||||
; # defined in this file too
|
||||
; output-mappings = ... # Lists mappings for sinks on this profile, those mappings must be
|
||||
; # defined in this file too
|
||||
; description = ...
|
||||
; priority = ... # Numeric value to deduce priority for this profile
|
||||
; skip-probe = no | yes # Skip probing for availability? If this is yes then this profile
|
||||
; # will be assumed as working without probing. Makes initialization
|
||||
; # a bit faster but only works if the card is really known well.
|
||||
|
||||
[General]
|
||||
auto-profiles = yes
|
||||
|
|
@ -99,6 +137,7 @@ channel-map = left,right
|
|||
priority = 4
|
||||
direction = output
|
||||
|
||||
; An example for defining multiple-sink profiles
|
||||
#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
|
||||
#description = Foobar
|
||||
#output-mappings = analog-stereo iec958-stereo
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
# This file is part of PulseAudio.
|
||||
#
|
||||
# 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
|
||||
# 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.
|
||||
|
||||
; Native Instruments Audio 4 DJ
|
||||
;
|
||||
; This card has two stereo pairs of input and two stereo pairs of
|
||||
; output, named channels A and B. Channel B has an additional
|
||||
; Headphone connector.
|
||||
;
|
||||
; We knowingly only define a subset of the theoretically possible
|
||||
; mapping combinations as profiles here.
|
||||
;
|
||||
; See default.conf for an explanation on the directives used here.
|
||||
|
||||
[General]
|
||||
auto-profiles = no
|
||||
|
||||
[Mapping analog-stereo-a]
|
||||
description = Analog Stereo Channel A
|
||||
device-strings = hw:%f,0,0
|
||||
channel-map = left,right
|
||||
|
||||
[Mapping analog-stereo-b-output]
|
||||
description = Analog Stereo Channel B (Headphones)
|
||||
device-strings = hw:%f,0,1
|
||||
channel-map = left,right
|
||||
direction = output
|
||||
|
||||
[Mapping analog-stereo-b-input]
|
||||
description = Analog Stereo Channel B
|
||||
device-strings = hw:%f,0,1
|
||||
channel-map = left,right
|
||||
direction = input
|
||||
|
||||
[Profile output:analog-stereo-all+input:analog-stereo-all]
|
||||
description = Analog Stereo Duplex Channels A, B (Headphones)
|
||||
output-mappings = analog-stereo-a analog-stereo-b-output
|
||||
input-mappings = analog-stereo-a analog-stereo-b-input
|
||||
priority = 100
|
||||
skip-probe = yes
|
||||
|
||||
[Profile output:analog-stereo-a+input:analog-stereo-a]
|
||||
description = Analog Stereo Duplex Channel A
|
||||
output-mappings = analog-stereo-a
|
||||
input-mappings = analog-stereo-a
|
||||
priority = 40
|
||||
skip-probe = yes
|
||||
|
||||
[Profile output:analog-stereo-b+input:analog-stereo-b]
|
||||
description = Analog Stereo Duplex Channel B (Headphones)
|
||||
output-mappings = analog-stereo-b-output
|
||||
input-mappings = analog-stereo-b-input
|
||||
priority = 50
|
||||
skip-probe = yes
|
||||
|
||||
[Profile output:analog-stereo-a]
|
||||
description = Analog Stereo Output Channel A
|
||||
output-mappings = analog-stereo-a
|
||||
priority = 5
|
||||
skip-probe = yes
|
||||
|
||||
[Profile output:analog-stereo-b]
|
||||
description = Analog Stereo Output Channel B (Headphones)
|
||||
output-mappings = analog-stereo-b-output
|
||||
priority = 6
|
||||
skip-probe = yes
|
||||
|
||||
[Profile input:analog-stereo-a]
|
||||
description = Analog Stereo Input Channel A
|
||||
input-mappings = analog-stereo-a
|
||||
priority = 2
|
||||
skip-probe = yes
|
||||
|
||||
[Profile input:analog-stereo-b]
|
||||
description = Analog Stereo Input Channel B
|
||||
input-mappings = analog-stereo-b-input
|
||||
priority = 1
|
||||
skip-probe = yes
|
||||
|
|
@ -22,6 +22,8 @@
|
|||
;
|
||||
; We knowingly only define a subset of the theoretically possible
|
||||
; mapping combinations as profiles here.
|
||||
;
|
||||
; See default.conf for an explanation on the directives used here.
|
||||
|
||||
[General]
|
||||
auto-profiles = no
|
||||
|
|
|
|||
|
|
@ -287,8 +287,7 @@ int pa__init(pa_module *m) {
|
|||
const char *description;
|
||||
char *fn = NULL;
|
||||
|
||||
pa_alsa_redirect_errors_inc();
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_refcnt_inc();
|
||||
|
||||
pa_assert(m);
|
||||
|
||||
|
|
@ -443,6 +442,5 @@ void pa__done(pa_module*m) {
|
|||
pa_xfree(u);
|
||||
|
||||
finish:
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_redirect_errors_dec();
|
||||
pa_alsa_refcnt_dec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,8 +82,7 @@ int pa__init(pa_module*m) {
|
|||
|
||||
pa_assert(m);
|
||||
|
||||
pa_alsa_redirect_errors_inc();
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_refcnt_inc();
|
||||
|
||||
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
||||
pa_log("Failed to parse module arguments");
|
||||
|
|
@ -124,6 +123,5 @@ void pa__done(pa_module*m) {
|
|||
if ((sink = m->userdata))
|
||||
pa_alsa_sink_free(sink);
|
||||
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_redirect_errors_dec();
|
||||
pa_alsa_refcnt_dec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,8 +106,7 @@ int pa__init(pa_module*m) {
|
|||
|
||||
pa_assert(m);
|
||||
|
||||
pa_alsa_redirect_errors_inc();
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_refcnt_inc();
|
||||
|
||||
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
||||
pa_log("Failed to parse module arguments");
|
||||
|
|
@ -148,6 +147,5 @@ void pa__done(pa_module*m) {
|
|||
if ((source = m->userdata))
|
||||
pa_alsa_source_free(source);
|
||||
|
||||
snd_config_update_free_global();
|
||||
pa_alsa_redirect_errors_dec();
|
||||
pa_alsa_refcnt_dec();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1265,7 +1265,6 @@ static void thread_func(void *userdata) {
|
|||
goto fail;
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
struct pollfd *pollfd;
|
||||
|
|
|
|||
|
|
@ -225,7 +225,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -280,7 +280,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority+1);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
u->thread_info.timestamp = pa_rtclock_usec();
|
||||
u->thread_info.in_null_mode = FALSE;
|
||||
|
|
|
|||
|
|
@ -200,7 +200,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
u->timestamp = pa_rtclock_usec();
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
struct pollfd *pollfd;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -166,7 +166,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
u->timestamp = pa_rtclock_usec();
|
||||
|
||||
|
|
|
|||
|
|
@ -683,7 +683,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -889,7 +889,6 @@ static void thread_func(void *userdata) {
|
|||
pa_make_realtime(u->core->realtime_priority);
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -323,7 +323,6 @@ static void thread_func(void *userdata) {
|
|||
pa_log_debug("Thread starting up");
|
||||
|
||||
pa_thread_mq_install(&u->thread_mq);
|
||||
pa_rtpoll_install(u->rtpoll);
|
||||
|
||||
pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@
|
|||
|
||||
#ifdef HAVE_SCHED_H
|
||||
#include <sched.h>
|
||||
|
||||
#if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
|
||||
#define SCHED_RESET_ON_FORK 0x40000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
|
|
@ -92,6 +96,10 @@
|
|||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include "rtkit.h"
|
||||
#endif
|
||||
|
||||
#include <pulse/xmalloc.h>
|
||||
#include <pulse/util.h>
|
||||
#include <pulse/utf8.h>
|
||||
|
|
@ -552,46 +560,78 @@ char *pa_strlcpy(char *b, const char *s, size_t l) {
|
|||
return b;
|
||||
}
|
||||
|
||||
static int set_scheduler(int rtprio) {
|
||||
struct sched_param sp;
|
||||
int r;
|
||||
#ifdef HAVE_DBUS
|
||||
DBusError error;
|
||||
DBusConnection *bus;
|
||||
|
||||
dbus_error_init(&error);
|
||||
#endif
|
||||
|
||||
pa_zero(sp);
|
||||
sp.sched_priority = rtprio;
|
||||
|
||||
#ifdef SCHED_RESET_ON_FORK
|
||||
if ((r = pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp)) == 0) {
|
||||
pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((r = pthread_setschedparam(pthread_self(), SCHED_RR, &sp)) == 0) {
|
||||
pa_log_debug("SCHED_RR worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* Try to talk to RealtimeKit */
|
||||
|
||||
if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
|
||||
pa_log("Failed to connect to system bus: %s\n", error.message);
|
||||
dbus_error_free(&error);
|
||||
errno = -EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = rtkit_make_realtime(bus, 0, rtprio);
|
||||
dbus_connection_unref(bus);
|
||||
|
||||
if (r >= 0) {
|
||||
pa_log_debug("RealtimeKit worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = -r;
|
||||
#else
|
||||
errno = r;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make the current thread a realtime thread, and acquire the highest
|
||||
* rtprio we can get that is less or equal the specified parameter. If
|
||||
* the thread is already realtime, don't do anything. */
|
||||
int pa_make_realtime(int rtprio) {
|
||||
|
||||
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||
struct sched_param sp;
|
||||
int r, policy;
|
||||
int p;
|
||||
|
||||
memset(&sp, 0, sizeof(sp));
|
||||
policy = 0;
|
||||
|
||||
if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) {
|
||||
pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (policy == SCHED_FIFO && sp.sched_priority >= rtprio) {
|
||||
pa_log_info("Thread already being scheduled with SCHED_FIFO with priority %i.", sp.sched_priority);
|
||||
if (set_scheduler(rtprio) >= 0) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i.", rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp.sched_priority = rtprio;
|
||||
if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) {
|
||||
|
||||
while (sp.sched_priority > 1) {
|
||||
sp.sched_priority --;
|
||||
|
||||
if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) == 0) {
|
||||
pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i, which is lower than the requested %i.", sp.sched_priority, rtprio);
|
||||
return 0;
|
||||
}
|
||||
for (p = rtprio-1; p >= 1; p--)
|
||||
if (set_scheduler(p)) {
|
||||
pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
|
||||
return 0;
|
||||
pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
#else
|
||||
|
||||
errno = ENOTSUP;
|
||||
|
|
@ -599,80 +639,42 @@ int pa_make_realtime(int rtprio) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/* This is merely used for giving the user a hint. This is not correct
|
||||
* for anything security related */
|
||||
pa_bool_t pa_can_realtime(void) {
|
||||
static int set_nice(int nice_level) {
|
||||
#ifdef HAVE_DBUS
|
||||
DBusError error;
|
||||
DBusConnection *bus;
|
||||
int r;
|
||||
|
||||
if (geteuid() == 0)
|
||||
return TRUE;
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
|
||||
{
|
||||
struct rlimit rl;
|
||||
|
||||
if (getrlimit(RLIMIT_RTPRIO, &rl) >= 0)
|
||||
if (rl.rlim_cur > 0 || rl.rlim_cur == RLIM_INFINITY)
|
||||
return TRUE;
|
||||
}
|
||||
dbus_error_init(&error);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
|
||||
{
|
||||
cap_t cap;
|
||||
|
||||
if ((cap = cap_get_proc())) {
|
||||
cap_flag_value_t flag = CAP_CLEAR;
|
||||
|
||||
if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
|
||||
if (flag == CAP_SET) {
|
||||
cap_free(cap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cap_free(cap);
|
||||
}
|
||||
if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
|
||||
pa_log_debug("setpriority() worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
/* Try to talk to RealtimeKit */
|
||||
|
||||
if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
|
||||
pa_log("Failed to connect to system bus: %s\n", error.message);
|
||||
dbus_error_free(&error);
|
||||
errno = -EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = rtkit_make_high_priority(bus, 0, nice_level);
|
||||
dbus_connection_unref(bus);
|
||||
|
||||
if (r >= 0) {
|
||||
pa_log_debug("RealtimeKit worked.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = -r;
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This is merely used for giving the user a hint. This is not correct
|
||||
* for anything security related */
|
||||
pa_bool_t pa_can_high_priority(void) {
|
||||
|
||||
if (geteuid() == 0)
|
||||
return TRUE;
|
||||
|
||||
#if defined(HAVE_SYS_RESOURCE_H) && defined(RLIMIT_RTPRIO)
|
||||
{
|
||||
struct rlimit rl;
|
||||
|
||||
if (getrlimit(RLIMIT_NICE, &rl) >= 0)
|
||||
if (rl.rlim_cur >= 21 || rl.rlim_cur == RLIM_INFINITY)
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_NICE)
|
||||
{
|
||||
cap_t cap;
|
||||
|
||||
if ((cap = cap_get_proc())) {
|
||||
cap_flag_value_t flag = CAP_CLEAR;
|
||||
|
||||
if (cap_get_flag(cap, CAP_SYS_NICE, CAP_EFFECTIVE, &flag) >= 0)
|
||||
if (flag == CAP_SET) {
|
||||
cap_free(cap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cap_free(cap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Raise the priority of the current process as much as possible that
|
||||
|
|
@ -680,22 +682,21 @@ pa_bool_t pa_can_high_priority(void) {
|
|||
int pa_raise_priority(int nice_level) {
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
if (setpriority(PRIO_PROCESS, 0, nice_level) < 0) {
|
||||
int n;
|
||||
int n;
|
||||
|
||||
for (n = nice_level+1; n < 0; n++) {
|
||||
|
||||
if (setpriority(PRIO_PROCESS, 0, n) == 0) {
|
||||
pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pa_log_warn("setpriority(): %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
if (set_nice(nice_level) >= 0) {
|
||||
pa_log_info("Successfully gained nice level %i.", nice_level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully gained nice level %i.", nice_level);
|
||||
for (n = nice_level+1; n < 0; n++)
|
||||
if (set_nice(n) > 0) {
|
||||
pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa_log_info("Failed to acquire high-priority scheduling: %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
|
|
@ -703,9 +704,10 @@ int pa_raise_priority(int nice_level) {
|
|||
if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
|
||||
pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
|
||||
errno = EPERM;
|
||||
return .-1;
|
||||
} else
|
||||
pa_log_info("Successfully gained high priority class.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_log_info("Successfully gained high priority class.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -720,8 +722,8 @@ void pa_reset_priority(void) {
|
|||
|
||||
setpriority(PRIO_PROCESS, 0, 0);
|
||||
|
||||
memset(&sp, 0, sizeof(sp));
|
||||
pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp) == 0);
|
||||
pa_zero(sp);
|
||||
pthread_setschedparam(pthread_self(), SCHED_OTHER, &sp);
|
||||
#endif
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
|
|
|
|||
|
|
@ -80,9 +80,6 @@ int pa_make_realtime(int rtprio);
|
|||
int pa_raise_priority(int nice_level);
|
||||
void pa_reset_priority(void);
|
||||
|
||||
pa_bool_t pa_can_realtime(void);
|
||||
pa_bool_t pa_can_high_priority(void);
|
||||
|
||||
int pa_parse_boolean(const char *s) PA_GCC_PURE;
|
||||
|
||||
static inline const char *pa_yes_no(pa_bool_t b) {
|
||||
|
|
|
|||
189
src/pulsecore/rtkit.c
Normal file
189
src/pulsecore/rtkit.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8 -*-*/
|
||||
|
||||
/***
|
||||
Copyright 2009 Lennart Poettering
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
***/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "rtkit.h"
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
static pid_t _gettid(void) {
|
||||
return (pid_t) syscall(SYS_gettid);
|
||||
}
|
||||
|
||||
static int translate_error(const char *name) {
|
||||
if (strcmp(name, DBUS_ERROR_NO_MEMORY) == 0)
|
||||
return -ENOMEM;
|
||||
if (strcmp(name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
|
||||
strcmp(name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
|
||||
return -ENOENT;
|
||||
if (strcmp(name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
|
||||
strcmp(name, DBUS_ERROR_AUTH_FAILED) == 0)
|
||||
return -EACCES;
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
|
||||
DBusMessage *m = NULL, *r = NULL;
|
||||
dbus_uint64_t u64;
|
||||
dbus_uint32_t u32;
|
||||
DBusError error;
|
||||
int ret;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
if (thread == 0)
|
||||
thread = _gettid();
|
||||
|
||||
if (!(m = dbus_message_new_method_call(
|
||||
RTKIT_SERVICE_NAME,
|
||||
RTKIT_OBJECT_PATH,
|
||||
"org.freedesktop.RealtimeKit1",
|
||||
"MakeThreadRealtime"))) {
|
||||
ret = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
u64 = (dbus_uint64_t) thread;
|
||||
u32 = (dbus_uint32_t) priority;
|
||||
|
||||
if (!dbus_message_append_args(
|
||||
m,
|
||||
DBUS_TYPE_UINT64, &u64,
|
||||
DBUS_TYPE_UINT32, &u32,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
ret = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
|
||||
ret = translate_error(error.name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
if (dbus_set_error_from_message(&error, r)) {
|
||||
ret = translate_error(error.name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
finish:
|
||||
|
||||
if (m)
|
||||
dbus_message_unref(m);
|
||||
|
||||
if (r)
|
||||
dbus_message_unref(r);
|
||||
|
||||
dbus_error_free(&error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
|
||||
DBusMessage *m = NULL, *r = NULL;
|
||||
dbus_uint64_t u64;
|
||||
dbus_int32_t s32;
|
||||
DBusError error;
|
||||
int ret;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
if (thread == 0)
|
||||
thread = _gettid();
|
||||
|
||||
if (!(m = dbus_message_new_method_call(
|
||||
RTKIT_SERVICE_NAME,
|
||||
RTKIT_OBJECT_PATH,
|
||||
"org.freedesktop.RealtimeKit1",
|
||||
"MakeThreadHighPriority"))) {
|
||||
ret = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
u64 = (dbus_uint64_t) thread;
|
||||
s32 = (dbus_int32_t) nice_level;
|
||||
|
||||
if (!dbus_message_append_args(
|
||||
m,
|
||||
DBUS_TYPE_UINT64, &u64,
|
||||
DBUS_TYPE_INT32, &s32,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
ret = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
|
||||
ret = translate_error(error.name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
if (dbus_set_error_from_message(&error, r)) {
|
||||
ret = translate_error(error.name);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
finish:
|
||||
|
||||
if (m)
|
||||
dbus_message_unref(m);
|
||||
|
||||
if (r)
|
||||
dbus_message_unref(r);
|
||||
|
||||
dbus_error_free(&error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#endif
|
||||
62
src/pulsecore/rtkit.h
Normal file
62
src/pulsecore/rtkit.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8 -*-*/
|
||||
|
||||
#ifndef foortkithfoo
|
||||
#define foortkithfoo
|
||||
|
||||
/***
|
||||
Copyright 2009 Lennart Poettering
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
***/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This is the reference implementation for a client for
|
||||
* RealtimeKit. You don't have to use this, but if do, just copy these
|
||||
* sources into your repository */
|
||||
|
||||
#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
|
||||
#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"
|
||||
|
||||
/* This is mostly equivalent to sched_setparam(thread, SCHED_RR, {
|
||||
* .sched_priority = priority }). 'thread' needs to be a kernel thread
|
||||
* id as returned by gettid(), not a pthread_t! If 'thread' is 0 the
|
||||
* current thread is used. The returned value is a negative errno
|
||||
* style error code, or 0 on success. */
|
||||
int rtkit_make_realtime(DBusConnection *system_bus, pid_t thread, int priority);
|
||||
|
||||
/* This is mostly equivalent to setpriority(PRIO_PROCESS, thread,
|
||||
* nice_level). 'thread' needs to be a kernel thread id as returned by
|
||||
* gettid(), not a pthread_t! If 'thread' is 0 the current thread is
|
||||
* used. The returned value is a negative errno style error code, or 0
|
||||
* on success.*/
|
||||
int rtkit_make_high_priority(DBusConnection *system_bus, pid_t thread, int nice_level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -30,10 +30,6 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#else
|
||||
|
|
@ -47,7 +43,6 @@
|
|||
#include <pulsecore/rtclock.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/llist.h>
|
||||
#include <pulsecore/rtsig.h>
|
||||
#include <pulsecore/flist.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
#include <pulsecore/winsock.h>
|
||||
|
|
@ -66,20 +61,9 @@ struct pa_rtpoll {
|
|||
|
||||
pa_bool_t scan_for_dead:1;
|
||||
pa_bool_t running:1;
|
||||
pa_bool_t installed:1;
|
||||
pa_bool_t rebuild_needed:1;
|
||||
pa_bool_t quit:1;
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
pa_bool_t timer_armed:1;
|
||||
#ifdef __linux__
|
||||
pa_bool_t dont_use_ppoll:1;
|
||||
#endif
|
||||
int rtsig;
|
||||
sigset_t sigset_unblocked;
|
||||
timer_t timer;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
pa_usec_t timestamp;
|
||||
pa_usec_t slept, awake;
|
||||
|
|
@ -107,52 +91,20 @@ struct pa_rtpoll_item {
|
|||
|
||||
PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
|
||||
|
||||
static void signal_handler_noop(int s) { /* write(2, "signal\n", 7); */ }
|
||||
|
||||
pa_rtpoll *pa_rtpoll_new(void) {
|
||||
pa_rtpoll *p;
|
||||
|
||||
p = pa_xnew(pa_rtpoll, 1);
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
|
||||
#ifdef __linux__
|
||||
/* ppoll is broken on Linux < 2.6.16 */
|
||||
p->dont_use_ppoll = FALSE;
|
||||
|
||||
{
|
||||
struct utsname u;
|
||||
unsigned major, minor, micro;
|
||||
|
||||
pa_assert_se(uname(&u) == 0);
|
||||
|
||||
if (sscanf(u.release, "%u.%u.%u", &major, &minor, µ) != 3 ||
|
||||
(major < 2) ||
|
||||
(major == 2 && minor < 6) ||
|
||||
(major == 2 && minor == 6 && micro < 16))
|
||||
|
||||
p->dont_use_ppoll = TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
p->rtsig = -1;
|
||||
sigemptyset(&p->sigset_unblocked);
|
||||
p->timer = (timer_t) -1;
|
||||
p->timer_armed = FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
p->n_pollfd_alloc = 32;
|
||||
p->pollfd = pa_xnew(struct pollfd, p->n_pollfd_alloc);
|
||||
p->pollfd2 = pa_xnew(struct pollfd, p->n_pollfd_alloc);
|
||||
p->n_pollfd_used = 0;
|
||||
|
||||
memset(&p->next_elapse, 0, sizeof(p->next_elapse));
|
||||
pa_zero(p->next_elapse);
|
||||
p->timer_enabled = FALSE;
|
||||
|
||||
p->running = FALSE;
|
||||
p->installed = FALSE;
|
||||
p->scan_for_dead = FALSE;
|
||||
p->rebuild_needed = FALSE;
|
||||
p->quit = FALSE;
|
||||
|
|
@ -167,46 +119,6 @@ pa_rtpoll *pa_rtpoll_new(void) {
|
|||
return p;
|
||||
}
|
||||
|
||||
void pa_rtpoll_install(pa_rtpoll *p) {
|
||||
pa_assert(p);
|
||||
pa_assert(!p->installed);
|
||||
|
||||
p->installed = TRUE;
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
# ifdef __linux__
|
||||
if (p->dont_use_ppoll)
|
||||
return;
|
||||
# endif
|
||||
|
||||
if ((p->rtsig = pa_rtsig_get_for_thread()) < 0) {
|
||||
pa_log_warn("Failed to reserve POSIX realtime signal.");
|
||||
return;
|
||||
}
|
||||
|
||||
pa_log_debug("Acquired POSIX realtime signal %s", pa_sig2str(p->rtsig));
|
||||
|
||||
{
|
||||
sigset_t ss;
|
||||
struct sigaction sa;
|
||||
|
||||
pa_assert_se(sigemptyset(&ss) == 0);
|
||||
pa_assert_se(sigaddset(&ss, p->rtsig) == 0);
|
||||
pa_assert_se(pthread_sigmask(SIG_BLOCK, &ss, &p->sigset_unblocked) == 0);
|
||||
pa_assert_se(sigdelset(&p->sigset_unblocked, p->rtsig) == 0);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = signal_handler_noop;
|
||||
pa_assert_se(sigemptyset(&sa.sa_mask) == 0);
|
||||
|
||||
pa_assert_se(sigaction(p->rtsig, &sa, NULL) == 0);
|
||||
|
||||
/* We never reset the signal handler. Why should we? */
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rtpoll_rebuild(pa_rtpoll *p) {
|
||||
|
||||
struct pollfd *e, *t;
|
||||
|
|
@ -250,7 +162,6 @@ static void rtpoll_rebuild(pa_rtpoll *p) {
|
|||
|
||||
if (ra)
|
||||
p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd));
|
||||
|
||||
}
|
||||
|
||||
static void rtpoll_item_destroy(pa_rtpoll_item *i) {
|
||||
|
|
@ -279,11 +190,6 @@ void pa_rtpoll_free(pa_rtpoll *p) {
|
|||
pa_xfree(p->pollfd);
|
||||
pa_xfree(p->pollfd2);
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
if (p->timer != (timer_t) -1)
|
||||
timer_delete(p->timer);
|
||||
#endif
|
||||
|
||||
pa_xfree(p);
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +227,6 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
|
|||
|
||||
pa_assert(p);
|
||||
pa_assert(!p->running);
|
||||
pa_assert(p->installed);
|
||||
|
||||
p->running = TRUE;
|
||||
|
||||
|
|
@ -402,22 +307,15 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
|
|||
|
||||
/* OK, now let's sleep */
|
||||
#ifdef HAVE_PPOLL
|
||||
|
||||
#ifdef __linux__
|
||||
if (!p->dont_use_ppoll)
|
||||
#endif
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = timeout.tv_sec;
|
||||
ts.tv_nsec = timeout.tv_usec * 1000;
|
||||
r = ppoll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? &ts : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked);
|
||||
r = ppoll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? &ts : NULL, NULL);
|
||||
}
|
||||
#ifdef __linux__
|
||||
else
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#else
|
||||
r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
{
|
||||
|
|
@ -472,73 +370,11 @@ finish:
|
|||
return r < 0 ? r : !p->quit;
|
||||
}
|
||||
|
||||
static void update_timer(pa_rtpoll *p) {
|
||||
pa_assert(p);
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
|
||||
#ifdef __linux__
|
||||
if (p->dont_use_ppoll)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (p->timer == (timer_t) -1) {
|
||||
struct sigevent se;
|
||||
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_SIGNAL;
|
||||
se.sigev_signo = p->rtsig;
|
||||
|
||||
if (timer_create(CLOCK_MONOTONIC, &se, &p->timer) < 0)
|
||||
if (timer_create(CLOCK_REALTIME, &se, &p->timer) < 0) {
|
||||
pa_log_warn("Failed to allocate POSIX timer: %s", pa_cstrerror(errno));
|
||||
p->timer = (timer_t) -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->timer != (timer_t) -1) {
|
||||
struct itimerspec its;
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
sigset_t ss;
|
||||
|
||||
if (p->timer_armed) {
|
||||
/* First disarm timer */
|
||||
memset(&its, 0, sizeof(its));
|
||||
pa_assert_se(timer_settime(p->timer, TIMER_ABSTIME, &its, NULL) == 0);
|
||||
|
||||
/* Remove a signal that might be waiting in the signal q */
|
||||
pa_assert_se(sigemptyset(&ss) == 0);
|
||||
pa_assert_se(sigaddset(&ss, p->rtsig) == 0);
|
||||
sigtimedwait(&ss, NULL, &ts);
|
||||
}
|
||||
|
||||
/* And install the new timer */
|
||||
if (p->timer_enabled) {
|
||||
memset(&its, 0, sizeof(its));
|
||||
|
||||
its.it_value.tv_sec = p->next_elapse.tv_sec;
|
||||
its.it_value.tv_nsec = p->next_elapse.tv_usec*1000;
|
||||
|
||||
/* Make sure that 0,0 is not understood as
|
||||
* "disarming" */
|
||||
if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
|
||||
its.it_value.tv_nsec = 1;
|
||||
pa_assert_se(timer_settime(p->timer, TIMER_ABSTIME, &its, NULL) == 0);
|
||||
}
|
||||
|
||||
p->timer_armed = p->timer_enabled;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, pa_usec_t usec) {
|
||||
pa_assert(p);
|
||||
|
||||
pa_timeval_store(&p->next_elapse, usec);
|
||||
p->timer_enabled = TRUE;
|
||||
|
||||
update_timer(p);
|
||||
}
|
||||
|
||||
void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) {
|
||||
|
|
@ -550,8 +386,6 @@ void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) {
|
|||
pa_rtclock_get(&p->next_elapse);
|
||||
pa_timeval_add(&p->next_elapse, usec);
|
||||
p->timer_enabled = TRUE;
|
||||
|
||||
update_timer(p);
|
||||
}
|
||||
|
||||
void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) {
|
||||
|
|
@ -559,8 +393,6 @@ void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) {
|
|||
|
||||
memset(&p->next_elapse, 0, sizeof(p->next_elapse));
|
||||
p->timer_enabled = FALSE;
|
||||
|
||||
update_timer(p);
|
||||
}
|
||||
|
||||
pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds) {
|
||||
|
|
|
|||
|
|
@ -62,9 +62,6 @@ typedef enum pa_rtpoll_priority {
|
|||
pa_rtpoll *pa_rtpoll_new(void);
|
||||
void pa_rtpoll_free(pa_rtpoll *p);
|
||||
|
||||
/* Install the rtpoll in the current thread */
|
||||
void pa_rtpoll_install(pa_rtpoll *p);
|
||||
|
||||
/* Sleep on the rtpoll until the time event, or any of the fd events
|
||||
* is triggered. If "wait" is 0 we don't sleep but only update the
|
||||
* struct pollfd. Returns negative on error, positive if the loop
|
||||
|
|
|
|||
|
|
@ -1,131 +0,0 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright 2004-2006 Lennart Poettering
|
||||
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
|
||||
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.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/flist.h>
|
||||
#include <pulsecore/once.h>
|
||||
#include <pulsecore/thread.h>
|
||||
#include <pulsecore/core-util.h>
|
||||
|
||||
#include "rtsig.h"
|
||||
|
||||
#ifdef SIGRTMIN
|
||||
|
||||
static void _free_rtsig(void *p) {
|
||||
pa_rtsig_put(PA_PTR_TO_INT(p));
|
||||
}
|
||||
|
||||
PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two((unsigned) (SIGRTMAX-SIGRTMIN+1)), NULL);
|
||||
PA_STATIC_TLS_DECLARE(rtsig_tls, _free_rtsig);
|
||||
|
||||
static pa_atomic_t rtsig_current = PA_ATOMIC_INIT(-1);
|
||||
|
||||
static int rtsig_start = -1, rtsig_end = -1;
|
||||
|
||||
int pa_rtsig_get(void) {
|
||||
void *p;
|
||||
int sig;
|
||||
|
||||
if ((p = pa_flist_pop(PA_STATIC_FLIST_GET(rtsig_flist))))
|
||||
return PA_PTR_TO_INT(p);
|
||||
|
||||
sig = pa_atomic_dec(&rtsig_current);
|
||||
|
||||
pa_assert(sig <= SIGRTMAX);
|
||||
pa_assert(sig <= rtsig_end);
|
||||
|
||||
if (sig < rtsig_start) {
|
||||
pa_atomic_inc(&rtsig_current);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
int pa_rtsig_get_for_thread(void) {
|
||||
int sig;
|
||||
void *p;
|
||||
|
||||
if ((p = PA_STATIC_TLS_GET(rtsig_tls)))
|
||||
return PA_PTR_TO_INT(p);
|
||||
|
||||
if ((sig = pa_rtsig_get()) < 0)
|
||||
return -1;
|
||||
|
||||
PA_STATIC_TLS_SET(rtsig_tls, PA_INT_TO_PTR(sig));
|
||||
return sig;
|
||||
}
|
||||
|
||||
void pa_rtsig_put(int sig) {
|
||||
pa_assert(sig >= rtsig_start);
|
||||
pa_assert(sig <= rtsig_end);
|
||||
|
||||
pa_assert_se(pa_flist_push(PA_STATIC_FLIST_GET(rtsig_flist), PA_INT_TO_PTR(sig)) >= 0);
|
||||
}
|
||||
|
||||
void pa_rtsig_configure(int start, int end) {
|
||||
int s;
|
||||
sigset_t ss;
|
||||
|
||||
pa_assert(pa_atomic_load(&rtsig_current) == -1);
|
||||
|
||||
pa_assert(SIGRTMIN <= start);
|
||||
pa_assert(start <= end);
|
||||
pa_assert(end <= SIGRTMAX);
|
||||
|
||||
rtsig_start = start;
|
||||
rtsig_end = end;
|
||||
|
||||
sigemptyset(&ss);
|
||||
|
||||
for (s = rtsig_start; s <= rtsig_end; s++)
|
||||
pa_assert_se(sigaddset(&ss, s) == 0);
|
||||
|
||||
pa_assert(pthread_sigmask(SIG_BLOCK, &ss, NULL) == 0);
|
||||
|
||||
/* We allocate starting from the end */
|
||||
pa_atomic_store(&rtsig_current, rtsig_end);
|
||||
}
|
||||
|
||||
#else /* SIGRTMIN */
|
||||
|
||||
int pa_rtsig_get(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pa_rtsig_get_for_thread(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pa_rtsig_put(int sig) {
|
||||
}
|
||||
|
||||
void pa_rtsig_configure(int start, int end) {
|
||||
}
|
||||
|
||||
#endif /* SIGRTMIN */
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef foopulsertsighfoo
|
||||
#define foopulsertsighfoo
|
||||
|
||||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright 2004-2006 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.
|
||||
***/
|
||||
|
||||
/* Return the next unused POSIX Realtime signals */
|
||||
int pa_rtsig_get(void);
|
||||
|
||||
/* If not called before in the current thread, return the next unused
|
||||
* rtsig, and install it in a TLS region and give it up automatically
|
||||
* when the thread shuts down */
|
||||
int pa_rtsig_get_for_thread(void);
|
||||
|
||||
/* Give an rtsig back. */
|
||||
void pa_rtsig_put(int sig);
|
||||
|
||||
/* Block all RT signals */
|
||||
void pa_rtsig_configure(int start, int end);
|
||||
|
||||
#endif
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/rtpoll.h>
|
||||
#include <pulsecore/rtsig.h>
|
||||
|
||||
static int before(pa_rtpoll_item *i) {
|
||||
pa_log("before");
|
||||
|
|
@ -47,10 +46,6 @@ int main(int argc, char *argv[]) {
|
|||
pa_rtpoll_item *i, *w;
|
||||
struct pollfd *pollfd;
|
||||
|
||||
#ifdef SIGRTMIN
|
||||
pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX);
|
||||
#endif
|
||||
|
||||
p = pa_rtpoll_new();
|
||||
|
||||
i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1);
|
||||
|
|
@ -64,7 +59,6 @@ int main(int argc, char *argv[]) {
|
|||
w = pa_rtpoll_item_new(p, PA_RTPOLL_NORMAL, 0);
|
||||
pa_rtpoll_item_set_before_callback(w, worker);
|
||||
|
||||
pa_rtpoll_install(p);
|
||||
pa_rtpoll_set_timer_relative(p, 10000000); /* 10 s */
|
||||
|
||||
pa_rtpoll_run(p, 1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue