* Fix debug build: compile error, false-positive abort, and crash DB lock
- psql_debug.c: add forward declaration for psql_do_prepare to fix
conflicting-types compile error (BUILD=debug was broken entirely)
- pfs_debug.c: change pfs_debug_check_lock_order from abort to log-only;
write paths legitimately take file lock before SQL and handle ordering
via psql_trylock()+relock in pfs_reopen_file_for_writing — no actual
deadlock risk, the check was a false positive
- psignal.c/h: add psignal_register_cleanup() hook mechanism; change
panic() to use _exit(1) instead of abort() so all file descriptors are
closed on crash, releasing SQLite WAL POSIX advisory locks immediately
and preventing ASan from hanging the process as a zombie
- psql.c: register psql_panic_cleanup() hook to close the DB on panic
(belt-and-suspenders alongside _exit fd cleanup)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix debug psql_trylock: missing strong override left lockctr unupdated
The weak psql_trylock() stub in psql.c called plocks_trywrlock() directly
without updating lockctr. In the debug build, psql_unlock() asserts
lockctr > 0, so when trylock succeeded (lock acquired, lockctr still 0)
the assert fired with SIGABRT on write ops via pfs_inc_writeid_locked.
Add a strong psql_trylock() override in psql_debug.c that delegates to
psql_do_trylock(), which properly acquires the rwlock and updates lockctr.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add psignal module for centralized signal handling
- Added pclsync/psignal.h with psignal_register() and psignal_check_pending() API
- Added pclsync/psignal.c with async-signal-safe handlers for SIGINT, SIGTERM, SIGHUP
- Implements flag-based deferred signal handling pattern
* Integrate psignal into main loop and remove conflicting handlers
- Added extern "C" linkage to psignal.h for C++ compatibility
- Integrated psignal_check_pending() into pclsync_lib.cpp main loop
- Integrated psignal_check_pending() into ptimer.c timer loop
- Removed conflicting signal handlers from pfs.c
* Migrate psync_set_signal to psignal module
- Added psignal_set_custom_handler() to psignal.h and psignal.c
- Replaced psync_set_signal() calls in pfs.c with psignal_set_custom_handler()
- Centralizes all signal handling in psignal module
---------
Co-authored-by: Levi Neely <lkn@darkstar.example.net>