forked from dyninc/OpenBFDD
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SchedulerBase.h
executable file
·140 lines (115 loc) · 3.79 KB
/
SchedulerBase.h
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**************************************************************
* Copyright (c) 2010-2013, Dynamic Network Services, Inc.
* Jake Montgomery ([email protected]) & Tom Daly ([email protected])
* Distributed under the FreeBSD License - see LICENSE
***************************************************************/
/**
Base class for implementations of the Scheduler interface.
*/
#pragma once
#include "Scheduler.h"
#include "TimeSpec.h"
#include "hash_map.h"
#include <set>
struct timespec;
class TimerImpl;
class SchedulerBase : public Scheduler
{
public:
typedef std::multiset<TimerImpl *, bool (*)(const TimerImpl *, const TimerImpl *)> timer_set;
typedef timer_set::iterator timer_set_it;
public:
virtual ~SchedulerBase();
/** Scheduler interface impl */
virtual bool Run();
virtual bool IsMainThread();
virtual bool SetSocketCallback(int socket, Scheduler::SocketCallback callback, void *userdata);
virtual void RemoveSocketCallback(int socket);
virtual bool CreateSignalChannel(int *outSigId, SignalCallback callback, void *userdata);
virtual bool Signal(int sigId);
virtual void RemoveSignalChannel(int sigId);
virtual void RequestShutdown();
virtual Timer* MakeTimer(const char *name);
virtual void FreeTimer(Timer *timer);
/** Other public functions */
static timer_set_it TimeSetFindExact(timer_set &timerSet, TimerImpl *target);
protected:
/**
* Constructor
* The thread that calls this is considered the "main thread". See
* Scheduler::IsMainThread().
*/
SchedulerBase();
/**
*
* Called to add a socket or pipe to the list of watched events.
*
* @note Called only on main thread. See Scheduler::IsMainThread().
*
* @param fd
*
* @return bool - false on failure
*/
virtual bool watchSocket(int fd) = 0;
/**
*
* Called to remove a socket or pipe to the list of watched events.
*
* @note Called only on main thread. See Scheduler::IsMainThread().
*
* @param fd
*
*/
virtual void unWatchSocket(int fd) = 0;
/**
* Called to wait for events.
*
* Subsequent calls to getNextSocketEvent() are based on this call.
*
* @note Called only on main thread. See Scheduler::IsMainThread().
*
* @param timeout - The maximum time to wait.
*
* @return bool - True if there was an actual socket event.
*/
virtual bool waitForEvents(const struct timespec &timeout) = 0;
/**
* Iterate over socket events found in last call to waitForEvents. Each
* subsequent call should return the next socket event (in any order).
*
* @note Called only on main thread. See Scheduler::IsMainThread().
*
* @return int - The next socket that was found in waitForEvents. -1 if there
* are no more sockets.
*/
virtual int getNextSocketEvent() = 0;
private:
TimeSpec getNextTimerTimeout();
bool expireTimer(Timer::Priority::Value minPri);
static bool compareTimers(const TimerImpl *lhs, const TimerImpl *rhs);
pthread_t m_mainThread; // This is the thread under which Run was called.
//
// Only access these from the Main scheduler thread. See IsMainThread().
//
bool m_isStarted; // True if Run was called.
struct schedulerSignalItem
{
Scheduler::SignalCallback callback;
void *userdata;
int fdWrite; // write end of pipe (also the signalId)
int fdRead; // read end of pipe
};
typedef hash_map<int, schedulerSignalItem>::Type SignalItemHashMap;
struct schedulerSocketItem
{
Scheduler::SocketCallback callback;
void *userdata;
int socket;
};
typedef hash_map<int, schedulerSocketItem>::Type SocketItemHashMap;
SocketItemHashMap m_sockets;
SignalItemHashMap m_signals;
bool m_wantsShutdown;
timer_set m_activeTimers;
int m_timerCount; // only used for debugging
};