|
27 | 27 | #include <sys/file.h> |
28 | 28 | #include <sys/stat.h> |
29 | 29 |
|
| 30 | +#include <cerrno> |
30 | 31 | #include <chrono> |
31 | 32 | #include <fstream> |
32 | 33 | #include <map> |
@@ -169,15 +170,43 @@ std::string GeometryEntry::accessFile(const std::string& path, const std::string |
169 | 170 | return localPath; |
170 | 171 | } |
171 | 172 |
|
172 | | - // Try to acquire exclusive lock (blocks until available) |
173 | | - LOG(info) << " --- Acquiring lock for: " << localPath; |
174 | | - if (flock(lockFd, LOCK_EX) == -1) { |
| 173 | + // Try to acquire exclusive lock (non-blocking) |
| 174 | + LOG(info) << " --- Attempting to acquire lock for: " << localPath; |
| 175 | + int lockResult = flock(lockFd, LOCK_EX | LOCK_NB); |
| 176 | + |
| 177 | + if (lockResult == -1 && errno == EWOULDBLOCK) { |
| 178 | + // Lock is held by another process - wait up to 10 minutes for download to complete |
| 179 | + LOG(info) << " --- Lock is held by another process. Waiting for download to complete (up to 10 minutes)..."; |
| 180 | + close(lockFd); |
| 181 | + |
| 182 | + const auto startTime = std::chrono::steady_clock::now(); |
| 183 | + const auto timeout = std::chrono::minutes(10); |
| 184 | + const auto checkInterval = std::chrono::seconds(5); |
| 185 | + |
| 186 | + while (true) { |
| 187 | + // Check if download is complete |
| 188 | + if (stat(doneFile.c_str(), &buffer) == 0) { |
| 189 | + LOG(info) << " --- Geometry configuration file was downloaded by another process: " << localPath; |
| 190 | + return localPath; |
| 191 | + } |
| 192 | + |
| 193 | + // Check timeout |
| 194 | + auto elapsed = std::chrono::steady_clock::now() - startTime; |
| 195 | + if (elapsed >= timeout) { |
| 196 | + LOG(fatal) << " --- Timeout waiting for geometry file download: " << localPath << ". Waited for 10 minutes."; |
| 197 | + return localPath; |
| 198 | + } |
| 199 | + |
| 200 | + // Wait before checking again |
| 201 | + std::this_thread::sleep_for(checkInterval); |
| 202 | + } |
| 203 | + } else if (lockResult == -1) { |
175 | 204 | LOG(error) << " --- Failed to acquire lock for: " << lockFile; |
176 | 205 | close(lockFd); |
177 | 206 | return localPath; |
178 | 207 | } |
179 | 208 |
|
180 | | - // Double-check if file was downloaded while waiting for lock |
| 209 | + // Lock acquired successfully - double-check if file was downloaded while we were trying |
181 | 210 | if (stat(doneFile.c_str(), &buffer) == 0) { |
182 | 211 | LOG(info) << " --- Geometry configuration file was downloaded by another process: " << localPath; |
183 | 212 | flock(lockFd, LOCK_UN); |
|
0 commit comments