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
|
#include "cron.h"
#include <util/system/thread.h>
#include <util/system/event.h>
#include <atomic>
#include <utility>
using namespace NCron;
namespace {
struct TPeriodicHandle: IHandle {
TPeriodicHandle(TJob job, const TDuration interval, const TString& threadName)
: Job(std::move(job))
, Interval(interval)
, Done(false)
{
TThread::TParams params(DoRun, this);
if (!threadName.empty()) {
params.SetName(threadName);
}
Thread = MakeHolder<TThread>(params);
Thread->Start();
}
static void* DoRun(void* data) noexcept {
static_cast<TPeriodicHandle*>(data)->Run();
return nullptr;
}
void Run() noexcept {
while (true) {
Job();
Event.WaitT(Interval);
if (Done.load()) {
return;
}
}
}
~TPeriodicHandle() override {
Done.store(true);
Event.Signal();
Thread->Join();
}
TJob Job;
TDuration Interval;
TManualEvent Event;
std::atomic<bool> Done;
THolder<TThread> Thread;
};
}
IHandlePtr NCron::StartPeriodicJob(TJob job) {
return NCron::StartPeriodicJob(std::move(job), TDuration::Seconds(0), TString());
}
IHandlePtr NCron::StartPeriodicJob(TJob job, const TDuration interval) {
return NCron::StartPeriodicJob(std::move(job), interval, TString());
}
IHandlePtr NCron::StartPeriodicJob(TJob job, TDuration interval, const TString& threadName) {
return new TPeriodicHandle(std::move(job), interval, threadName);
}
IHandle::~IHandle() = default;
|