Checked Then Freed

Two threads in a connection server:

/* worker thread */
if (conn->hostname) {
    log_line("serving %s", conn->hostname);
}

/* reaper thread */
free(conn->hostname);
conn->hostname = NULL;

Under load the worker segfaults inside log_line on a pointer that tested non-NULL microseconds earlier. Which change fixes it?

A

Reorder the reaper to set conn->hostname = NULL first and call free afterwards.

B

Take one mutex around the check and the use in the worker, and around the free and the clear in the reaper.

C

Declare the field as _Atomic(char *) so the load and the store cannot tear.

D

Copy conn->hostname into a local, test the local, and pass the local to log_line.