diff --git a/pclsync/debug/pfs_debug.c b/pclsync/debug/pfs_debug.c index e5ead10..868b598 100644 --- a/pclsync/debug/pfs_debug.c +++ b/pclsync/debug/pfs_debug.c @@ -45,3 +45,10 @@ void pfs_debug_register_signal_handlers() { sa.sa_flags = 0; sigaction(SIGUSR1, &sa, NULL); } + +void pfs_debug_check_lock_order(const char *file, unsigned long line) { + if (!psql_locked()) { + pdbg_logf(D_ERROR, "lock ordering violation: pfs_lock_file called without psql_lock at %s:%lu", file, line); + abort(); + } +} diff --git a/pclsync/pfs.c b/pclsync/pfs.c index 6d22621..9e07c16 100644 --- a/pclsync/pfs.c +++ b/pclsync/pfs.c @@ -117,6 +117,7 @@ __attribute__((weak)) void pfs_debug_init_file_mutex(pthread_mutex_t *m) { } __attribute__((weak)) void pfs_debug_dump_internals() {} __attribute__((weak)) void pfs_debug_register_signal_handlers() {} +__attribute__((weak)) void pfs_debug_check_lock_order(const char *file, unsigned long line) {} static int pfs_ftruncate_of_locked(psync_openfile_t *of, fuse_off_t size); diff --git a/pclsync/pfs.h b/pclsync/pfs.h index db14a3b..f36b1ba 100644 --- a/pclsync/pfs.h +++ b/pclsync/pfs.h @@ -45,6 +45,7 @@ #include "pfoldersync.h" #include "ptimer.h" #include "ptree.h" +#include "psql.h" #define pfs_need_per_folder_refresh() pfs_need_per_folder_refresh_f() #define pfs_need_per_folder_refresh_const() 1 @@ -137,6 +138,8 @@ typedef struct { int dummy[0]; } pfs_index_header; +void pfs_debug_check_lock_order(const char *file, unsigned long line); + #if IS_DEBUG #define pfs_lock_file(of) pfs_do_lock_file(of, __FILE__, __LINE__) @@ -145,6 +148,7 @@ typedef struct { extern PSYNC_THREAD const char *psync_thread_name; static inline int pfs_do_lock_file(psync_openfile_t *of, const char *file, unsigned long line) { + pfs_debug_check_lock_order(file, line); if (unlikely(pthread_mutex_trylock(&of->mutex))) { struct timespec tm; clock_gettime(CLOCK_REALTIME, &tm);