2 * Copyright (c) 2017, De Rais <derais@cock.li>
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
30 static int *lock_table
= 0;
31 static size_t lock_table_len
= 0;
34 * Set up the lock files and make sure we can connect to them.
38 * - setup_locks() was not invoked more recently than clean_locks().
40 * Postconditions (success):
42 * - Any other function in this file may be safely called.
44 int setup_locks(const struct configuration
*conf
)
54 if (!(lock_table
= malloc(conf
->boards_num
* sizeof *lock_table
))) {
55 PERROR_MESSAGE("malloc");
56 ERROR_MESSAGE("Cannot set up locks");
60 for (size_t j
= 0; j
< conf
->boards_num
; ++j
) {
64 for (size_t j
= 0; j
< conf
->boards_num
; ++j
) {
65 len
= snprintf(0, 0, "%s/lock_board_%s", conf
->work_path
,
66 conf
->boards
[j
].name
);
68 if (!(path
= malloc(len
+ 1))) {
69 PERROR_MESSAGE("malloc");
73 sprintf(path
, "%s/lock_board_%s", conf
->work_path
,
74 conf
->boards
[j
].name
);
76 if (!(lock_table
[j
] = open(path
, O_RDWR
| O_CREAT
, 0700))) {
77 PERROR_MESSAGE("open");
78 ERROR_MESSAGE("Cannot open or create lock file %s",
88 lock_table_len
= conf
->boards_num
;
96 * Get a lock for a board
100 * - board_idx represents a board.
102 * - The lock for board_idx is not held in this program.
104 * Postconditions (success):
106 * - The lock for board_idx is now held by this program.
108 int lock_acquire(size_t board_idx
)
113 lock_table
[board_idx
] < 0) {
114 ERROR_MESSAGE("lock_table isn't set up yet");
118 if (lockf(lock_table
[board_idx
], F_LOCK
, 0) < 0) {
119 PERROR_MESSAGE("lockf");
120 ERROR_MESSAGE("Cannot lock board %zu", board_idx
);
131 * Release a lock for a board
135 * - board_idx represents a board.
137 * - The lock for board_idx is held in this program.
139 * Postconditions (success):
141 * - The lock for board_idx is now not held by this program.
143 int lock_release(size_t board_idx
)
146 lock_table
[board_idx
] < 0) {
150 if (lockf(lock_table
[board_idx
], F_ULOCK
, 0) < 0) {
151 PERROR_MESSAGE("lockf");
152 ERROR_MESSAGE("Cannot release lock for board %zu", board_idx
);
161 * Clean up any memory from this file
163 * Postconditions (success):
165 * - Valgrind won't report any memory leaks from this file.
167 * - setup_locks() can be safely called again.
169 int clean_locks(void)
175 for (size_t j
= 0; j
< lock_table_len
; ++j
) {
177 close(lock_table
[j
]);