c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef FILE_LOCK_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define FILE_LOCK_H
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#include <unistd.h>
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#include <fcntl.h>
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen#define DEFAULT_LOCK_TIMEOUT 120
9e86ad9eb313004cd4c8b5427daeb4c241b57af6Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenstruct file_lock;
f27a51cd9a66685b63357de25e733c37eb03b07cTimo Sirainenstruct dotlock;
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenenum file_lock_method {
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen FILE_LOCK_METHOD_FCNTL,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen FILE_LOCK_METHOD_FLOCK,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen FILE_LOCK_METHOD_DOTLOCK
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen};
c2bb1764c359ce85a7f7f789ead11dd613ff9769Timo Sirainen
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen/* Parse lock method from given string. Returns TRUE if ok,
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen FALSE if name is unknown. */
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainenbool file_lock_method_parse(const char *name, enum file_lock_method *method_r);
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainen/* Convert lock method to string. */
8c8f7ac580b661aee3d8b8dd37df4a9b41c77000Timo Sirainenconst char *file_lock_method_to_str(enum file_lock_method method);
6e77746e501c2b45850b1c530836058ed75e09eeTimo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen/* Lock the file. Returns 1 if successful, 0 if file is already locked,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen or -1 if error. lock_type is F_WRLCK or F_RDLCK. */
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenint file_try_lock(int fd, const char *path, int lock_type,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen enum file_lock_method lock_method,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct file_lock **lock_r);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen/* Like file_try_lock(), but return the error message as a string instead
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen of logging it. Also when returning 0 an error message is returned. */
0dc7891233a973829f00371b27810f849b987c66Timo Sirainenint file_try_lock_error(int fd, const char *path, int lock_type,
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen enum file_lock_method lock_method,
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen struct file_lock **lock_r, const char **error_r);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen/* Like lock_try_lock(), but return 0 only after having tried to lock for
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen timeout_secs. */
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenint file_wait_lock(int fd, const char *path, int lock_type,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen enum file_lock_method lock_method,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen unsigned int timeout_secs,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct file_lock **lock_r);
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen/* Like file_wait_lock(), but return the error message as a string instead
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen of logging it. Also when returning 0 an error message is returned. */
0dc7891233a973829f00371b27810f849b987c66Timo Sirainenint file_wait_lock_error(int fd, const char *path, int lock_type,
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen enum file_lock_method lock_method,
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen unsigned int timeout_secs,
0dc7891233a973829f00371b27810f849b987c66Timo Sirainen struct file_lock **lock_r, const char **error_r);
cac6b8b1a2bcf672fe43d3fb91a7278877f8cf09Timo Sirainen/* Change the lock type. WARNING: This isn't an atomic operation!
cac6b8b1a2bcf672fe43d3fb91a7278877f8cf09Timo Sirainen The result is the same as file_unlock() + file_try_lock(). */
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenint file_lock_try_update(struct file_lock *lock, int lock_type);
3581ece16eb740a5003c4c11dd3c7d02839a24a4Timo Sirainen/* When the lock is freed, unlink() the file automatically, unless other
3581ece16eb740a5003c4c11dd3c7d02839a24a4Timo Sirainen processes are already waiting on the lock. This can be useful for files that
3581ece16eb740a5003c4c11dd3c7d02839a24a4Timo Sirainen are only created to exist as lock files. */
68332e3a49dea15013aa8f4daa16b5e07eb3d543Timo Sirainenvoid file_lock_set_unlink_on_free(struct file_lock *lock, bool set);
65f9a90ef5ed4c86fb9e44f22e472509126ae9f5Timo Sirainen/* When the lock is freed, close the fd automatically. This can
65f9a90ef5ed4c86fb9e44f22e472509126ae9f5Timo Sirainen be useful for files that are only created to exist as lock files. */
65f9a90ef5ed4c86fb9e44f22e472509126ae9f5Timo Sirainenvoid file_lock_set_close_on_free(struct file_lock *lock, bool set);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
f27a51cd9a66685b63357de25e733c37eb03b07cTimo Sirainen/* Convert dotlock into file_lock, which can be deleted with either
f27a51cd9a66685b63357de25e733c37eb03b07cTimo Sirainen file_unlock() or file_lock_free(). */
f27a51cd9a66685b63357de25e733c37eb03b07cTimo Sirainenstruct file_lock *file_lock_from_dotlock(struct dotlock **dotlock);
f27a51cd9a66685b63357de25e733c37eb03b07cTimo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen/* Unlock and free the lock. */
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenvoid file_unlock(struct file_lock **lock);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen/* Free the lock without unlocking it (because you're closing the fd anyway). */
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainenvoid file_lock_free(struct file_lock **lock);
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen
f1243d7759a3dddc1c3eaf7eda8a153c8ef0112bTimo Sirainen/* Returns the path given as parameter to file_*lock*(). */
f1243d7759a3dddc1c3eaf7eda8a153c8ef0112bTimo Sirainenconst char *file_lock_get_path(struct file_lock *lock);
d8d93ecd89efa7c84a3a21264a550449619f715bTimo Sirainen/* Update lock file's path (after it gets renamed by the caller). This is
d8d93ecd89efa7c84a3a21264a550449619f715bTimo Sirainen useful mainly together with file_lock_set_unlink_on_free(). */
d8d93ecd89efa7c84a3a21264a550449619f715bTimo Sirainenvoid file_lock_set_path(struct file_lock *lock, const char *path);
f1243d7759a3dddc1c3eaf7eda8a153c8ef0112bTimo Sirainen
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen/* Returns human-readable string containing the process that has the file
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen currently locked. Returns "" if unknown, otherwise " (string)". */
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainenconst char *file_lock_find(int lock_fd, enum file_lock_method lock_method,
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen int lock_type);
1107c86ff3fa4f29796c2e76134b78d0b4a0db50Timo Sirainen
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen/* Track the duration of a lock wait. */
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainenvoid file_lock_wait_start(void);
f83fd83f9c6708d198748e714aa947cad9362c02Timo Sirainenvoid file_lock_wait_end(const char *lock_name);
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen/* Return how many microseconds has been spent on lock waiting. */
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainenuint64_t file_lock_wait_get_total_usecs(void);
4a7e04d325db0c03f575f98f045246fceb0de279Timo Sirainen
02b32cf39a098edf60981fc228e4b034f11f3b90Timo Sirainen#endif