Skip to Content.
Sympa Menu

sm-commit - [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (485d8783c6524f7ceaf123e257b268a7abbd8c17)

sm-commit AT lists.ibiblio.org

Subject: Source Mage code commit list

List archive

Chronological Thread  
  • From: Pavel Vinogradov <scm AT sourcemage.org>
  • To: sm-commit AT lists.ibiblio.org
  • Subject: [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (485d8783c6524f7ceaf123e257b268a7abbd8c17)
  • Date: Tue, 3 Dec 2019 02:29:57 +0000

GIT changes to master grimoire by Pavel Vinogradov <public AT sourcemage.org>:

http/firefox/DEPENDS | 2
http/firefox/DETAILS | 4
http/firefox/HISTORY | 5
http/firefox/patches/2000_system_harfbuzz_support.patch | 23
http/firefox/patches/2007_arm-fp-wasm-fixes.patch | 34
http/firefox/patches/2008_custom_vendor_lexicon.patch | 422 ++++++
http/firefox/patches/2009_musl_audioipc-fixup.patch | 82 +
http/firefox/patches/6009_musl_audio_thread_priority.patch | 876
-------------
8 files changed, 556 insertions(+), 892 deletions(-)

New commits:
commit 485d8783c6524f7ceaf123e257b268a7abbd8c17
Author: Pavel Vinogradov <public AT sourcemage.org>
Commit: Pavel Vinogradov <public AT sourcemage.org>

http/firefox: version 71.0, SECURITY_PATCH++

diff --git a/http/firefox/DEPENDS b/http/firefox/DEPENDS
index 6180a1e..cf09bea 100755
--- a/http/firefox/DEPENDS
+++ b/http/firefox/DEPENDS
@@ -30,7 +30,7 @@ depends libwebp "--with-system-webp"
&&

depends nspr "--with-system-nspr" &&

-local NSS_BRANCH="3.46" &&
+local NSS_BRANCH="3.47" &&
if spell_ok nss &&
is_version_less "$(installed_version nss)" "${NSS_BRANCH}"; then
depends -sub "${NSS_BRANCH}.x" nss "--with-system-nss"
diff --git a/http/firefox/DETAILS b/http/firefox/DETAILS
index 3298b6f..0d070e2 100755
--- a/http/firefox/DETAILS
+++ b/http/firefox/DETAILS
@@ -1,6 +1,6 @@
SPELL=firefox
- VERSION=70.0.1
- SECURITY_PATCH=136
+ VERSION=71.0
+ SECURITY_PATCH=137
SOURCE="${SPELL}-${VERSION}.source.tar.xz"

SOURCE_URL[0]="http://releases.mozilla.org/pub/${SPELL}/releases/${VERSION}/source/${SOURCE}";
SOURCE2="${SOURCE}.asc"
diff --git a/http/firefox/HISTORY b/http/firefox/HISTORY
index dabfcac..e34f656 100644
--- a/http/firefox/HISTORY
+++ b/http/firefox/HISTORY
@@ -1,3 +1,8 @@
+2019-12-02 Pavel Vinogradov <public AT sourcemage.org>
+ * DETAILS: version 71.0, SECURITY_PATCH++
+ * DEPENDS: needs nss branch >= 3.47
+ * patches/*: updated
+
2019-10-31 Pavel Vinogradov <public AT sourcemage.org>
* DETAILS: version 70.0.1

diff --git a/http/firefox/patches/2000_system_harfbuzz_support.patch
b/http/firefox/patches/2000_system_harfbuzz_support.patch
index dc46fa3..21ccd1f 100644
--- a/http/firefox/patches/2000_system_harfbuzz_support.patch
+++ b/http/firefox/patches/2000_system_harfbuzz_support.patch
@@ -34,7 +34,7 @@ diff --git a/config/system-headers.mozbuild
b/config/system-headers.mozbuild
diff --git a/dom/base/moz.build b/dom/base/moz.build
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
-@@ -534,16 +534,19 @@ include('/ipc/chromium/chromium-config.m
+@@ -538,13 +538,16 @@ include('/ipc/chromium/chromium-config.m
FINAL_LIBRARY = 'xul'

if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
@@ -46,14 +46,11 @@ diff --git a/dom/base/moz.build b/dom/base/moz.build
+if CONFIG['MOZ_SYSTEM_HARFBUZZ']:
+ CXXFLAGS += CONFIG['MOZ_HARFBUZZ_CFLAGS']
+
- GENERATED_FILES += [
- 'UseCounterList.h',
- ]
-
- counterlist = GENERATED_FILES['UseCounterList.h']
- counterlist.script = 'gen-usecounters.py:use_counter_list'
- counterlist.inputs = ['UseCounters.conf']
+ GeneratedFile('UseCounterList.h', script='gen-usecounters.py',
+ entry_point='use_counter_list', inputs=['UseCounters.conf'])

+ if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
+ CXXFLAGS += ['-Wno-error=shadow']
diff --git a/gfx/moz.build b/gfx/moz.build
--- a/gfx/moz.build
+++ b/gfx/moz.build
@@ -170,9 +167,9 @@ diff --git a/intl/unicharutil/util/moz.build
b/intl/unicharutil/util/moz.build
diff --git a/netwerk/dns/moz.build b/netwerk/dns/moz.build
--- a/netwerk/dns/moz.build
+++ b/netwerk/dns/moz.build
-@@ -81,12 +81,15 @@ etld_data = GENERATED_FILES['etld_data.i
- etld_data.script = 'prepare_tlds.py'
- etld_data.inputs = ['effective_tld_names.dat']
+@@ -77,12 +77,15 @@ FINAL_LIBRARY = 'xul'
+ GeneratedFile('etld_data.inc', script='prepare_tlds.py',
+ inputs=['effective_tld_names.dat'])

# need to include etld_data.inc
LOCAL_INCLUDES += [
@@ -189,7 +186,7 @@ diff --git a/netwerk/dns/moz.build b/netwerk/dns/moz.build
diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
-@@ -240,16 +240,19 @@ if CONFIG['MOZ_ANDROID_GOOGLE_VR']:
+@@ -234,16 +234,19 @@ if CONFIG['MOZ_ANDROID_GOOGLE_VR']:
OS_LIBS += [
'-L%s' % CONFIG['MOZ_ANDROID_GOOGLE_VR_LIBS'],
'-lgvr',
@@ -212,7 +209,7 @@ diff --git a/toolkit/library/moz.build
b/toolkit/library/moz.build
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
-@@ -390,16 +390,26 @@ def freetype2_combined_info(fontconfig_i
+@@ -394,16 +394,26 @@ def freetype2_combined_info(fontconfig_i
return namespace(
cflags=freetype2_info.cflags + fontconfig_info.cflags,
libs=freetype2_info.libs + fontconfig_info.libs,
diff --git a/http/firefox/patches/2007_arm-fp-wasm-fixes.patch
b/http/firefox/patches/2007_arm-fp-wasm-fixes.patch
new file mode 100644
index 0000000..8c66657
--- /dev/null
+++ b/http/firefox/patches/2007_arm-fp-wasm-fixes.patch
@@ -0,0 +1,34 @@
+# HG changeset patch
+# Parent 869216461f5985d028e679b86e0afd1642dd2b82
+
+diff --git a/js/src/wasm/WasmSignalHandlers.cpp
b/js/src/wasm/WasmSignalHandlers.cpp
+--- a/js/src/wasm/WasmSignalHandlers.cpp
++++ b/js/src/wasm/WasmSignalHandlers.cpp
+@@ -243,17 +243,26 @@ using mozilla::DebugOnly;
+ // If you run into compile problems on a tier-3 platform, you can disable
the
+ // emulation here.
+
+ #if defined(__linux__) && defined(__arm__)
+ # define WASM_EMULATE_ARM_UNALIGNED_FP_ACCESS
+ #endif
+
+ #ifdef WASM_EMULATE_ARM_UNALIGNED_FP_ACCESS
+-# include <sys/user.h>
++struct user_vfp {
++ unsigned long long fpregs[32];
++ unsigned long fpscr;
++};
++
++struct user_vfp_exc {
++ unsigned long fpexc;
++ unsigned long fpinst;
++ unsigned long fpinst2;
++};
+ #endif
+
+ #if defined(ANDROID)
+ // Not all versions of the Android NDK define ucontext_t or mcontext_t.
+ // Detect this and provide custom but compatible definitions. Note that
these
+ // follow the GLibc naming convention to access register values from
+ // mcontext_t.
+ //
diff --git a/http/firefox/patches/2008_custom_vendor_lexicon.patch
b/http/firefox/patches/2008_custom_vendor_lexicon.patch
new file mode 100644
index 0000000..aaa0dc4
--- /dev/null
+++ b/http/firefox/patches/2008_custom_vendor_lexicon.patch
@@ -0,0 +1,422 @@
+# HG changeset patch
+# Parent b060564081862e54ec7058fd4c8614709a3c8f0f
+Add support for custom vendors, as in "x86_64-gentoo-linux-musl".
+
+diff --git a/third_party/rust/target-lexicon/.cargo-checksum.json
b/third_party/rust/target-lexicon/.cargo-checksum.json
+--- a/third_party/rust/target-lexicon/.cargo-checksum.json
++++ b/third_party/rust/target-lexicon/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{"Cargo.lock":"75d1f84b3d9e98d87e2f74984f7d032f5b28d7610cccf5e13977367189a77acd","Cargo.toml":"fe18dc2e0c86e6b28ed0244ced50e26f481087c693cb7cc1ff3062929894b0d4","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","build.rs":"a9f00c32de64b949c3bb23442304fc7943154efcc831aa0d87c9b83247e4e28a","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","host.rs":"4ef91a2c26405151454c2695dc0a7f455374207900ea6814d4eafdfef5f7b630","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","sorted.txt":"5548c14054ea61b51e2d8a495da662546523c3c13e8f742f6dd57754e11f46b5","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"5ad3a9418a6cb52cacc0a662645ccc671c326df954671b5ec0db667653dd125a","src/parse_error.rs":"f6689a741589ca8e659b1639728696f987c9da4948701f3b7ab6dc3e35754dab","src/targets.rs":"81320bd0280c96846a328689afe22be283cb7df9c37f005ff693ee1834b345a8","src/triple.rs":"ae2895bb2ee8451b90aa6e92d7fbf24c021230416fef030fb6ad0ef051c786c3","test.sh":"40761ee2ab0b361bdce4dc17708e671f32661f62cb56a45724d60510f9498b74"},"package":"7975cb2c6f37d77b190bc5004a2bb015971464756fde9514651a525ada2a741a"}
+\ No newline at end of file
++{"files":{"Cargo.lock":"75d1f84b3d9e98d87e2f74984f7d032f5b28d7610cccf5e13977367189a77acd","Cargo.toml":"fe18dc2e0c86e6b28ed0244ced50e26f481087c693cb7cc1ff3062929894b0d4","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","build.rs":"8fad88eb56ac757d5a8e115b136f2bfb497b762e0ff10f7e587b99fd5a5cfe4f","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","host.rs":"4ef91a2c26405151454c2695dc0a7f455374207900ea6814d4eafdfef5f7b630","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","sorted.txt":"5548c14054ea61b51e2d8a495da662546523c3c13e8f742f6dd57754e11f46b5","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"2acf0373ad7d4b23753f1cf24889f4d4ccd709b277f15dfc3e5d81804d1da0f2","src/parse_error.rs":"f6689a741589ca8e659b1639728696f987c9da4948701f3b7ab6dc3e35754dab","src/targets.rs":"50b491ef337676a7b593af7243d799ee96b1b5a9a21d060a0750a674e65826a3","src/triple.rs":"780bc76830fbdafc6682b4290d07eabeacb3572b608739688b0b681e800d78e8","test.sh":"40761ee2ab0b361bdce4dc17708e671f32661f62cb56a45724d60510f9498b74"},"package":"7975cb2c6f37d77b190bc5004a2bb015971464756fde9514651a525ada2a741a"}
+diff --git a/third_party/rust/target-lexicon/build.rs
b/third_party/rust/target-lexicon/build.rs
+--- a/third_party/rust/target-lexicon/build.rs
++++ b/third_party/rust/target-lexicon/build.rs
+@@ -32,16 +32,17 @@ mod parse_error {
+ UnrecognizedOperatingSystem(String),
+ UnrecognizedEnvironment(String),
+ UnrecognizedBinaryFormat(String),
+ UnrecognizedField(String),
+ NoneWithoutBinaryFormat,
+ }
+ }
+
++use self::targets::Vendor;
+ use self::triple::{Endianness, PointerWidth, Triple};
+
+ /// Assuming `target` is a path to a custom target json config file, open it
+ /// and build a `Triple` using its contents.
+ fn read_target_from_file(path: &Path) -> Triple {
+ let mut file = File::open(path).expect("error opening target file");
+ let mut json = String::new();
+ file.read_to_string(&mut json)
+@@ -124,25 +125,27 @@ fn write_host_rs(mut out: File, triple:
+ // The generated Debug implementation for the inner architecture
variants
+ // doesn't print the enum name qualifier, so import them here. There
+ // shouldn't be any conflicts because these enums all share a namespace
+ // in the triple string format.
+ writeln!(out, "#[allow(unused_imports)]")?;
+ writeln!(out, "use crate::Aarch64Architecture::*;")?;
+ writeln!(out, "#[allow(unused_imports)]")?;
+ writeln!(out, "use crate::ArmArchitecture::*;")?;
++ writeln!(out, "#[allow(unused_imports)]")?;
++ writeln!(out, "use crate::CustomVendor;")?;
+ writeln!(out)?;
+ writeln!(out, "/// The `Triple` of the current host.")?;
+ writeln!(out, "pub const HOST: Triple = Triple {{")?;
+ writeln!(
+ out,
+ " architecture: Architecture::{:?},",
+ triple.architecture
+ )?;
+- writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
++ writeln!(out, " vendor: {},", vendor_display(&triple.vendor))?;
+ writeln!(
+ out,
+ " operating_system: OperatingSystem::{:?},",
+ triple.operating_system
+ )?;
+ writeln!(
+ out,
+ " environment: Environment::{:?},",
+@@ -162,17 +165,17 @@ fn write_host_rs(mut out: File, triple:
+ writeln!(out, " Architecture::{:?}", triple.architecture)?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl Vendor {{")?;
+ writeln!(out, " /// Return the vendor for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+- writeln!(out, " Vendor::{:?}", triple.vendor)?;
++ writeln!(out, " {}", vendor_display(&triple.vendor))?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl OperatingSystem {{")?;
+ writeln!(
+ out,
+ " /// Return the operating system for the current host."
+@@ -210,17 +213,21 @@ fn write_host_rs(mut out: File, triple:
+ writeln!(out, " /// Return the triple for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " Self {{")?;
+ writeln!(
+ out,
+ " architecture: Architecture::{:?},",
+ triple.architecture
+ )?;
+- writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
++ writeln!(
++ out,
++ " vendor: {},",
++ vendor_display(&triple.vendor)
++ )?;
+ writeln!(
+ out,
+ " operating_system: OperatingSystem::{:?},",
+ triple.operating_system
+ )?;
+ writeln!(
+ out,
+ " environment: Environment::{:?},",
+@@ -232,8 +239,18 @@ fn write_host_rs(mut out: File, triple:
+ triple.binary_format
+ )?;
+ writeln!(out, " }}")?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+
+ Ok(())
+ }
++
++fn vendor_display(vendor: &Vendor) -> String {
++ match vendor {
++ Vendor::Custom(custom) => format!(
++ "Vendor::Custom(CustomVendor::Static({:?}))",
++ custom.as_str()
++ ),
++ known => format!("Vendor::{:?}", known),
++ }
++}
+diff --git a/third_party/rust/target-lexicon/src/lib.rs
b/third_party/rust/target-lexicon/src/lib.rs
+--- a/third_party/rust/target-lexicon/src/lib.rs
++++ b/third_party/rust/target-lexicon/src/lib.rs
+@@ -26,12 +26,12 @@ mod host;
+ mod parse_error;
+ mod targets;
+ #[macro_use]
+ mod triple;
+
+ pub use self::host::HOST;
+ pub use self::parse_error::ParseError;
+ pub use self::targets::{
+- Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat,
Environment, OperatingSystem,
+- Vendor,
++ Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat,
CustomVendor, Environment,
++ OperatingSystem, Vendor,
+ };
+ pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};
+diff --git a/third_party/rust/target-lexicon/src/targets.rs
b/third_party/rust/target-lexicon/src/targets.rs
+--- a/third_party/rust/target-lexicon/src/targets.rs
++++ b/third_party/rust/target-lexicon/src/targets.rs
+@@ -1,12 +1,15 @@
+ // This file defines all the identifier enums and target-aware logic.
+
+ use crate::triple::{Endianness, PointerWidth, Triple};
++use alloc::boxed::Box;
++use alloc::string::String;
+ use core::fmt;
++use core::hash::{Hash, Hasher};
+ use core::str::FromStr;
+
+ /// The "architecture" field, which in some cases also specifies a specific
+ /// subarchitecture.
+ #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+ #[allow(missing_docs)]
+ pub enum Architecture {
+ Unknown,
+@@ -285,32 +288,74 @@ impl Aarch64Architecture {
+ pub fn endianness(self) -> Endianness {
+ match self {
+ Aarch64Architecture::Aarch64 => Endianness::Little,
+ Aarch64Architecture::Aarch64be => Endianness::Big,
+ }
+ }
+ }
+
++/// A string for a `Vendor::Custom` that can either be used in `const`
++/// contexts or hold dynamic strings.
++#[derive(Clone, Debug, Eq)]
++pub enum CustomVendor {
++ /// An owned `String`. This supports the general case.
++ Owned(Box<String>),
++ /// A static `str`, so that `CustomVendor` can be constructed in `const`
++ /// contexts.
++ Static(&'static str),
++}
++
++impl CustomVendor {
++ /// Extracts a string slice.
++ pub fn as_str(&self) -> &str {
++ match self {
++ CustomVendor::Owned(s) => s,
++ CustomVendor::Static(s) => s,
++ }
++ }
++}
++
++impl PartialEq for CustomVendor {
++ fn eq(&self, other: &Self) -> bool {
++ self.as_str() == other.as_str()
++ }
++}
++
++impl Hash for CustomVendor {
++ fn hash<H: Hasher>(&self, state: &mut H) {
++ self.as_str().hash(state)
++ }
++}
++
+ /// The "vendor" field, which in practice is little more than an arbitrary
+ /// modifier.
+-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
++#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+ #[allow(missing_docs)]
+ pub enum Vendor {
+ Unknown,
+ Amd,
+ Apple,
+ Experimental,
+ Fortanix,
+ Nvidia,
+ Pc,
+ Rumprun,
+ Sun,
+ Uwp,
+ Wrs,
++
++ /// A custom vendor. "Custom" in this context means that the vendor is
++ /// not specifically recognized by upstream Autotools, LLVM, Rust, or
other
++ /// relevant authorities on triple naming. It's useful for people
building
++ /// and using locally patched toolchains.
++ ///
++ /// Outside of such patched environments, users of `target-lexicon`
should
++ /// treat `Custom` the same as `Unknown` and ignore the string.
++ Custom(CustomVendor),
+ }
+
+ /// The "operating system" field, which sometimes implies an environment,
and
+ /// sometimes isn't an actual operating system.
+ #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+ #[allow(missing_docs)]
+ pub enum OperatingSystem {
+ Unknown,
+@@ -710,16 +755,17 @@ impl fmt::Display for Vendor {
+ Vendor::Experimental => "experimental",
+ Vendor::Fortanix => "fortanix",
+ Vendor::Nvidia => "nvidia",
+ Vendor::Pc => "pc",
+ Vendor::Rumprun => "rumprun",
+ Vendor::Sun => "sun",
+ Vendor::Uwp => "uwp",
+ Vendor::Wrs => "wrs",
++ Vendor::Custom(ref name) => name.as_str(),
+ };
+ f.write_str(s)
+ }
+ }
+
+ impl FromStr for Vendor {
+ type Err = ();
+
+@@ -731,17 +777,54 @@ impl FromStr for Vendor {
+ "experimental" => Vendor::Experimental,
+ "fortanix" => Vendor::Fortanix,
+ "nvidia" => Vendor::Nvidia,
+ "pc" => Vendor::Pc,
+ "rumprun" => Vendor::Rumprun,
+ "sun" => Vendor::Sun,
+ "uwp" => Vendor::Uwp,
+ "wrs" => Vendor::Wrs,
+- _ => return Err(()),
++ custom => {
++ use alloc::borrow::ToOwned;
++
++ // A custom vendor. Since triple syntax is so loosely
defined,
++ // be as conservative as we can to avoid potential
ambiguities.
++ // We err on the side of being too strict here, as we can
++ // always relax it if needed.
++
++ // Don't allow empty string names.
++ if custom.is_empty() {
++ return Err(());
++ }
++
++ // Don't allow any other recognized name as a custom vendor,
++ // since vendors can be omitted in some contexts.
++ if Architecture::from_str(custom).is_ok()
++ || OperatingSystem::from_str(custom).is_ok()
++ || Environment::from_str(custom).is_ok()
++ || BinaryFormat::from_str(custom).is_ok()
++ {
++ return Err(());
++ }
++
++ // Require the first character to be an ascii lowercase.
++ if !custom.chars().nth(0).unwrap().is_ascii_lowercase() {
++ return Err(());
++ }
++
++ // Restrict the set of characters permitted in a custom
vendor.
++ fn is_prohibited_char(c: char) -> bool {
++ !(c.is_ascii_lowercase() || c.is_ascii_digit() || c ==
'_' || c == '.')
++ }
++ if custom.chars().any(is_prohibited_char) {
++ return Err(());
++ }
++
++
Vendor::Custom(CustomVendor::Owned(Box::new(custom.to_owned())))
++ }
+ })
+ }
+ }
+
+ impl fmt::Display for OperatingSystem {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ OperatingSystem::Unknown => "unknown",
+@@ -1106,9 +1189,88 @@ mod tests {
+ t.architecture,
+ Architecture::Arm(ArmArchitecture::Thumbv7em)
+ );
+ assert_eq!(t.vendor, Vendor::Unknown);
+ assert_eq!(t.operating_system, OperatingSystem::None_);
+ assert_eq!(t.environment, Environment::Eabihf);
+ assert_eq!(t.binary_format, BinaryFormat::Elf);
+ }
++
++ #[test]
++ fn custom_vendors() {
++ // Test various invalid cases.
++ assert!(Triple::from_str("x86_64--linux").is_err());
++ assert!(Triple::from_str("x86_64-42-linux").is_err());
++ assert!(Triple::from_str("x86_64-__customvendor__-linux").is_err());
++ assert!(Triple::from_str("x86_64-^-linux").is_err());
++ assert!(Triple::from_str("x86_64- -linux").is_err());
++ assert!(Triple::from_str("x86_64-CustomVendor-linux").is_err());
++ assert!(Triple::from_str("x86_64-linux-linux").is_err());
++ assert!(Triple::from_str("x86_64-x86_64-linux").is_err());
++ assert!(Triple::from_str("x86_64-elf-linux").is_err());
++ assert!(Triple::from_str("x86_64-gnu-linux").is_err());
++ assert!(Triple::from_str("x86_64-linux-customvendor").is_err());
++ assert!(Triple::from_str("customvendor").is_err());
++ assert!(Triple::from_str("customvendor-x86_64").is_err());
++ assert!(Triple::from_str("x86_64-").is_err());
++ assert!(Triple::from_str("x86_64--").is_err());
++
++ // Test various Unicode things.
++ assert!(
++ Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux").is_err(),
++ "unicode font hazard"
++ );
++ assert!(
++ Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux").is_err(),
++ "diacritical mark stripping hazard"
++ );
++ assert!(
++ Triple::from_str("x86_64-customvendοr-linux").is_err(),
++ "homoglyph hazard"
++ );
++ assert!(Triple::from_str("x86_64-customvendor-linux").is_ok());
++ assert!(
++ Triple::from_str("x86_64-ffi-linux").is_err(),
++ "normalization hazard"
++ );
++ assert!(Triple::from_str("x86_64-ffi-linux").is_ok());
++ assert!(
++ Triple::from_str("x86_64-custom‍vendor-linux").is_err(),
++ "zero-width character hazard"
++ );
++
++ // Test some valid cases.
++ let t = Triple::from_str("x86_64-customvendor-linux")
++ .expect("can't parse target with custom vendor");
++ assert_eq!(t.architecture, Architecture::X86_64);
++ assert_eq!(
++ t.vendor,
++ Vendor::Custom(CustomVendor::Static("customvendor"))
++ );
++ assert_eq!(t.operating_system, OperatingSystem::Linux);
++ assert_eq!(t.environment, Environment::Unknown);
++ assert_eq!(t.binary_format, BinaryFormat::Elf);
++ assert_eq!(t.to_string(), "x86_64-customvendor-linux");
++
++ let t =
++ Triple::from_str("x86_64-customvendor").expect("can't parse
target with custom vendor");
++ assert_eq!(t.architecture, Architecture::X86_64);
++ assert_eq!(
++ t.vendor,
++ Vendor::Custom(CustomVendor::Static("customvendor"))
++ );
++ assert_eq!(t.operating_system, OperatingSystem::Unknown);
++ assert_eq!(t.environment, Environment::Unknown);
++ assert_eq!(t.binary_format, BinaryFormat::Unknown);
++
++ assert_eq!(
++ Triple::from_str("unknown-foo"),
++ Ok(Triple {
++ architecture: Architecture::Unknown,
++ vendor: Vendor::Custom(CustomVendor::Static("foo")),
++ operating_system: OperatingSystem::Unknown,
++ environment: Environment::Unknown,
++ binary_format: BinaryFormat::Unknown,
++ })
++ );
++ }
+ }
+diff --git a/third_party/rust/target-lexicon/src/triple.rs
b/third_party/rust/target-lexicon/src/triple.rs
+--- a/third_party/rust/target-lexicon/src/triple.rs
++++ b/third_party/rust/target-lexicon/src/triple.rs
+@@ -303,20 +303,16 @@ mod tests {
+ Triple::from_str(""),
+ Err(ParseError::UnrecognizedArchitecture("".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("foo"),
+ Err(ParseError::UnrecognizedArchitecture("foo".to_owned()))
+ );
+ assert_eq!(
+- Triple::from_str("unknown-foo"),
+- Err(ParseError::UnrecognizedVendor("foo".to_owned()))
+- );
+- assert_eq!(
+ Triple::from_str("unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedEnvironment("foo".to_owned()))
+ );
+ assert_eq!(
diff --git a/http/firefox/patches/2009_musl_audioipc-fixup.patch
b/http/firefox/patches/2009_musl_audioipc-fixup.patch
new file mode 100644
index 0000000..9cf64e4
--- /dev/null
+++ b/http/firefox/patches/2009_musl_audioipc-fixup.patch
@@ -0,0 +1,82 @@
+# HG changeset patch
+# Parent e44961cd1e80024c729afde2019f75917d7522f4
+Stop storing sched_param in RtPriorityThreadInfo on Linux
+
+It wasn't really being used anyways, since we alwayrs restore priority
+to `SCHED_OTHER`, that expects the only common field of `sched_param` to
+be zero, because `SCHED_OTHER` does not support a priority.
+
+diff --git a/third_party/rust/audio_thread_priority/.cargo-checksum.json
b/third_party/rust/audio_thread_priority/.cargo-checksum.json
+--- a/third_party/rust/audio_thread_priority/.cargo-checksum.json
++++ b/third_party/rust/audio_thread_priority/.cargo-checksum.json
+@@ -1,1 +1,1 @@
+-{"files":{"Cargo.toml":"363ab43ea4980149350eb3a4da691a93f0b7c61a5d3b4ce8b59f73cde5866a92","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"516388cf4ccf55f23a6ccb248f56ab525b759a24819e67605cd12f640517ddd3","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"b4db36baa754ab166b40f3801acc4f2046d226a2645f0e136dbbfa1bc771344e","src/rt_mach.rs":"5fce324b9a64305ff221fdd185eaa4b1c7386b6e61edc32cf63e424f9f3d90ef","src/rt_win.rs":"f8f5b7af21cadd686cf7d8099d1972d3265c3889574020bd4ea088b832fbfa51"},"package":"197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"}
+\ No newline at end of file
++{"files":{"Cargo.toml":"363ab43ea4980149350eb3a4da691a93f0b7c61a5d3b4ce8b59f73cde5866a92","Makefile":"0f9a771cfb30c7c4b9961d82fdca4e9e229a955bb2e636474a4101389e18e938","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","atp_test.cpp":"8075a040941a65fb9e3f7cbf0535853ca6661c3ac442ec35569b42b24bbec797","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"516388cf4ccf55f23a6ccb248f56ab525b759a24819e67605cd12f640517ddd3","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"61df532b5cf78d3300e1284c735985e48da32582541973d8ec11a1fb83d3d597","src/rt_mach.rs":"5fce324b9a64305ff221fdd185eaa4b1c7386b6e61edc32cf63e424f9f3d90ef","src/rt_win.rs":"f8f5b7af21cadd686cf7d8099d1972d3265c3889574020bd4ea088b832fbfa51"},"package":"197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"}
+diff --git a/third_party/rust/audio_thread_priority/src/rt_linux.rs
b/third_party/rust/audio_thread_priority/src/rt_linux.rs
+--- a/third_party/rust/audio_thread_priority/src/rt_linux.rs
++++ b/third_party/rust/audio_thread_priority/src/rt_linux.rs
+@@ -26,19 +26,17 @@ pub struct RtPriorityThreadInfoInternal
+ pid: libc::pid_t,
+ /// System-wise thread id, use to promote the thread via dbus.
+ thread_id: kernel_pid_t,
+ /// Process-local thread id, used to restore scheduler characteristics.
This information is not
+ /// useful in another process, but is useful tied to the `thread_id`,
when back into the first
+ /// process.
+ pthread_id: libc::pthread_t,
+ /// ...
+- policy: libc::c_int,
+- /// ...
+- param: libc::sched_param,
++ policy: libc::c_int
+ }
+
+ impl RtPriorityThreadInfoInternal {
+ /// Serialize a RtPriorityThreadInfoInternal to a byte buffer.
+ pub fn serialize(&self) -> [u8; std::mem::size_of::<Self>()] {
+ unsafe { std::mem::transmute::<Self, [u8;
std::mem::size_of::<Self>()]>(*self) }
+ }
+ /// Get an RtPriorityThreadInfoInternal from a byte buffer.
+@@ -136,19 +134,21 @@ pub fn promote_current_thread_to_real_ti
+ let thread_info = get_current_thread_info_internal()?;
+ promote_thread_to_real_time_internal(thread_info, audio_buffer_frames,
audio_samplerate_hz)
+ }
+
+ pub fn demote_current_thread_from_real_time_internal(rt_priority_handle:
RtPriorityHandleInternal)
+ -> Result<(), ()> {
+ assert!(unsafe { libc::pthread_self() } ==
rt_priority_handle.thread_info.pthread_id);
+
++ let param = unsafe { std::mem::zeroed::<libc::sched_param>() };
++
+ if unsafe {
libc::pthread_setschedparam(rt_priority_handle.thread_info.pthread_id,
+
rt_priority_handle.thread_info.policy,
+-
&rt_priority_handle.thread_info.param) } < 0 {
++ &param) } < 0 {
+ error!("could not demote thread {}",
OSError::last_os_error().raw_os_error().unwrap());
+ return Err(());
+ }
+ return Ok(());
+ }
+
+ /// This can be called by sandboxed code, it only restores priority to what
they were.
+ pub fn demote_thread_from_real_time_internal(thread_info:
RtPriorityThreadInfoInternal)
+@@ -182,18 +182,17 @@ pub fn get_current_thread_info_internal(
+ }
+
+ let pid = unsafe { libc::getpid() };
+
+ Ok(RtPriorityThreadInfoInternal {
+ pid,
+ thread_id,
+ pthread_id,
+- policy,
+- param
++ policy
+ })
+ }
+
+ /// This set the RLIMIT_RTTIME resource to something other than
"unlimited". It's necessary for the
+ /// rtkit request to succeed, and needs to hapen in the child. We can't get
the real limit here,
+ /// because we don't have access to DBUS, so it is hardcoded to 200ms,
which is the default in the
+ /// rtkit package.
+ pub fn set_real_time_hard_limit_internal(audio_buffer_frames: u32,
diff --git a/http/firefox/patches/6009_musl_audio_thread_priority.patch
b/http/firefox/patches/6009_musl_audio_thread_priority.patch
deleted file mode 100644
index 86a8fcd..0000000
--- a/http/firefox/patches/6009_musl_audio_thread_priority.patch
+++ /dev/null
@@ -1,876 +0,0 @@
-# HG changeset patch
-# Parent 531900878b92d74b9e9deb66409b7f298b33944e
-Unbreak assumptions for error handling
-
-diff --git a/third_party/rust/audio_thread_priority/.cargo-checksum.json
b/third_party/rust/audio_thread_priority/.cargo-checksum.json
---- a/third_party/rust/audio_thread_priority/.cargo-checksum.json
-+++ b/third_party/rust/audio_thread_priority/.cargo-checksum.json
-@@ -1,1 +1,1 @@
--{"files":{"Cargo.toml":"a18d74797e678c75ae36f85e15092ea4eca698f5e8a2580c3144e32f407164d4","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","audio_thread_priority.h":"880889a154283a87cf84218cc4d6b2b9dd2c8fd09adc6d38f527b08ccd0c6168","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"25df84928756bc50fa908d65acace5259b59dfa5fc57a3f0f8b0e1f8a98ab512","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"3da1550beacc8f8a0d86c07ed190ceef7d56398c675b99a145919f5c7231eed7","src/rt_mach.rs":"5fce324b9a64305ff221fdd185eaa4b1c7386b6e61edc32cf63e424f9f3d90ef","src/rt_win.rs":"f8f5b7af21cadd686cf7d8099d1972d3265c3889574020bd4ea088b832fbfa51"},"package":"4c1e4aab7f57d8334168073cd0d0f11c7d1f7f3aabef84a1733a42629d0da80c"}
-\ No newline at end of file
-+{"files":{"Cargo.toml":"a18d74797e678c75ae36f85e15092ea4eca698f5e8a2580c3144e32f407164d4","README.md":"bcfa4948edf52fdacd485200a0c1c886a92232cc1931eeb4e1044050f46ec253","audio_thread_priority.h":"f0ecaf1b674f794cde0dc834028e074d4e4675d22ae96acf08b2ae1dceb3474e","generate_osx_bindings.sh":"06e4e03450f788ced18d31fff5660919e6f6ec1119ddace363ffeb82f0518a71","src/lib.rs":"516388cf4ccf55f23a6ccb248f56ab525b759a24819e67605cd12f640517ddd3","src/mach_sys.rs":"352560fcb9b41d877cff92e5b3b04d6dc68b1f30508ce4b9aed78940120a883e","src/rt_linux.rs":"b4db36baa754ab166b40f3801acc4f2046d226a2645f0e136dbbfa1bc771344e","src/rt_mach.rs":"5fce324b9a64305ff221fdd185eaa4b1c7386b6e61edc32cf63e424f9f3d90ef","src/rt_win.rs":"f8f5b7af21cadd686cf7d8099d1972d3265c3889574020bd4ea088b832fbfa51"},"package":"4c1e4aab7f57d8334168073cd0d0f11c7d1f7f3aabef84a1733a42629d0da80c"}
-diff --git a/third_party/rust/audio_thread_priority/audio_thread_priority.h
b/third_party/rust/audio_thread_priority/audio_thread_priority.h
---- a/third_party/rust/audio_thread_priority/audio_thread_priority.h
-+++ b/third_party/rust/audio_thread_priority/audio_thread_priority.h
-@@ -8,16 +8,18 @@
- #include <stdint.h>
- #include <stdlib.h>
-
- /**
- * An opaque structure containing information about a thread that was
promoted
- * to real-time priority.
- */
- struct atp_handle;
-+struct atp_thread_info;
-+extern size_t ATP_THREAD_INFO_SIZE;
-
- #ifdef __cplusplus
- extern "C" {
- #endif // __cplusplus
-
- /**
- * Promotes the current thread to real-time priority.
- *
-@@ -26,16 +28,17 @@ extern "C" {
- * or an upper bound.
- * audio_samplerate_hz: sample-rate for this audio stream, in Hz
- *
- * Returns an opaque handle in case of success, NULL otherwise.
- */
- atp_handle *atp_promote_current_thread_to_real_time(uint32_t
audio_buffer_frames,
- uint32_t
audio_samplerate_hz);
-
-+
- /**
- * Demotes the current thread promoted to real-time priority via
- * `atp_demote_current_thread_from_real_time` to its previous priority.
- *
- * Returns 0 in case of success, non-zero otherwise.
- */
- int32_t atp_demote_current_thread_from_real_time(atp_handle *handle);
-
-@@ -44,13 +47,107 @@ int32_t atp_demote_current_thread_from_r
- *`atp_demote_current_thread_from_real_time` on the right thread. Access to
the
- * handle must be synchronized externaly (or the related thread must have
- * exited).
- *
- * Returns 0 in case of success, non-zero otherwise.
- */
- int32_t atp_free_handle(atp_handle *handle);
-
-+/*
-+ * Linux-only API.
-+ *
-+ * The Linux backend uses DBUS to promote a thread to real-time priority. In
-+ * environment where this is not possible (due to sandboxing), this set of
-+ * functions allow remoting the call to a process that can make DBUS calls.
-+ *
-+ * To do so:
-+ * - Set the real-time limit from within the process where a
-+ * thread will be promoted. This is a `setrlimit` call, that can be done
-+ * before the sandbox lockdown.
-+ * - Then, gather information on the thread that will be promoted.
-+ * - Serialize this info.
-+ * - Send over the serialized data via an IPC mechanism
-+ * - Deserialize the inf
-+ * - Call `atp_promote_thread_to_real_time`
-+ */
-+
-+#ifdef __linux__
-+/**
-+ * Promotes a thread, possibly in another process, to real-time priority.
-+ *
-+ * thread_info: info on the thread to promote, gathered with
-+ * `atp_get_current_thread_info()`, called on the thread itself.
-+ * audio_buffer_frames: number of frames per audio buffer. If unknown,
passing 0
-+ * will choose an appropriate number, conservatively. If variable, either
pass 0
-+ * or an upper bound.
-+ * audio_samplerate_hz: sample-rate for this audio stream, in Hz
-+ *
-+ * Returns an opaque handle in case of success, NULL otherwise.
-+ *
-+ * This call is useful on Linux desktop only, when the process is sandboxed
and
-+ * cannot promote itself directly.
-+ */
-+atp_handle *atp_promote_thread_to_real_time(atp_thread_info *thread_info);
-+
-+/**
-+ * Demotes a thread promoted to real-time priority via
-+ * `atp_demote_thread_from_real_time` to its previous priority.
-+ *
-+ * Returns 0 in case of success, non-zero otherwise.
-+ *
-+ * This call is useful on Linux desktop only, when the process is sandboxed
and
-+ * cannot promote itself directly.
-+ */
-+int32_t atp_demote_thread_from_real_time(atp_thread_info* thread_info);
-+
-+/**
-+ * Gather informations from the calling thread, to be able to promote it
from
-+ * another thread and/or process.
-+ *
-+ * Returns a non-null pointer to an `atp_thread_info` structure in case of
-+ * sucess, to be freed later with `atp_free_thread_info`, and NULL
otherwise.
-+ *
-+ * This call is useful on Linux desktop only, when the process is sandboxed
and
-+ * cannot promote itself directly.
-+ */
-+atp_thread_info *atp_get_current_thread_info();
-+
-+/**
-+ * Free an `atp_thread_info` structure.
-+ *
-+ * Returns 0 in case of success, non-zero in case of error (because
thread_info
-+ * was NULL).
-+ */
-+int32_t atp_free_thread_info(atp_thread_info *thread_info);
-+
-+/**
-+ * Serialize an `atp_thread_info` to a byte buffer that is
-+ * sizeof(atp_thread_info) long.
-+ */
-+void atp_serialize_thread_info(atp_thread_info *thread_info, uint8_t
*bytes);
-+
-+/**
-+ * Deserialize a byte buffer of sizeof(atp_thread_info) to an
`atp_thread_info`
-+ * pointer. It can be then freed using atp_free_thread_info.
-+ * */
-+atp_thread_info* atp_deserialize_thread_info(uint8_t *bytes);
-+
-+/**
-+ * Set real-time limit for the calling process.
-+ *
-+ * This is useful only on Linux desktop, and allows remoting the rtkit DBUS
call
-+ * to a process that has access to DBUS. This function has to be called
before
-+ * attempting to promote threads from another process.
-+ *
-+ * This sets the real-time computation limit. For actually promoting the
thread
-+ * to a real-time scheduling class, see `atp_promote_thread_to_real_time`.
-+ */
-+int32_t atp_set_real_time_limit(uint32_t audio_buffer_frames,
-+ uint32_t audio_samplerate_hz);
-+
-+#endif // __linux__
-+
- #ifdef __cplusplus
- } // extern "C"
- #endif // __cplusplus
-
- #endif // AUDIO_THREAD_PRIORITY_H
-diff --git a/third_party/rust/audio_thread_priority/src/lib.rs
b/third_party/rust/audio_thread_priority/src/lib.rs
---- a/third_party/rust/audio_thread_priority/src/lib.rs
-+++ b/third_party/rust/audio_thread_priority/src/lib.rs
-@@ -1,19 +1,22 @@
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-+#[warn(missing_docs)]
-+
- #[macro_use]
- extern crate cfg_if;
- #[cfg(feature = "terminal-logging")]
- extern crate simple_logger;
- #[macro_use]
- extern crate log;
-
-+
- cfg_if! {
- if #[cfg(target_os = "macos")] {
- mod rt_mach;
- #[allow(unused, non_camel_case_types, non_snake_case,
non_upper_case_globals)]
- mod mach_sys;
- extern crate mach;
- extern crate libc;
- use rt_mach::promote_current_thread_to_real_time_internal;
-@@ -24,38 +27,298 @@ cfg_if! {
- mod rt_win;
- use rt_win::promote_current_thread_to_real_time_internal;
- use rt_win::demote_current_thread_from_real_time_internal;
- use rt_win::RtPriorityHandleInternal;
- } else if #[cfg(target_os = "linux")] {
- mod rt_linux;
- extern crate dbus;
- extern crate libc;
-+ use rt_linux::set_real_time_hard_limit_internal as
set_real_time_hard_limit;
- use rt_linux::promote_current_thread_to_real_time_internal;
- use rt_linux::demote_current_thread_from_real_time_internal;
-+ use rt_linux::get_current_thread_info_internal;
-+ use rt_linux::promote_thread_to_real_time_internal;
-+ use rt_linux::demote_thread_from_real_time_internal;
-+ use rt_linux::RtPriorityThreadInfoInternal;
- use rt_linux::RtPriorityHandleInternal;
-+ #[no_mangle]
-+ /// Size of a RtPriorityThreadInfo or atp_thread_info struct, for
use in FFI.
-+ pub static ATP_THREAD_INFO_SIZE: usize =
std::mem::size_of::<RtPriorityThreadInfo>();
- } else {
-+ // blanket implementations for Android and other systems.
- pub struct RtPriorityHandleInternal {}
- pub fn promote_current_thread_to_real_time_internal(_: u32,
audio_samplerate_hz: u32) -> Result<RtPriorityHandle, ()> {
- if audio_samplerate_hz == 0 {
- return Err(());
- }
- // no-op
-- return Ok(RtPriorityHandle{});
-+ Ok(RtPriorityHandle{})
- }
- pub fn demote_current_thread_from_real_time_internal(_:
RtPriorityHandle) -> Result<(), ()> {
- // no-op
-- return Ok(());
-+ Ok(())
- }
- }
- }
-
- /// Opaque handle to a thread handle structure.
- pub type RtPriorityHandle = RtPriorityHandleInternal;
-
-+cfg_if! {
-+ if #[cfg(target_os = "linux")] {
-+/// Opaque handle to a thread info.
-+///
-+/// This can be serialized to raw bytes to be sent via IPC.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+pub type RtPriorityThreadInfo = RtPriorityThreadInfoInternal;
-+
-+
-+/// Get the calling thread's information, to be able to promote it to
real-time from somewhere
-+/// else, later.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+///
-+/// # Return value
-+///
-+/// Ok in case of success, with an opaque structure containing relevant
info for the platform, Err
-+/// otherwise.
-+pub fn get_current_thread_info() -> Result<RtPriorityThreadInfo, ()> {
-+ return get_current_thread_info_internal();
-+}
-+
-+/// Return a byte buffer containing serialized information about a thread,
to promote it to
-+/// real-time from elsewhere.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+pub fn thread_info_serialize(
-+ thread_info: RtPriorityThreadInfo,
-+) -> [u8; std::mem::size_of::<RtPriorityThreadInfo>()] {
-+ return thread_info.serialize();
-+}
-+
-+/// From a byte buffer, return a `RtPriorityThreadInfo`.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+///
-+/// # Arguments
-+///
-+/// A byte buffer containing a serializezd `RtPriorityThreadInfo`.
-+pub fn thread_info_deserialize(
-+ bytes: [u8; std::mem::size_of::<RtPriorityThreadInfo>()],
-+) -> RtPriorityThreadInfo {
-+ return RtPriorityThreadInfoInternal::deserialize(bytes);
-+}
-+
-+/// Get the calling threads' information, to promote it from another
process or thread, with a C
-+/// API.
-+///
-+/// This is intended to call on the thread that will end up being promoted
to real time priority,
-+/// but that cannot do it itself (probably because of sandboxing reasons).
-+///
-+/// After use, it MUST be freed by calling `atp_free_thread_info`.
-+///
-+/// # Return value
-+///
-+/// A pointer to a struct that can be serialized and deserialized, and that
can be passed to
-+/// `atp_promote_thread_to_real_time`, even from another process.
-+#[no_mangle]
-+pub extern "C" fn atp_get_current_thread_info() -> *mut atp_thread_info {
-+ match get_current_thread_info() {
-+ Ok(thread_info) =>
Box::into_raw(Box::new(atp_thread_info(thread_info))),
-+ _ => std::ptr::null_mut(),
-+ }
-+}
-+
-+/// Frees a thread info, with a c api.
-+///
-+/// # Arguments
-+///
-+/// thread_info: the `atp_thread_info` structure to free.
-+///
-+/// # Return value
-+///
-+/// 0 in case of success, 1 otherwise (if `thread_info` is NULL).
-+#[no_mangle]
-+pub extern "C" fn atp_free_thread_info(thread_info: *mut atp_thread_info)
-> i32 {
-+ if thread_info.is_null() {
-+ return 1;
-+ }
-+ unsafe { Box::from_raw(thread_info) };
-+ 0
-+}
-+
-+/// Return a byte buffer containing serialized information about a thread,
to promote it to
-+/// real-time from elsewhere, with a C API.
-+///
-+/// `bytes` MUST be `std::mem::size_of<RtPriorityThreadInfo>()` bytes long.
-+///
-+/// This is exposed in the C API as `ATP_THREAD_INFO_SIZE`.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed, cannot promote itself
-+/// directly, and the `atp_thread_info` struct must be passed via IPC.
-+#[no_mangle]
-+pub extern "C" fn atp_serialize_thread_info(
-+ thread_info: *mut atp_thread_info,
-+ bytes: *mut libc::c_void,
-+) {
-+ let thread_info = unsafe { &mut *thread_info };
-+ let source = thread_info.0.serialize();
-+ unsafe {
-+ std::ptr::copy(source.as_ptr(), bytes as *mut u8, source.len());
-+ }
-+}
-+
-+/// From a byte buffer, return a `RtPriorityThreadInfo`, with a C API.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+///
-+/// # Arguments
-+///
-+/// A byte buffer containing a serializezd `RtPriorityThreadInfo`.
-+#[no_mangle]
-+pub extern "C" fn atp_deserialize_thread_info(
-+ in_bytes: *mut u8,
-+) -> *mut atp_thread_info {
-+ let bytes = unsafe { *(in_bytes as *mut [u8;
std::mem::size_of::<RtPriorityThreadInfoInternal>()]) };
-+ let thread_info = RtPriorityThreadInfoInternal::deserialize(bytes);
-+ return Box::into_raw(Box::new(atp_thread_info(thread_info)));
-+}
-+
-+/// Promote a particular thread thread to real-time priority.
-+///
-+/// This call is useful on Linux desktop only, when the process is
sandboxed and
-+/// cannot promote itself directly.
-+///
-+/// # Arguments
-+///
-+/// * `thread_info` - informations about the thread to promote, gathered
using
-+/// `get_current_thread_info`.
-+/// * `audio_buffer_frames` - the exact or an upper limit on the number of
frames that have to be
-+/// rendered each callback, or 0 for a sensible default value.
-+/// * `audio_samplerate_hz` - the sample-rate for this audio stream, in Hz.
-+///
-+/// # Return value
-+///
-+/// This function returns a `Result<RtPriorityHandle>`, which is an opaque
struct to be passed to
-+/// `demote_current_thread_from_real_time` to revert to the previous thread
priority.
-+pub fn promote_thread_to_real_time(
-+ thread_info: RtPriorityThreadInfo,
-+ audio_buffer_frames: u32,
-+ audio_samplerate_hz: u32,
-+) -> Result<RtPriorityHandle, ()> {
-+ if audio_samplerate_hz == 0 {
-+ return Err(());
-+ }
-+ return promote_thread_to_real_time_internal(
-+ thread_info,
-+ audio_buffer_frames,
-+ audio_samplerate_hz,
-+ );
-+}
-+
-+/// Demotes a thread from real-time priority.
-+///
-+/// # Arguments
-+///
-+/// * `thread_info` - An opaque struct returned from a successful call to
-+/// `get_current_thread_info`.
-+///
-+/// # Return value
-+///
-+/// `Ok` in case of success, `Err` otherwise.
-+pub fn demote_thread_from_real_time(thread_info: RtPriorityThreadInfo) ->
Result<(), ()> {
-+ return demote_thread_from_real_time_internal(thread_info);
-+}
-+
-+/// Opaque info to a particular thread.
-+#[allow(non_camel_case_types)]
-+pub struct atp_thread_info(RtPriorityThreadInfo);
-+
-+/// Promote a specific thread to real-time, with a C API.
-+///
-+/// This is useful when the thread to promote cannot make some system calls
necessary to promote
-+/// it.
-+///
-+/// # Arguments
-+///
-+/// `thread_info` - the information of the thread to promote to real-time,
gather from calling
-+/// `atp_get_current_thread_info` on the thread to promote.
-+/// * `audio_buffer_frames` - the exact or an upper limit on the number of
frames that have to be
-+/// rendered each callback, or 0 for a sensible default value.
-+/// * `audio_samplerate_hz` - the sample-rate for this audio stream, in Hz.
-+///
-+/// # Return value
-+///
-+/// A pointer to an `atp_handle` in case of success, NULL otherwise.
-+#[no_mangle]
-+pub extern "C" fn atp_promote_thread_to_real_time(
-+ thread_info: *mut atp_thread_info,
-+ audio_buffer_frames: u32,
-+ audio_samplerate_hz: u32,
-+) -> *mut atp_handle {
-+ let thread_info = unsafe { &mut *thread_info };
-+ match promote_thread_to_real_time(thread_info.0, audio_buffer_frames,
audio_samplerate_hz) {
-+ Ok(handle) => Box::into_raw(Box::new(atp_handle(handle))),
-+ _ => std::ptr::null_mut(),
-+ }
-+}
-+
-+/// Demote a thread promoted to from real-time, with a C API.
-+///
-+/// # Arguments
-+///
-+/// `handle` - an opaque struct received from a promoting function.
-+///
-+/// # Return value
-+///
-+/// 0 in case of success, non-zero otherwise.
-+#[no_mangle]
-+pub extern "C" fn atp_demote_thread_from_real_time(thread_info: *mut
atp_thread_info) -> i32 {
-+ if thread_info.is_null() {
-+ return 1;
-+ }
-+ let thread_info = unsafe { (*thread_info).0 };
-+
-+ match demote_thread_from_real_time(thread_info) {
-+ Ok(_) => 0,
-+ _ => 1,
-+ }
-+}
-+
-+/// Set a real-time limit for the calling thread.
-+///
-+/// # Arguments
-+///
-+/// `audio_buffer_frames` - the number of frames the audio callback has to
render each quantum. 0
-+/// picks a rather high default value.
-+/// `audio_samplerate_hz` - the sample-rate of the audio stream.
-+///
-+/// # Return value
-+///
-+/// 0 in case of success, 1 otherwise.
-+#[no_mangle]
-+pub extern "C" fn atp_set_real_time_limit(audio_buffer_frames: u32,
-+ audio_samplerate_hz: u32) -> i32 {
-+ let r = set_real_time_hard_limit(audio_buffer_frames,
audio_samplerate_hz);
-+ if r.is_err() {
-+ return 1;
-+ }
-+ 0
-+}
-+
-+}
-+}
-+
- /// Promote the calling thread thread to real-time priority.
- ///
- /// # Arguments
- ///
- /// * `audio_buffer_frames` - the exact or an upper limit on the number of
frames that have to be
- /// rendered each callback, or 0 for a sensible default value.
- /// * `audio_samplerate_hz` - the sample-rate for this audio stream, in Hz.
- ///
-@@ -200,9 +463,91 @@ mod tests {
- Ok(_) => {}
- Err(e) => {
- panic!(e);
- }
- }
- // automatically deallocated, but not demoted until the thread
exits.
- }
- }
-+ cfg_if! {
-+ if #[cfg(target_os = "linux")] {
-+ use nix::unistd::*;
-+ use nix::sys::signal::*;
-+
-+ #[test]
-+ fn test_linux_api() {
-+ {
-+ let info = get_current_thread_info().unwrap();
-+ match promote_thread_to_real_time(info, 512, 44100) {
-+ Ok(_) => {
-+ }
-+ Err(e) => {
-+ panic!(e);
-+ }
-+ }
-+ }
-+ {
-+ let info = get_current_thread_info().unwrap();
-+ let bytes = info.serialize();
-+ let info2 = RtPriorityThreadInfo::deserialize(bytes);
-+ assert!(info == info2);
-+ }
-+ {
-+ let info = get_current_thread_info().unwrap();
-+ let bytes = thread_info_serialize(info);
-+ let info2 = thread_info_deserialize(bytes);
-+ assert!(info == info2);
-+ }
-+ }
-+ #[test]
-+ fn test_remote_promotion() {
-+ let (rd, wr) = pipe().unwrap();
-+
-+ match fork().expect("fork failed") {
-+ ForkResult::Parent{ child } => {
-+ eprintln!("Parent PID: {}", getpid());
-+ let mut bytes = [0 as u8;
std::mem::size_of::<RtPriorityThreadInfo>()];
-+ match read(rd, &mut bytes) {
-+ Ok(_) => {
-+ let info =
RtPriorityThreadInfo::deserialize(bytes);
-+ match promote_thread_to_real_time(info, 0,
44100) {
-+ Ok(_) => {
-+ eprintln!("thread promotion in the
child from the parent succeeded");
-+ assert!(true);
-+ }
-+ Err(_) => {
-+ eprintln!("promotion Err");
-+ assert!(false);
-+ }
-+ }
-+ }
-+ Err(e) => {
-+ eprintln!("could not read from the pipe:
{}", e);
-+ }
-+ }
-+ kill(child, SIGKILL).expect("Could not kill the
child?");
-+ }
-+ ForkResult::Child => {
-+ let r = set_real_time_hard_limit(0, 44100);
-+ if r.is_err() {
-+ eprintln!("Could not set RT limit, the test
will fail.");
-+ }
-+ eprintln!("Child pid: {}", getpid());
-+ let info = get_current_thread_info().unwrap();
-+ let bytes = info.serialize();
-+ match write(wr, &bytes) {
-+ Ok(_) => {
-+ loop {
-+
std::thread::sleep(std::time::Duration::from_millis(100));
-+ eprintln!("child sleeping, waiting to
be promoted...");
-+ }
-+ }
-+ Err(_) => {
-+ eprintln!("write error on the pipe.");
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
- }
-diff --git a/third_party/rust/audio_thread_priority/src/rt_linux.rs
b/third_party/rust/audio_thread_priority/src/rt_linux.rs
---- a/third_party/rust/audio_thread_priority/src/rt_linux.rs
-+++ b/third_party/rust/audio_thread_priority/src/rt_linux.rs
-@@ -4,132 +4,239 @@
-
- /* Widely copied from dbus-rs/dbus/examples/rtkit.rs */
-
- extern crate dbus;
- extern crate libc;
-
- use std::cmp;
- use std::error::Error;
-+use std::io::Error as OSError;
-
- use dbus::{Connection, BusType, Props, MessageItem, Message};
-
- const DBUS_SOCKET_TIMEOUT: i32 = 10_000;
- const RT_PRIO_DEFAULT: u32 = 10;
- // This is different from libc::pid_t, which is 32 bits, and is defined in
sys/types.h.
- #[allow(non_camel_case_types)]
- type kernel_pid_t = libc::c_long;
-
-+#[repr(C)]
-+#[derive(Clone, Copy)]
-+pub struct RtPriorityThreadInfoInternal {
-+ /// The PID of the process containing `thread_id` below.
-+ pid: libc::pid_t,
-+ /// System-wise thread id, use to promote the thread via dbus.
-+ thread_id: kernel_pid_t,
-+ /// Process-local thread id, used to restore scheduler characteristics.
This information is not
-+ /// useful in another process, but is useful tied to the `thread_id`,
when back into the first
-+ /// process.
-+ pthread_id: libc::pthread_t,
-+ /// ...
-+ policy: libc::c_int,
-+ /// ...
-+ param: libc::sched_param,
-+}
-+
-+impl RtPriorityThreadInfoInternal {
-+ /// Serialize a RtPriorityThreadInfoInternal to a byte buffer.
-+ pub fn serialize(&self) -> [u8; std::mem::size_of::<Self>()] {
-+ unsafe { std::mem::transmute::<Self, [u8;
std::mem::size_of::<Self>()]>(*self) }
-+ }
-+ /// Get an RtPriorityThreadInfoInternal from a byte buffer.
-+ pub fn deserialize(bytes: [u8; std::mem::size_of::<Self>()]) -> Self {
-+ unsafe { std::mem::transmute::<[u8; std::mem::size_of::<Self>()],
Self>(bytes) }
-+ }
-+}
-+
-+impl PartialEq for RtPriorityThreadInfoInternal {
-+ fn eq(&self, other: &Self) -> bool {
-+ self.thread_id == other.thread_id &&
-+ self.pthread_id == other.pthread_id
-+ }
-+}
-+
- /*#[derive(Debug)]*/
- pub struct RtPriorityHandleInternal {
-- /// Process-local thread id, used to restore scheduler characteristics.
-- pthread_id: libc::pthread_t,
-- /// The scheduler originaly associated with this thread (probably
SCHED_OTHER).
-- policy: libc::c_int,
-- /// The initial priority for this thread.
-- param: libc::sched_param,
-+ thread_info: RtPriorityThreadInfoInternal,
- }
-
- fn item_as_i64(i: MessageItem) -> Result<i64, Box<dyn Error>> {
- match i {
- MessageItem::Int32(i) => Ok(i as i64),
- MessageItem::Int64(i) => Ok(i),
- _ => Err(Box::from(&*format!("Property is not integer ({:?})", i)))
- }
- }
-
--fn rtkit_set_realtime(c: &Connection, thread: u64, prio: u32) -> Result<(),
Box<dyn Error>> {
-- let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1",
-- "/org/freedesktop/RealtimeKit1",
-- "org.freedesktop.RealtimeKit1",
-- "MakeThreadRealtime")?;
-- m.append_items(&[thread.into(), prio.into()]);
-+fn rtkit_set_realtime(thread: u64, pid: u64, prio: u32) -> Result<(),
Box<dyn Error>> {
-+ let m = if unsafe { libc::getpid() as u64 } == pid {
-+ let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1",
-+
"/org/freedesktop/RealtimeKit1",
-+ "org.freedesktop.RealtimeKit1",
-+ "MakeThreadRealtime")?;
-+ m.append_items(&[thread.into(), prio.into()]);
-+ m
-+ } else {
-+ let mut m = Message::new_method_call("org.freedesktop.RealtimeKit1",
-+
"/org/freedesktop/RealtimeKit1",
-+ "org.freedesktop.RealtimeKit1",
-+ "MakeThreadRealtimeWithPID")?;
-+ m.append_items(&[pid.into(), thread.into(), prio.into()]);
-+ m
-+ };
-+ let c = Connection::get_private(BusType::System)?;
- c.send_with_reply_and_block(m, DBUS_SOCKET_TIMEOUT)?;
- return Ok(());
- }
-
--fn make_realtime(tid: kernel_pid_t, requested_slice_us: u64, prio: u32) ->
Result<u32, Box<dyn Error>> {
-+/// Returns the maximum priority, maximum real-time time slice, and the
current real-time time
-+/// slice for this process.
-+fn get_limits() -> Result<(i64, u64, libc::rlimit64), Box<dyn Error>> {
- let c = Connection::get_private(BusType::System)?;
-
- let p = Props::new(&c, "org.freedesktop.RealtimeKit1",
"/org/freedesktop/RealtimeKit1",
-- "org.freedesktop.RealtimeKit1", DBUS_SOCKET_TIMEOUT);
-+ "org.freedesktop.RealtimeKit1", DBUS_SOCKET_TIMEOUT);
-+ let mut current_limit = libc::rlimit64 {
-+ rlim_cur: 0,
-+ rlim_max: 0
-+ };
-
-- // Make sure we don't fail by wanting too much
- let max_prio = item_as_i64(p.get("MaxRealtimePriority")?)?;
- if max_prio < 0 {
- return Err(Box::from("invalid negative MaxRealtimePriority"));
- }
-- let prio = cmp::min(prio, max_prio as u32);
-
-- // Enforce RLIMIT_RTPRIO, also a must before asking rtkit for rtprio
- let max_rttime = item_as_i64(p.get("RTTimeUSecMax")?)?;
- if max_rttime < 0 {
- return Err(Box::from("invalid negative RTTimeUSecMax"));
- }
-
-- // Only take what we need, or cap at the system limit, no further.
-- let rttime_request = cmp::min(requested_slice_us, max_rttime as u64);
--
-- // Set a soft limit to the limit requested, to be able to handle going
over the limit using
-- // SIXCPU. Set the hard limit to the maxium slice to prevent getting
SIGKILL.
-- let new_limit = libc::rlimit64 { rlim_cur: rttime_request,
-- rlim_max: max_rttime as u64 };
-- let mut old_limit = new_limit;
-- if unsafe { libc::getrlimit64(libc::RLIMIT_RTTIME, &mut old_limit) } <
0 {
-+ if unsafe { libc::getrlimit64(libc::RLIMIT_RTTIME, &mut current_limit)
} < 0 {
-+ error!("getrlimit64: {}",
OSError::last_os_error().raw_os_error().unwrap());
- return Err(Box::from("getrlimit failed"));
- }
-+
-+ Ok((max_prio, (max_rttime as u64), current_limit))
-+}
-+
-+fn set_limits(request: u64, max: u64) -> Result<(), Box<dyn Error>> {
-+ // Set a soft limit to the limit requested, to be able to handle going
over the limit using
-+ // SIGXCPU. Set the hard limit to the maxium slice to prevent getting
SIGKILL.
-+ let new_limit = libc::rlimit64 { rlim_cur: request,
-+ rlim_max: max };
- if unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &new_limit) } < 0 {
- return Err(Box::from("setrlimit failed"));
- }
-
-- // Finally, let's ask rtkit to make us realtime
-- let r = rtkit_set_realtime(&c, tid as u64, prio);
--
-- if r.is_err() {
-- unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &old_limit) };
-- return Err(Box::from("could not set process as real-time."));
-- }
--
-- Ok(prio)
-+ Ok(())
- }
-
- pub fn promote_current_thread_to_real_time_internal(audio_buffer_frames:
u32,
-- audio_samplerate_hz:
u32) -> Result<RtPriorityHandleInternal, ()>
--{
-+ audio_samplerate_hz:
u32)
-+ ->
Result<RtPriorityHandleInternal, ()> {
-+ let thread_info = get_current_thread_info_internal()?;
-+ promote_thread_to_real_time_internal(thread_info, audio_buffer_frames,
audio_samplerate_hz)
-+}
-+
-+pub fn demote_current_thread_from_real_time_internal(rt_priority_handle:
RtPriorityHandleInternal)
-+ -> Result<(), ()> {
-+ assert!(unsafe { libc::pthread_self() } ==
rt_priority_handle.thread_info.pthread_id);
-+
-+ if unsafe {
libc::pthread_setschedparam(rt_priority_handle.thread_info.pthread_id,
-+
rt_priority_handle.thread_info.policy,
-+
&rt_priority_handle.thread_info.param) } < 0 {
-+ error!("could not demote thread {}",
OSError::last_os_error().raw_os_error().unwrap());
-+ return Err(());
-+ }
-+ return Ok(());
-+}
-+
-+/// This can be called by sandboxed code, it only restores priority to what
they were.
-+pub fn demote_thread_from_real_time_internal(thread_info:
RtPriorityThreadInfoInternal)
-+ -> Result<(), ()> {
-+ let param = unsafe { std::mem::zeroed::<libc::sched_param>() };
-+
-+ // https://github.com/rust-lang/libc/issues/1511
-+ const SCHED_RESET_ON_FORK: libc::c_int = 0x40000000;
-+
-+ if unsafe { libc::pthread_setschedparam(thread_info.pthread_id,
-+
libc::SCHED_OTHER|SCHED_RESET_ON_FORK,
-+ &param) } < 0 {
-+ error!("could not demote thread {}",
OSError::last_os_error().raw_os_error().unwrap());
-+ return Err(());
-+ }
-+ return Ok(());
-+}
-+
-+/// Get the current thread information, as an opaque struct, that can be
serialized and sent
-+/// accross processes. This is enough to capture the current state of the
scheduling policy, and
-+/// an identifier to have another thread promoted to real-time.
-+pub fn get_current_thread_info_internal() ->
Result<RtPriorityThreadInfoInternal, ()> {
- let thread_id = unsafe { libc::syscall(libc::SYS_gettid) };
- let pthread_id = unsafe { libc::pthread_self() };
- let mut param = unsafe { std::mem::zeroed::<libc::sched_param>() };
- let mut policy = 0;
-
- if unsafe { libc::pthread_getschedparam(pthread_id, &mut policy, &mut
param) } < 0 {
-- error!("pthread_getschedparam error {}", pthread_id);
-+ error!("pthread_getschedparam error {}",
OSError::last_os_error().raw_os_error().unwrap());
- return Err(());
- }
-
-+ let pid = unsafe { libc::getpid() };
-+
-+ Ok(RtPriorityThreadInfoInternal {
-+ pid,
-+ thread_id,
-+ pthread_id,
-+ policy,
-+ param
-+ })
-+}
-+
-+/// This set the RLIMIT_RTTIME resource to something other than
"unlimited". It's necessary for the
-+/// rtkit request to succeed, and needs to hapen in the child. We can't get
the real limit here,
-+/// because we don't have access to DBUS, so it is hardcoded to 200ms,
which is the default in the
-+/// rtkit package.
-+pub fn set_real_time_hard_limit_internal(audio_buffer_frames: u32,
-+ audio_samplerate_hz: u32) ->
Result<(), ()> {
- let buffer_frames = if audio_buffer_frames > 0 {
- audio_buffer_frames
- } else {
- // 50ms slice. This "ought to be enough for anybody".
- audio_samplerate_hz / 20
- };
- let budget_us = (buffer_frames * 1_000_000 / audio_samplerate_hz) as
u64;
-- let handle = RtPriorityHandleInternal { pthread_id, policy, param};
-- let r = make_realtime(thread_id, budget_us, RT_PRIO_DEFAULT);
-- if r.is_err() {
-- warn!("Could not make thread real-time.");
-- return Err(());
-- }
-- return Ok(handle);
-+
-+ // It's only necessary to set RLIMIT_RTTIME to something when in the
child, skip it if it's a
-+ // remoting call.
-+ let (_, max_rttime, _) = get_limits().map_err(|_| {})?;
-+
-+ // Only take what we need, or cap at the system limit, no further.
-+ let rttime_request = cmp::min(budget_us, max_rttime as u64);
-+ set_limits(rttime_request, max_rttime).map_err(|_| {})?;
-+
-+ Ok(())
- }
-
--pub fn demote_current_thread_from_real_time_internal(rt_priority_handle:
RtPriorityHandleInternal)
-- -> Result<(), ()> {
-- assert!(unsafe { libc::pthread_self() } ==
rt_priority_handle.pthread_id);
-+/// Promote a thread (possibly in another process) identified by its tid,
to real-time.
-+pub fn promote_thread_to_real_time_internal(thread_info:
RtPriorityThreadInfoInternal,
-+ audio_buffer_frames: u32,
-+ audio_samplerate_hz: u32) ->
Result<RtPriorityHandleInternal, ()>
-+{
-+ let RtPriorityThreadInfoInternal { pid, thread_id, .. } = thread_info;
-+
-+ let handle = RtPriorityHandleInternal { thread_info };
-+
-+ let (_, _, limits) = get_limits().map_err(|_| {})?;
-+ set_real_time_hard_limit_internal(audio_buffer_frames,
audio_samplerate_hz)?;
-
-- if unsafe { libc::pthread_setschedparam(rt_priority_handle.pthread_id,
-- rt_priority_handle.policy,
-- &rt_priority_handle.param) } <
0 {
-- warn!("could not demote thread {}", rt_priority_handle.pthread_id);
-- return Err(());
-+ let r = rtkit_set_realtime(thread_id as u64, pid as u64,
RT_PRIO_DEFAULT);
-+
-+ if r.is_err() {
-+ if unsafe { libc::setrlimit64(libc::RLIMIT_RTTIME, &limits) } < 0 {
-+ error!("setrlimit64: {}",
OSError::last_os_error().raw_os_error().unwrap());
-+ return Err(());
-+ }
- }
-- return Ok(());
-+
-+ return Ok(handle);
- }
--



  • [SM-Commit] GIT changes to master grimoire by Pavel Vinogradov (485d8783c6524f7ceaf123e257b268a7abbd8c17), Pavel Vinogradov, 12/02/2019

Archive powered by MHonArc 2.6.24.

Top of Page