🔢 What is cntr
in struct xid_command
?
In glibc’s struct xid_command
, the field:
volatile int cntr;
is used as a synchronization counter to track how many threads still need to process the UID/GID change triggered by __nptl_setxid()
.
🔄 Role of cntr
-
When a UID/GID change (like
setuid()
) is initiated, glibc sends aSIGSETXID
signal to each thread. -
Each thread runs the
__nptl_setxid_sighandler
, which:- Performs the
setuid
-like syscall - Decrements
xidcmd->cntr
- If the result of decrementing is
1
, the current thread is the last one to finish- It then wakes up the initiating thread via futex
- Performs the
🧩 How It’s Used
In the signal handler:
if (atomic_fetch_add_relaxed(&xidcmd->cntr, -1) == 1)
futex_wake((unsigned int *) &xidcmd->cntr, 1, FUTEX_PRIVATE);
- Each thread atomically decrements the counter.
- The thread that sees it reach
0
(via== 1
before subtracting) knows it was the last - It then wakes the initiating thread that is waiting for all threads to complete.
🚦 Why It’s Volatile
- Marked
volatile
so that changes are not optimized away or cached across threads. - Ensures correctness in multithreaded, signal-driven context.
📌 Summary
Field | Purpose |
---|---|
cntr | Synchronization counter used to detect when all threads have finished applying a UID/GID change |
It’s a simple but effective way to wait for all threads to acknowledge and apply an identity transition in a race-free and safe manner.