annotate rust/chg/src/procutil.rs @ 50400:95acba2c29f6

encoding: avoid quadratic time complexity when json-encoding non-UTF8 strings Apparently the code uses "+=" with a bytes object, which is linear-time, so the whole encoding is quadratic-time. This patch makes us use a bytearray object, instead, which has a(n amortized-)constant-time append operation. The encoding is still not particularly fast, but at least a 10MB file takes tens of seconds, not many hours to encode.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Mon, 06 Mar 2023 11:27:57 +0000
parents 426294d06ddc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39970
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
1 // Copyright 2018 Yuya Nishihara <yuya@tcha.org>
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
2 //
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
5
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
6 //! Low-level utility for signal and process handling.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
7
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
8 use libc::{self, c_int, pid_t, size_t, ssize_t};
39970
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
9 use std::io;
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
10 use std::os::unix::io::RawFd;
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
11 use std::sync;
39970
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
12
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
13 #[link(name = "procutil", kind = "static")]
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
14 extern "C" {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
15 // sendfds.c
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
16 fn sendfds(sockfd: c_int, fds: *const c_int, fdlen: size_t) -> ssize_t;
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
17
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
18 // sighandlers.c
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
19 fn setupsignalhandler(pid: pid_t, pgid: pid_t) -> c_int;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
20 fn restoresignalhandler() -> c_int;
39970
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
21 }
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
22
39976
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39973
diff changeset
23 /// Returns the effective uid of the current process.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39973
diff changeset
24 pub fn get_effective_uid() -> u32 {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39973
diff changeset
25 unsafe { libc::geteuid() }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39973
diff changeset
26 }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39973
diff changeset
27
44683
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
28 /// Returns the umask of the current process.
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
29 ///
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
30 /// # Safety
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
31 ///
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
32 /// This is unsafe because the umask value is temporarily changed, and
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
33 /// the change can be observed from the other threads. Don't call this in
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
34 /// multi-threaded context.
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
35 pub unsafe fn get_umask() -> u32 {
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
36 let mask = libc::umask(0);
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
37 libc::umask(mask);
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
38 mask
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
39 }
065048e66f32 rust-chg: send client side umask to server
Yuya Nishihara <yuya@tcha.org>
parents: 43818
diff changeset
40
39973
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
41 /// Changes the given fd to blocking mode.
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
42 pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> {
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
43 let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
44 if flags < 0 {
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
45 return Err(io::Error::last_os_error());
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
46 }
45620
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
47 let r =
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
48 unsafe { libc::fcntl(fd, libc::F_SETFL, flags & !libc::O_NONBLOCK) };
39973
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
49 if r < 0 {
43818
ce088b38f92b rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents: 40120
diff changeset
50 return Err(io::Error::last_os_error());
39973
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
51 }
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
52 Ok(())
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
53 }
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39970
diff changeset
54
39970
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
55 /// Sends file descriptors via the given socket.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
56 pub fn send_raw_fds(sock_fd: RawFd, fds: &[RawFd]) -> io::Result<()> {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
57 let r = unsafe { sendfds(sock_fd, fds.as_ptr(), fds.len() as size_t) };
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
58 if r < 0 {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
59 return Err(io::Error::last_os_error());
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
60 }
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
61 Ok(())
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
62 }
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
63
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
64 static SETUP_SIGNAL_HANDLER: sync::Once = sync::Once::new();
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
65 static RESTORE_SIGNAL_HANDLER: sync::Once = sync::Once::new();
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
66
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
67 /// Installs signal handlers to forward signals to the server.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
68 ///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
69 /// # Safety
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
70 ///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
71 /// This touches global states, and thus synchronized as a one-time
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
72 /// initialization function.
45620
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
73 pub fn setup_signal_handler_once(
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
74 pid: u32,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
75 pgid: Option<u32>,
426294d06ddc rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents: 44683
diff changeset
76 ) -> io::Result<()> {
40120
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
77 let pid_signed = pid as i32;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
78 let pgid_signed = pgid.map(|n| n as i32).unwrap_or(0);
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
79 let mut r = 0;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
80 SETUP_SIGNAL_HANDLER.call_once(|| {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
81 r = unsafe { setupsignalhandler(pid_signed, pgid_signed) };
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
82 });
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
83 if r < 0 {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
84 return Err(io::Error::last_os_error());
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
85 }
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
86 Ok(())
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
87 }
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
88
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
89 /// Restores the original signal handlers.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
90 ///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
91 /// # Safety
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
92 ///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
93 /// This touches global states, and thus synchronized as a one-time
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
94 /// initialization function.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
95 pub fn restore_signal_handler_once() -> io::Result<()> {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
96 let mut r = 0;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
97 RESTORE_SIGNAL_HANDLER.call_once(|| {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
98 r = unsafe { restoresignalhandler() };
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
99 });
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
100 if r < 0 {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
101 return Err(io::Error::last_os_error());
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
102 }
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
103 Ok(())
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39976
diff changeset
104 }