@@ -237,40 +237,53 @@ class RobustSharedLock
237
237
bool * was_lock_created,
238
238
bool * was_lock_released)
239
239
{
240
- auto fd = open (file_path.c_str (), O_RDONLY, 0 );
240
+ int fd = -1 ;
241
+ do {
242
+ fd = open (file_path.c_str (), O_RDONLY, 0 );
241
243
242
- if (fd != -1 )
243
- {
244
- *was_lock_created = false ;
245
- }
246
- else
247
- {
248
- *was_lock_created = true ;
249
- fd = open (file_path.c_str (), O_CREAT | O_RDONLY, 0666 );
250
- }
251
-
252
- if (was_lock_released != nullptr )
253
- {
254
- // Lock exclusive
255
- if (0 == flock (fd, LOCK_EX | LOCK_NB))
244
+ if (fd != -1 )
256
245
{
257
- // Exclusive => shared
258
- flock (fd, LOCK_SH | LOCK_NB);
259
- *was_lock_released = true ;
260
- return fd;
246
+ *was_lock_created = false ;
261
247
}
262
248
else
263
249
{
264
- *was_lock_released = false ;
250
+ *was_lock_created = true ;
251
+ fd = open (file_path.c_str (), O_CREAT | O_RDONLY, 0666 );
265
252
}
266
- }
267
253
268
- // Lock shared
269
- if (0 != flock (fd, LOCK_SH | LOCK_NB))
270
- {
271
- close (fd);
272
- throw std::runtime_error ((" failed to lock " + file_path).c_str ());
273
- }
254
+ if (was_lock_released != nullptr )
255
+ {
256
+ // Lock exclusive
257
+ if (0 == flock (fd, LOCK_EX | LOCK_NB))
258
+ {
259
+ // Check if file was deleted by clean up script between open and lock
260
+ // if yes, repeat file creation
261
+ struct stat buffer = {};
262
+ if (stat (file_path.c_str (), &buffer) != 0 && errno == ENOENT)
263
+ {
264
+ close (fd);
265
+ fd = -1 ;
266
+ continue ;
267
+ }
268
+
269
+ // Exclusive => shared
270
+ flock (fd, LOCK_SH | LOCK_NB);
271
+ *was_lock_released = true ;
272
+ return fd;
273
+ }
274
+ else
275
+ {
276
+ *was_lock_released = false ;
277
+ }
278
+ }
279
+
280
+ // Lock shared
281
+ if (0 != flock (fd, LOCK_SH | LOCK_NB))
282
+ {
283
+ close (fd);
284
+ throw std::runtime_error ((" failed to lock " + file_path).c_str ());
285
+ }
286
+ } while (fd == -1 );
274
287
275
288
return fd;
276
289
}
0 commit comments