-
Notifications
You must be signed in to change notification settings - Fork 0
/
alive.cpp
79 lines (67 loc) · 1.82 KB
/
alive.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
* Copyright (c) 2024 Jan Wilmans.
*/
#include "alive.h"
#include "fmt/core.h"
#include <string>
#include <string_view>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#include <chrono>
#include <filesystem>
#include <thread>
Alive::Alive(std::filesystem::path unique_filename, unexpected_termination_callback callback) :
m_name(unique_filename)
{
if (callback && std::filesystem::exists(m_name.c_str()))
{
callback();
}
m_fd = open(m_name.c_str(), O_RDWR | O_CREAT, 0666);
flock(m_fd, LOCK_EX); // lock the handle, automatically released when if the process ends for any reason.
}
Alive::~Alive()
{
// fails if it was never created, but thats fine, ignore it.
flock(m_fd, LOCK_UN);
close(m_fd);
unlink(m_name.c_str());
}
bool is_file_handled_locked(int fd)
{
// if we can not lock, that that means it is already locked.
return flock(fd, LOCK_EX | LOCK_NB) == -1;
}
bool is_alive(std::filesystem::path unique_filename)
{
int fd = open(unique_filename.c_str(), O_RDWR | O_CREAT, 0666);
if (fd == -1)
{
fmt::print(stderr, "could not find {}\n", unique_filename.string());
return false;
}
bool result = is_file_handled_locked(fd);
close(fd);
return result;
}
bool wait_for_alive(std::filesystem::path unique_filename, std::chrono::milliseconds timeout)
{
auto time_limit = std::chrono::steady_clock::now() + timeout;
while (std::chrono::steady_clock::now() < time_limit)
{
if (is_alive(unique_filename))
{
return true;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return false;
}
void wait_for_alive(std::filesystem::path unique_filename)
{
while (!is_alive(unique_filename))
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}