aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/cron/cron.cpp
blob: e7c1c59735b705d5cb632c3ddfdf618c70a08958 (plain) (blame)
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
#include "cron.h"

#include <library/cpp/deprecated/atomic/atomic.h>

#include <util/system/thread.h>
#include <util/system/event.h>

using namespace NCron;

namespace {
    struct TPeriodicHandle: public IHandle {
        inline TPeriodicHandle(TJob job, TDuration interval, const TString& threadName)
            : Job(job)
            , Interval(interval)
            , Done(false)
        {
            TThread::TParams params(DoRun, this);
            if (!threadName.empty()) {
                params.SetName(threadName);
            }
            Thread = MakeHolder<TThread>(params);
            Thread->Start();
        }

        static inline void* DoRun(void* data) noexcept {
            ((TPeriodicHandle*)data)->Run();

            return nullptr;
        }

        inline void Run() noexcept {
            while (true) {
                Job();

                Event.WaitT(Interval);

                if (AtomicGet(Done)) {
                    return;
                }
            }
        }

        ~TPeriodicHandle() override {
            AtomicSet(Done, true);
            Event.Signal();
            Thread->Join();
        }

        TJob Job;
        TDuration Interval;
        TManualEvent Event;
        TAtomic Done;
        THolder<TThread> Thread;
    };
}

IHandlePtr NCron::StartPeriodicJob(TJob job) {
    return NCron::StartPeriodicJob(job, TDuration::Seconds(0), "");
}

IHandlePtr NCron::StartPeriodicJob(TJob job, TDuration interval) {
    return NCron::StartPeriodicJob(job, interval, "");
}

IHandlePtr NCron::StartPeriodicJob(TJob job, TDuration interval, const TString& threadName) {
    return new TPeriodicHandle(job, interval, threadName);
}

IHandle::~IHandle() = default;