annotate rust/chg/src/procutil.rs @ 48178:f12a19d03d2c

fix: reduce number of tool executions By grouping together (path, ctx) pairs according to the inputs they would provide to fixer tools, we can deduplicate executions of fixer tools to significantly reduce the amount of time spent running slow tools. This change does not handle clean files in the working copy, which could still be deduplicated against the files in the checked out commit. It's a little harder to do that because the filerev is not available in the workingfilectx (and it doesn't exist for added files). Anecdotally, this change makes some real uses cases at Google 10x faster. I think we were originally hesitant to do this because the benefits weren't obvious, and implementing it efficiently is kind of tricky. If we simply memoized the formatter execution function, we would be keeping tons of file content in memory. Also included is a regression test for a corner case that I broke with my first attempt at optimizing this code. Differential Revision: https://phab.mercurial-scm.org/D11280
author Danny Hooper <hooper@google.com>
date Thu, 02 Sep 2021 14:08:45 -0700
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 }