]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/configuration/sgconfig/stgconfig.cpp
More jthreads.
[stg.git] / projects / stargazer / plugins / configuration / sgconfig / stgconfig.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21 #include "stgconfig.h"
22
23 #include "stg/common.h"
24
25 #include <algorithm>
26 #include <csignal>
27 #include <cstring>
28 #include <cerrno>
29
30 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
33 bool STG_CONFIG_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
34 {
35     STG::ParamValue pv;
36     std::vector<STG::ParamValue>::const_iterator pvi;
37     ///////////////////////////
38     pv.param = "Port";
39     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
40     if (pvi == s.moduleParams.end() || pvi->value.empty())
41         {
42         errorStr = "Parameter \'Port\' is not found.";
43         printfd(__FILE__, "%s\n", errorStr.c_str());
44         return false;
45         }
46     int p;
47     if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
48         {
49         errorStr = "Parameter \'Port\' should be an integral value in range (2, 65535). Actual value: '" + pvi->value[0] + "'.";
50         printfd(__FILE__, "%s\n", errorStr.c_str());
51         return false;
52         }
53     m_port = static_cast<uint16_t>(p);
54
55     pv.param = "BindAddress";
56     pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
57     if (pvi != s.moduleParams.end() && !pvi->value.empty())
58         m_bindAddress = pvi->value[0];
59
60     return true;
61 }
62 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
64 //-----------------------------------------------------------------------------
65 extern "C" STG::Plugin * GetPlugin()
66 {
67     static STG_CONFIG plugin;
68     return &plugin;
69 }
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
73 STG_CONFIG::STG_CONFIG()
74     : nonstop(false),
75       isRunning(false),
76       logger(STG::PluginLogger::get("conf_sg")),
77       config(logger)
78 {
79 }
80 //-----------------------------------------------------------------------------
81 int STG_CONFIG::ParseSettings()
82 {
83     if (stgConfigSettings.ParseSettings(settings))
84         return 0;
85     errorStr = stgConfigSettings.GetStrError();
86     return -1;
87 }
88 //-----------------------------------------------------------------------------
89 int STG_CONFIG::Start()
90 {
91     if (isRunning)
92         return 0;
93
94     nonstop = true;
95
96     config.SetPort(stgConfigSettings.GetPort());
97     config.SetBindAddress(stgConfigSettings.GetBindAddress());
98
99     if (config.Prepare())
100     {
101         errorStr = config.GetStrError();
102         return -1;
103     }
104
105     m_thread = std::jthread([this](auto token){ Run(token); });
106
107     return 0;
108 }
109 //-----------------------------------------------------------------------------
110 int STG_CONFIG::Stop()
111 {
112     if (!isRunning)
113         return 0;
114
115     config.Stop();
116     m_thread.request_stop();
117
118     //5 seconds to thread stops itself
119     for (size_t i = 0; i < 25; ++i)
120     {
121         if (!isRunning)
122             break;
123
124         struct timespec ts = {0, 200000000};
125         nanosleep(&ts, NULL);
126     }
127
128     if (isRunning)
129         m_thread.detach();
130     else
131         m_thread.join();
132
133     return 0;
134 }
135 //-----------------------------------------------------------------------------
136 void STG_CONFIG::Run(std::stop_token token)
137 {
138     sigset_t signalSet;
139     sigfillset(&signalSet);
140     pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
141
142     isRunning = true;
143
144     config.Run(token);
145
146     isRunning = false;
147 }