17 #ifndef LIB_WINSS_SVSCAN_SVSCAN_HPP_ 18 #define LIB_WINSS_SVSCAN_SVSCAN_HPP_ 26 #include "easylogging/easylogging++.hpp" 27 #include "../windows_interface.hpp" 28 #include "../environment.hpp" 29 #include "../filesystem_interface.hpp" 30 #include "../not_owning_ptr.hpp" 31 #include "../wait_multiplexer.hpp" 32 #include "../path_mutex.hpp" 33 #include "../process.hpp" 34 #include "../utils.hpp" 35 #include "../handle_wrapper.hpp" 36 #include "../event_wrapper.hpp" 37 #include "../ctrl_handler.hpp" 40 namespace fs = std::experimental::filesystem;
53 template<
typename TService,
typename TMutex,
typename TProcess>
72 if (mutex.HasLock()) {
80 <<
"' does not exist.";
102 auto env = env_dir.ReadEnvSource();
104 for (
const auto& kv : env) {
105 if (kv.second.empty()) {
106 WINDOWS.SetEnvironmentVariable(
107 const_cast<char *>(kv.first.data()),
110 WINDOWS.SetEnvironmentVariable(
111 const_cast<char *>(kv.first.data()),
112 const_cast<char *>(kv.second.data()));
126 void Check(
const fs::path& service_dir) {
127 std::string name = service_dir.filename().string();
130 if (name.empty() || name.front() == L
'.') {
131 VLOG(4) <<
"Skipping directory " << name;
135 auto pred = [name](
const TService& service) {
136 return service.GetName() == name;
139 auto it = find_if(services.begin(), services.end(), pred);
140 if (it == services.end()) {
141 TService service(name);
142 VLOG(2) <<
"Found new service " << name;
144 services.push_back(std::move(service));
146 VLOG(3) <<
"Found existing service " << name;
155 if (rescan > 0 && rescan != INFINITE) {
172 multiplexer->
Stop(0);
177 VLOG(5) <<
"Close event reset";
184 fs::path svscan_dir = scan_dir / fs::path(
kSvscanDir);
185 fs::path sigterm_file = svscan_dir / fs::path(
kSigTermFile);
187 std::string cmd =
FILESYSTEM.Read(sigterm_file);
189 VLOG(2) <<
"Starting SIGTERM process";
191 std::string expanded =
202 LOG(WARNING) <<
"Unable to spawn .winss-svscan/SIGTERM";
219 fs::path svscan_dir = scan_dir / fs::path(
kSvscanDir);
220 fs::path finish_file = svscan_dir / fs::path(
kFinishFile);
222 std::string cmd =
FILESYSTEM.Read(finish_file);
224 VLOG(2) <<
"Starting finish process";
226 std::string expanded =
229 auto finish = std::make_shared<TProcess>();
237 <<
"Finished process exited with " 238 << finish->GetExitCode();
241 LOG(WARNING) <<
"Unable to spawn .winss-svscan/finish";
253 static constexpr
const char kSvscanDir[14] =
".winss-svscan";
258 static constexpr
const char kEnvDir[18] =
".winss-svscan\\env";
270 const fs::path& scan_dir, DWORD rescan,
bool signals,
272 scan_dir(scan_dir), rescan(rescan), mutex(scan_dir, kMutexName),
273 signals(signals), close_event(close_event) {
296 virtual void Scan(
bool timeout) {
297 if (!mutex.HasLock() ||
exiting) {
305 VLOG(2) <<
"Scanning directory " <<
scan_dir;
307 for (TService& service : services) {
311 for (
auto dir :
FILESYSTEM.GetDirectories(scan_dir)) {
324 if (!mutex.HasLock()) {
328 VLOG(3) <<
"Closing all services (forced: " << ignore_flagged <<
")";
330 auto it = services.begin();
331 while (it != services.end()) {
332 bool flagged = it->Close(ignore_flagged);
334 VLOG(2) <<
"Removing service " << it->GetName();
335 it = services.erase(it);
348 virtual void Exit(
bool close_services) {
349 close_on_exit = close_services;
350 multiplexer->
Stop(0);
363 #endif // LIB_WINSS_SVSCAN_SVSCAN_HPP_ The svscan template.
Definition: svscan.hpp:54
A wrapper for a Windows HANDLE.
Definition: handle_wrapper.hpp:39
Parameters to start a Windows process.
Definition: process.hpp:29
A directory where each file is an environment variable.
Definition: environment.hpp:58
fs::path scan_dir
The scan directory.
Definition: svscan.hpp:58
virtual void CloseAllServices(bool ignore_flagged)
Closes all the services.
Definition: svscan.hpp:323
#define WINDOWS
Definition: windows_interface.hpp:25
Wraps a windows event.
Definition: event_wrapper.hpp:27
SvScanTmpl< winss::Service, winss::PathMutex, winss::Process > SvScan
Concrete svscan implementation.
Definition: svscan.hpp:360
static constexpr const char kEnvDir[18]
Env directory.
Definition: svscan.hpp:258
static constexpr const char kFinishFile[7]
Finish file.
Definition: svscan.hpp:254
bool exiting
Exiting flag.
Definition: svscan.hpp:61
void Terminate()
Handles a signal to terminate.
Definition: svscan.hpp:166
TMutex mutex
The svscan global mutex.
Definition: svscan.hpp:60
virtual void AddStopCallback(Callback callback)
Add a stop callback.
Definition: wait_multiplexer.cpp:60
Definition: case_ignore.hpp:23
void Check(const fs::path &service_dir)
Checks the given service directory.
Definition: svscan.hpp:126
virtual void AddTimeoutCallback(DWORD timeout, Callback callback, std::string group="")
Add a timeout item which given the timeout period will call the callback if it is not removed before ...
Definition: wait_multiplexer.cpp:50
virtual void AddTriggeredCallback(const winss::HandleWrapper &handle, TriggeredCallback callback)
Add a triggered callback for when an event happens on the given handle.
Definition: wait_multiplexer.cpp:43
winss::EventWrapper close_event
Event when to stop.
Definition: svscan.hpp:64
static void ReadEnv()
Reads the env directory into the current environment.
Definition: svscan.hpp:100
bool Reset()
Resets the event.
Definition: event_wrapper.cpp:32
static const int kFatalExitCode
Something went wrong.
Definition: svscan.hpp:248
winss::HandleWrapper GetHandle() const
Gets a handle to the event.
Definition: event_wrapper.cpp:36
void Schedule()
Schedules the next scan of the scan directory.
Definition: svscan.hpp:154
static const int kMutexTaken
Scan dir in use error.
Definition: svscan.hpp:247
static constexpr const char kMutexName[7]
Mutex name.
Definition: svscan.hpp:249
static constexpr const char kTimeoutGroup[7]
The timeout group for the multiplexer.
Definition: svscan.hpp:251
void Stop()
Stops the svscan instance.
Definition: svscan.hpp:208
A HANDLE wait multiplexer.
Definition: wait_multiplexer.hpp:70
virtual void Stop(int code)
Stops the multiplexer with the given code if one has not already been set.
Definition: wait_multiplexer.cpp:189
void Init()
Initializes svscan.
Definition: svscan.hpp:71
virtual void AddInitCallback(Callback callback)
Add an initialization callback.
Definition: wait_multiplexer.cpp:37
static constexpr const char kSvscanDir[14]
The directory for svscan data.
Definition: svscan.hpp:253
SvScanTmpl & operator=(const SvScanTmpl &)=delete
No copy.
bool signals
Use handlers for signals.
Definition: svscan.hpp:63
bool close_on_exit
Option to close services on exit.
Definition: svscan.hpp:62
#define FILESYSTEM
Definition: filesystem_interface.hpp:26
const DWORD rescan
The directory scan period.
Definition: svscan.hpp:59
winss::NotOwningPtr< winss::WaitMultiplexer > multiplexer
The event multiplexer for svscan.
Definition: svscan.hpp:57
virtual void Exit(bool close_services)
Signals the scanner to exit.
Definition: svscan.hpp:348
virtual void Scan(bool timeout)
Does a scan of the scan directory.
Definition: svscan.hpp:296
virtual bool RemoveTriggeredCallback(const winss::HandleWrapper &handle)
Removes the triggered callback which matches the given handle.
Definition: wait_multiplexer.cpp:66
virtual bool RemoveTimeoutCallback(std::string group)
Removes the timeout call back for the given group.
Definition: wait_multiplexer.cpp:77
SvScanTmpl(winss::NotOwningPtr< winss::WaitMultiplexer > multiplexer, const fs::path &scan_dir, DWORD rescan, bool signals, winss::EventWrapper close_event)
SvScan constructor.
Definition: svscan.hpp:269
std::vector< TService > services
A list of services.
Definition: svscan.hpp:66
static constexpr const char kSigTermFile[8]
SIGTERM file.
Definition: svscan.hpp:256
static std::string ExpandEnvironmentVariables(const std::string &value)
Expand the given string with environment variables.
Definition: utils.cpp:31