21
21
*/
22
22
23
23
#pragma once
24
+
24
25
#include " ext/luawrapper/include/LuaContext.hpp"
25
26
#include " misc.hh"
26
27
#include < mutex>
@@ -41,7 +42,7 @@ typedef std::function<std::string(const std::string&)> canonicalize_t;
41
42
42
43
struct CustomFuncMapObject {
43
44
custom_func_t c_func;
44
- bool c_reportSink;
45
+ bool c_reportSink;
45
46
};
46
47
47
48
typedef std::map<std::string, CustomFuncMapObject> CustomFuncMap;
@@ -50,7 +51,10 @@ extern CustomFuncMap g_custom_func_map;
50
51
typedef std::map<std::string, custom_get_func_t > CustomGetFuncMap;
51
52
extern CustomGetFuncMap g_custom_get_func_map;
52
53
53
- vector<std::function<void (void )>> setupLua (bool client, bool allow_report, LuaContext& c_lua, allow_t & allow_func, report_t & report_func, reset_t & reset_func, canonicalize_t & canon_func, CustomFuncMap& custom_func_map, CustomGetFuncMap& custom_get_func_map, const std::string& config);
54
+ vector<std::function<void (void )>>
55
+ setupLua (bool client, bool allow_report, LuaContext& c_lua, allow_t & allow_func, report_t & report_func,
56
+ reset_t & reset_func, canonicalize_t & canon_func, CustomFuncMap& custom_func_map,
57
+ CustomGetFuncMap& custom_get_func_map, const std::string& config);
54
58
55
59
struct LuaThreadContext {
56
60
LuaContext lua_context;
@@ -65,101 +69,132 @@ struct LuaThreadContext {
65
69
66
70
#define NUM_LUA_STATES 6
67
71
68
- class LuaMultiThread
69
- {
72
+ class LuaMultiThread {
70
73
public:
71
- LuaMultiThread () : num_states(NUM_LUA_STATES),
72
- state_index ( 0 )
74
+
75
+ LuaMultiThread () : num_states(NUM_LUA_STATES )
73
76
{
74
77
LuaMultiThread{num_states};
75
78
}
76
79
77
- LuaMultiThread (unsigned int nstates) : num_states(nstates),
78
- state_index(0 )
80
+ LuaMultiThread (unsigned int nstates) : num_states(nstates)
79
81
{
80
- for (unsigned int i=0 ; i<num_states; i++) {
81
- lua_cv.push_back (std::make_shared<LuaThreadContext>());
82
- }
82
+ for (unsigned int i = 0 ; i < num_states; i++) {
83
+ lua_pool.push_back (std::make_shared<LuaThreadContext>());
84
+ }
85
+ lua_read_only = lua_pool; // Make a copy for use by the control thread
83
86
}
84
87
85
88
LuaMultiThread (const LuaMultiThread&) = delete ;
89
+
86
90
LuaMultiThread& operator =(const LuaMultiThread&) = delete ;
87
91
88
92
// these are used to setup the allow and report function pointers
89
- std::vector<std::shared_ptr<LuaThreadContext>>::iterator begin () { return lua_cv.begin (); }
90
- std::vector<std::shared_ptr<LuaThreadContext>>::iterator end () { return lua_cv.end (); }
93
+ std::vector<std::shared_ptr<LuaThreadContext>>::iterator begin ()
94
+ { return lua_read_only.begin (); }
95
+
96
+ std::vector<std::shared_ptr<LuaThreadContext>>::iterator end ()
97
+ { return lua_read_only.end (); }
91
98
92
- bool reset (const std::string& type, const std::string& login_value, const ComboAddress& ca_value) {
93
- auto lt_context = getLuaState ();
99
+ bool reset (const std::string& type, const std::string& login_value, const ComboAddress& ca_value)
100
+ {
101
+ auto pool_member = getPoolMember ();
102
+ auto lt_context = pool_member.getLuaContext ();
94
103
// lock the lua state mutex
95
104
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
96
105
// call the reset function
97
106
return lt_context->reset_func (type, login_value, ca_value);
98
107
}
99
108
100
- AllowReturn allow (const LoginTuple& lt) {
101
- auto lt_context = getLuaState ();
109
+ AllowReturn allow (const LoginTuple& lt)
110
+ {
111
+ auto pool_member = getPoolMember ();
112
+ auto lt_context = pool_member.getLuaContext ();
102
113
// lock the lua state mutex
103
114
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
104
115
// call the allow function
105
116
return lt_context->allow_func (lt);
106
117
}
107
118
108
- void report (const LoginTuple& lt) {
109
- auto lt_context = getLuaState ();
119
+ void report (const LoginTuple& lt)
120
+ {
121
+ auto pool_member = getPoolMember ();
122
+ auto lt_context = pool_member.getLuaContext ();
110
123
// lock the lua state mutex
111
124
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
112
125
// call the report function
113
126
lt_context->report_func (lt);
114
127
}
115
128
116
- std::string canonicalize (const std::string& login) {
117
- auto lt_context = getLuaState ();
129
+ std::string canonicalize (const std::string& login)
130
+ {
131
+ auto pool_member = getPoolMember ();
132
+ auto lt_context = pool_member.getLuaContext ();
118
133
// lock the lua state mutex
119
134
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
120
135
// call the canonicalize function
121
136
return lt_context->canon_func (login);
122
137
}
123
138
124
- CustomFuncReturn custom_func (const std::string& command, const CustomFuncArgs& cfa, bool & reportSinkReturn) {
125
- auto lt_context = getLuaState ();
139
+ CustomFuncReturn custom_func (const std::string& command, const CustomFuncArgs& cfa, bool & reportSinkReturn)
140
+ {
141
+ auto pool_member = getPoolMember ();
142
+ auto lt_context = pool_member.getLuaContext ();
126
143
// lock the lua state mutex
127
144
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
128
145
// call the custom function
129
- for (const auto & i : lt_context->custom_func_map ) {
146
+ for (const auto & i: lt_context->custom_func_map ) {
130
147
if (command.compare (i.first ) == 0 ) {
131
- reportSinkReturn = i.second .c_reportSink ;
132
- return i.second .c_func (cfa);
148
+ reportSinkReturn = i.second .c_reportSink ;
149
+ return i.second .c_func (cfa);
133
150
}
134
151
}
135
152
return CustomFuncReturn (false , KeyValVector{});
136
153
}
137
154
138
- std::string custom_get_func (const std::string& command) {
139
- auto lt_context = getLuaState ();
155
+ std::string custom_get_func (const std::string& command)
156
+ {
157
+ auto pool_member = getPoolMember ();
158
+ auto lt_context = pool_member.getLuaContext ();
140
159
// lock the lua state mutex
141
160
std::lock_guard<std::mutex> lock (lt_context->lua_mutex );
142
161
// call the custom function
143
- for (const auto & i : lt_context->custom_get_func_map ) {
162
+ for (const auto & i: lt_context->custom_get_func_map ) {
144
163
if (command.compare (i.first ) == 0 ) {
145
- return i.second ();
164
+ return i.second ();
146
165
}
147
166
}
148
167
return string ();
149
168
}
150
-
169
+
151
170
protected:
152
- std::shared_ptr<LuaThreadContext> getLuaState ()
153
- {
171
+
172
+ class SharedPoolMember {
173
+ public:
174
+ SharedPoolMember (std::shared_ptr<LuaThreadContext> ptr, LuaMultiThread* pool) : d_pool_item(ptr), d_pool(pool) {}
175
+ ~SharedPoolMember () { if (d_pool != nullptr ) { d_pool->returnPoolMember (d_pool_item); } }
176
+ SharedPoolMember (const SharedPoolMember&) = delete ;
177
+ SharedPoolMember& operator =(const SharedPoolMember&) = delete ;
178
+ std::shared_ptr<LuaThreadContext> getLuaContext () { return d_pool_item; }
179
+ private:
180
+ std::shared_ptr<LuaThreadContext> d_pool_item;
181
+ LuaMultiThread* d_pool;
182
+ };
183
+ SharedPoolMember getPoolMember () {
184
+ std::lock_guard<std::mutex> lock (mutx);
185
+ auto member = lua_pool.back ();
186
+ lua_pool.pop_back ();
187
+ return SharedPoolMember (member, this );
188
+ }
189
+ void returnPoolMember (std::shared_ptr<LuaThreadContext> my_ptr) {
154
190
std::lock_guard<std::mutex> lock (mutx);
155
- if (state_index >= num_states)
156
- state_index = 0 ;
157
- return lua_cv[state_index++];
191
+ lua_pool.push_back (my_ptr);
158
192
}
193
+
159
194
private:
160
- std::vector<std::shared_ptr<LuaThreadContext>> lua_cv;
195
+ std::vector<std::shared_ptr<LuaThreadContext>> lua_pool;
196
+ std::vector<std::shared_ptr<LuaThreadContext>> lua_read_only;
161
197
unsigned int num_states;
162
- unsigned int state_index;
163
198
std::mutex mutx;
164
199
};
165
200
0 commit comments