]>
Commit | Line | Data |
---|---|---|
12471842 PL |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
7b3865cd | 22 | #pragma once |
23 | #include <map> | |
24 | #include <time.h> | |
25 | #include <thread> | |
26 | ||
27 | /** | |
28 | General idea: many threads submit work to this class, but only one executes it. The work should therefore be entirely trivial. | |
7dd3c413 | 29 | The implementation is that submitter threads create an object that represents the work, and it gets sent over a pipe |
7b3865cd | 30 | to the worker thread. |
31 | ||
32 | The worker thread meanwhile listens on this pipe (non-blocking), with a delay set to the next object that needs to be executed. | |
33 | If meanwhile new work comes in, all objects who's time has come are executed, a new sleep time is calculated. | |
34 | */ | |
35 | ||
36 | ||
37 | /* ObjectPipe facilitates the type-safe passing of types over a pipe */ | |
38 | ||
39 | template<class T> | |
40 | class ObjectPipe | |
41 | { | |
42 | public: | |
43 | ObjectPipe(); | |
44 | ~ObjectPipe(); | |
45 | void write(T& t); | |
46 | bool read(T* t); // returns false on EOF | |
74519f6f | 47 | int readTimeout(T* t, double msec); //!< -1 is timeout, 0 is no data, 1 is data. msec<0 waits infinitely wrong. msec==0 = undefined |
7b3865cd | 48 | void close(); |
49 | private: | |
50 | int d_fds[2]; | |
51 | }; | |
52 | ||
53 | template<class T> | |
54 | class DelayPipe | |
55 | { | |
56 | public: | |
57 | DelayPipe(); | |
58 | ~DelayPipe(); | |
74519f6f | 59 | void submit(T& t, int msec); //!< don't try for more than 4294 msec |
7b3865cd | 60 | |
61 | private: | |
7b3865cd | 62 | void worker(); |
63 | struct Combo | |
64 | { | |
65 | T what; | |
66 | struct timespec when; | |
67 | }; | |
68 | ||
4081de56 | 69 | double tsdelta(const struct timespec& a, const struct timespec& b) // read as a-b |
70 | { | |
71 | return 1.0*(a.tv_sec-b.tv_sec)+1.0*(a.tv_nsec-b.tv_nsec)/1000000000.0; | |
72 | } | |
73 | ||
7b3865cd | 74 | ObjectPipe<Combo> d_pipe; |
75 | struct tscomp { | |
76 | bool operator()(const struct timespec& a, const struct timespec& b) const | |
77 | { | |
78 | return std::tie(a.tv_sec, a.tv_nsec) < std::tie(b.tv_sec, b.tv_nsec); | |
79 | } | |
80 | }; | |
81 | std::multimap<struct timespec, T, tscomp> d_work; | |
8f4a3c16 | 82 | void gettime(struct timespec* ts); |
2c8244ca | 83 | std::thread d_thread; |
7b3865cd | 84 | }; |
85 | ||
86 | #include "delaypipe.cc" |