1 #ifndef FILE_LOCK_H
2 #define FILE_LOCK_H
3 
4 #include <unistd.h>
5 #include <fcntl.h>
6 
7 #define DEFAULT_LOCK_TIMEOUT 120
8 
9 struct file_lock;
10 struct dotlock;
11 
12 enum file_lock_method {
13 	FILE_LOCK_METHOD_FCNTL,
14 	FILE_LOCK_METHOD_FLOCK,
15 	FILE_LOCK_METHOD_DOTLOCK
16 };
17 
18 struct file_lock_settings {
19 	enum file_lock_method lock_method;
20 
21 	/* When the lock is freed, close the fd automatically. This can
22 	   be useful for files that are only created to exist as lock files. */
23 	bool unlink_on_free:1;
24 	/* When the lock is freed, unlink() the file automatically, unless other
25 	   processes are already waiting on the lock. This can be useful for
26 	   files that are only created to exist as lock files. */
27 	bool close_on_free:1;
28 	/* Do not panic when the kernel returns EDEADLK while acquiring the
29 	   lock. */
30 	bool allow_deadlock:1;
31 };
32 
33 /* Parse lock method from given string. Returns TRUE if ok,
34    FALSE if name is unknown. */
35 bool file_lock_method_parse(const char *name, enum file_lock_method *method_r);
36 /* Convert lock method to string. */
37 const char *file_lock_method_to_str(enum file_lock_method method);
38 
39 /* Lock the file. Returns 1 if successful, 0 if file is already locked,
40    or -1 if error. lock_type is F_WRLCK or F_RDLCK. */
41 int file_try_lock(int fd, const char *path, int lock_type,
42 		  const struct file_lock_settings *set,
43 		  struct file_lock **lock_r, const char **error_r);
44 /* Like lock_try_lock(), but return 0 only after having tried to lock for
45    timeout_secs. */
46 int file_wait_lock(int fd, const char *path, int lock_type,
47 		   const struct file_lock_settings *set,
48 		   unsigned int timeout_secs,
49 		   struct file_lock **lock_r, const char **error_r);
50 /* Change the lock type. WARNING: This isn't an atomic operation!
51    The result is the same as file_unlock() + file_try_lock(). */
52 int file_lock_try_update(struct file_lock *lock, int lock_type);
53 /* When the lock is freed, unlink() the file automatically, unless other
54    processes are already waiting on the lock. This can be useful for files that
55    are only created to exist as lock files. */
56 void file_lock_set_unlink_on_free(struct file_lock *lock, bool set);
57 /* When the lock is freed, close the fd automatically. This can
58    be useful for files that are only created to exist as lock files. */
59 void file_lock_set_close_on_free(struct file_lock *lock, bool set);
60 
61 /* Convert dotlock into file_lock, which can be deleted with either
62    file_unlock() or file_lock_free(). */
63 struct file_lock *file_lock_from_dotlock(struct dotlock **dotlock);
64 
65 /* Unlock and free the lock. */
66 void file_unlock(struct file_lock **lock);
67 /* Free the lock without unlocking it (because you're closing the fd anyway). */
68 void file_lock_free(struct file_lock **lock);
69 
70 /* Returns the path given as parameter to file_*lock*(). */
71 const char *file_lock_get_path(struct file_lock *lock);
72 /* Update lock file's path (after it gets renamed by the caller). This is
73    useful mainly together with file_lock_set_unlink_on_free(). */
74 void file_lock_set_path(struct file_lock *lock, const char *path);
75 
76 /* Returns human-readable string containing the process that has the file
77    currently locked. Returns "" if unknown, otherwise " (string)". */
78 const char *file_lock_find(int lock_fd, enum file_lock_method lock_method,
79 			   int lock_type);
80 
81 /* Track the duration of a lock wait. */
82 void file_lock_wait_start(void);
83 void file_lock_wait_end(const char *lock_name);
84 /* Return how many microseconds has been spent on lock waiting. */
85 uint64_t file_lock_wait_get_total_usecs(void);
86 
87 #endif
88