Modules: fixed shared dict state save stuck forever
The "dirty" and "writing" flags of a shared dict were bit fields of
the same word. ngx_js_dict_save() clears "writing" without holding
the lock, while set(), incr(), delete() and clear() set "dirty" under
the write lock in other workers. The two read-modify-write operations
could interleave and leave "writing" set for good.
After that, every save attempt returned NGX_AGAIN: the state file was
never written again, and the save timer, re-armed every second and not
cancelable, prevented any worker of the zone from finishing a graceful
shutdown, regardless of worker_shutdown_timeout. The flag lives in
shared memory, so it survived reloads.
The fix is to store the flags in separate words.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This fixes #1136.