Skip to content

Commit 774b813

Browse files
add TLS-based fork-inflight guard
1 parent 5d332d6 commit 774b813

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

libc/src/__support/OSUtil/linux/pid.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace LIBC_NAMESPACE {
1414

1515
pid_t ProcessIdentity::cache = -1;
16+
thread_local bool ProcessIdentity::fork_inflight = false;
1617
pid_t ProcessIdentity::get_uncached() {
1718
return syscall_impl<pid_t>(SYS_getpid);
1819
}

libc/src/__support/OSUtil/pid.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
namespace LIBC_NAMESPACE {
1515

1616
class ProcessIdentity {
17+
static thread_local bool fork_inflight;
1718
static pid_t cache;
1819
static pid_t get_uncached();
1920

2021
public:
21-
LIBC_INLINE static void invalidate_cache() { cache = -1; }
22+
LIBC_INLINE static void start_fork() { fork_inflight = true; }
23+
LIBC_INLINE static void end_fork() { fork_inflight = false; }
2224
LIBC_INLINE static void refresh_cache() { cache = get_uncached(); }
2325
LIBC_INLINE static pid_t get() {
24-
if (LIBC_UNLIKELY(cache < 0))
26+
if (LIBC_UNLIKELY(fork_inflight))
2527
return get_uncached();
2628
return cache;
2729
}

libc/src/unistd/linux/fork.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ LLVM_LIBC_FUNCTION(pid_t, fork, (void)) {
3030
// getting wrong values. gettid() is not async-signal-safe, but let's provide
3131
// our best efforts here.
3232
self.invalidate_tid();
33-
ProcessIdentity::invalidate_cache();
33+
ProcessIdentity::start_fork();
3434

3535
#ifdef SYS_fork
3636
pid_t ret = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_fork);
@@ -46,15 +46,20 @@ LLVM_LIBC_FUNCTION(pid_t, fork, (void)) {
4646
return -1;
4747
}
4848

49+
// Common
4950
// Refresh tid/pid cache after fork
5051
self.refresh_tid();
51-
ProcessIdentity::refresh_cache();
5252

53+
// Child process
5354
if (ret == 0) {
55+
ProcessIdentity::refresh_cache();
56+
ProcessIdentity::end_fork();
5457
invoke_child_callbacks();
5558
return 0;
5659
}
5760

61+
// Parent process
62+
ProcessIdentity::end_fork();
5863
invoke_parent_callbacks();
5964
return ret;
6065
}

0 commit comments

Comments
 (0)