1 /*
2    Copyright 2005-2010 Jakub Kruszona-Zawadzki, Gemius SA, 2013-2014 EditShare, 2013-2017 Skytechnology sp. z o.o..
3 
4    This file is part of LizardFS.
5 
6    LizardFS is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3.
9 
10    LizardFS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with LizardFS  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "common/platform.h"
22 
23 #include <inttypes.h>
24 #include <string>
25 #include <vector>
26 
27 #if defined(_WIN32)
28   #include "winsock2.h"
29 #else
30   #include <poll.h>
31 #endif
32 
33 
34 #define TIMEMODE_SKIP_LATE 0
35 #define TIMEMODE_RUN_LATE 1
36 
37 enum class ExitingStatus {
38 	kRunning = 0,
39 	kWantExit = 1,
40 	kCanExit = 2,
41 	kDoExit = 3
42 };
43 
44 extern ExitingStatus gExitingStatus;
45 extern bool gReloadRequested;
46 
47 void eventloop_destructregister (void (*fun)(void));
48 void eventloop_canexitregister (int (*fun)(void));
49 void eventloop_wantexitregister (void (*fun)(void));
50 void eventloop_reloadregister (void (*fun)(void));
51 void eventloop_pollregister (void (*desc)(std::vector<pollfd>&),void (*serve)(const std::vector<pollfd>&));
52 void eventloop_eachloopregister (void (*fun)(void));
53 
54 /*! \brief Register handler for recurring event.
55  *
56  * \param mode Event mode. Can be one of
57  *                TIMEMODE_SKIP_LATE - if the event engine is late then we skip to the next time
58  *                                     divisible by seconds.
59  *                TIMEMODE_RUN_LATE  - can be executed even if the event engine is late (so time
60  *                                     isn't divisible by seconds).
61  * \param seconds when event should be run (event is executed at time divisible by
62  *                value of seconds).
63  * \param offset  if greater than 0 then event is executed offset seconds after time divisible by
64  *                value of parameter seconds).
65  * \param fun address of function to execute.
66  * \return handle - handle to newly registered timed event.
67  */
68 void *eventloop_timeregister(int mode, uint64_t seconds, uint64_t offset, void (*fun)(void));
69 
70 /*! \brief Register handler for recurring event (millisecond precision).
71  *
72  * \param period  how often event should be run (in ms)
73  * \param fun address of function to execute.
74  * \return handle - handle to newly registered timed event.
75  */
76 void *eventloop_timeregister_ms(uint64_t period, void (*fun)(void));
77 
78 /*! \brief Make the next poll nonblocking
79  */
80 void eventloop_make_next_poll_nonblocking();
81 
82 /*! \brief Unregister previously registered timed event handler.
83  *
84  * \param handle - handle to currently registered timed event.
85  */
86 void eventloop_timeunregister (void* handle);
87 
88 /*! \brief Change previously registered timed event frequency and mode.
89  *
90  * \param handle  - handle to currently registered timed event.
91  * \param mode    - event mode
92  * \param seconds - event period
93  * \param offset  - event offset
94  * \return 0  - success
95  *         -1 - error occurred
96  */
97 int eventloop_timechange(void* handle, int mode, uint64_t seconds, uint64_t offset);
98 
99 /*! \brief Change previously registered timed event frequency and mode.
100  *
101  * \param handle  - handle to currently registered timed event.
102  * \param period - event period (in ms)
103  * \return 0  - success
104  *         -1 - error occurred
105  */
106 int eventloop_timechange_ms(void* handle, uint64_t period);
107 
108 /*! \brief Try to exit as if term signal was received.
109  *
110  * \return LIZARDFS_STATUS_OK if term sequence has been initialized
111  *         LIZARDFS_ERROR_NOTPOSSIBLE if it was already initialized.
112  */
113 uint8_t eventloop_want_to_terminate(void);
114 
115 /*! \brief Request reloading the configuration.
116  *
117  * Reload will be performed after the current loop, so this function returns
118  * before thereload actually happens.
119  */
120 void eventloop_want_to_reload(void);
121 
122 /*! \brief Run event loop. */
123 void eventloop_run();
124 
125 /*! \brief Release resources used by event loop. */
126 void eventloop_release_resources(void);
127 
128 /*! \brief Call function registered in function eventloop_destructregister. */
129 void eventloop_destruct();
130 
131 /*! \brief Returns event loop time. The time is updated before call to handler functions
132  * and doesn't change during handlers execution.
133  *
134  * \return time in milliseconds.
135  */
136 uint32_t eventloop_time(void);
137 
138 /*! \brief Returns event loop time. The time is updated before call to handler functions
139  * and doesn't change during handlers execution.
140  *
141  * \return time in microseconds.
142  */
143 uint64_t eventloop_utime(void);
144 
145 /*! \brief Set time returned by functions eventloop_time and eventloop_utime
146  * to current system time.
147  */
148 void eventloop_updatetime();
149