diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 48adae569..04b1511ea 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -34,7 +34,7 @@ static sig_t _oldhandler; static sigset_t _fullsigset, _intsigset; static int _handler_installed; -static int _release_lock(const char *file) +static int _release_lock(const char *file, int unlock) { struct lock_list *ll; struct list *llh, *llt; @@ -46,10 +46,11 @@ static int _release_lock(const char *file) if (!file || !strcmp(ll->res, file)) { list_del(llh); - log_very_verbose("Unlocking %s", ll->res); - - if (flock(ll->lf, LOCK_NB | LOCK_UN)) - log_sys_error("flock", ll->res); + if (unlock) { + log_very_verbose("Unlocking %s", ll->res); + if (flock(ll->lf, LOCK_NB | LOCK_UN)) + log_sys_error("flock", ll->res); + } if (!flock(ll->lf, LOCK_NB | LOCK_EX) && !stat(ll->res, &buf1) && @@ -74,7 +75,12 @@ static int _release_lock(const char *file) static void _fin_file_locking(void) { - _release_lock(NULL); + _release_lock(NULL, 1); +} + +static void _reset_file_locking(void) +{ + _release_lock(NULL, 0); } static void _remove_ctrl_c_handler() @@ -127,7 +133,7 @@ static int _lock_file(const char *file, int flags) state = 'W'; break; case LCK_UNLOCK: - return _release_lock(file); + return _release_lock(file, 1); default: log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK); return 0; @@ -233,6 +239,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, int init_file_locking(struct locking_type *locking, struct config_tree *cf) { locking->lock_resource = _file_lock_resource; + locking->reset_locking = _reset_file_locking; locking->fin_locking = _fin_file_locking; /* Get lockfile directory from config file */ diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 5af4db452..0278dbefc 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -86,6 +86,19 @@ static void _unblock_signals(void) return; } +void reset_locking(void) +{ + int was_locked = _lock_count; + + _lock_count = 0; + _write_lock_held = 0; + + _locking.reset_locking(); + + if (was_locked) + _unblock_signals(); +} + static inline void _update_lock_count(int flags) { if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK) diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 92a44f3ed..430711180 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -11,6 +11,7 @@ int init_locking(int type, struct config_tree *cf); void fin_locking(void); +void reset_locking(void); /* * LCK_VG: diff --git a/lib/locking/locking_types.h b/lib/locking/locking_types.h index cc693af10..03c92274c 100644 --- a/lib/locking/locking_types.h +++ b/lib/locking/locking_types.h @@ -12,10 +12,12 @@ typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource, int flags); typedef void (*fin_lock_fn) (void); +typedef void (*reset_lock_fn) (void); struct locking_type { lock_resource_fn lock_resource; + reset_lock_fn reset_locking; fin_lock_fn fin_locking; }; diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c index 1fd8f8dbc..79f23b883 100644 --- a/lib/locking/no_locking.c +++ b/lib/locking/no_locking.c @@ -22,6 +22,11 @@ static void _no_fin_locking(void) return; } +static void _no_reset_locking(void) +{ + return; +} + static int _no_lock_resource(struct cmd_context *cmd, const char *resource, int flags) { @@ -54,6 +59,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource, int init_no_locking(struct locking_type *locking, struct config_tree *cf) { locking->lock_resource = _no_lock_resource; + locking->reset_locking = _no_reset_locking; locking->fin_locking = _no_fin_locking; return 1;