Mercurial > public > mercurial-scm > hg
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 |
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 } |