🔢 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 a SIGSETXID signal to each thread.

  • Each thread runs the __nptl_setxid_sighandler, which:

    1. Performs the setuid-like syscall
    2. Decrements xidcmd->cntr
    3. 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

🧩 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

FieldPurpose
cntrSynchronization 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.