prosody

changeset 992
3153eff6dae2
parent 978
a9898f54b402
child 1006
4bd375bde3cb
equal deleted inserted replaced
991:cd0d75de8345 992:3153eff6dae2
85 require "core.sessionmanager" 85 require "core.sessionmanager"
86 require "core.stanza_router" 86 require "core.stanza_router"
87 87
88 require "util.array" 88 require "util.array"
89 require "util.iterators" 89 require "util.iterators"
90 require "util.timer"
90 91
91 -- Commented to protect us from 92 -- Commented to protect us from
92 -- the second kind of people 93 -- the second kind of people
93 --[[ 94 --[[
94 pcall(require, "remdebug.engine"); 95 pcall(require, "remdebug.engine");
154 else 155 else
155 log("error", "Console is enabled, but the console module appears not to be loaded"); 156 log("error", "Console is enabled, but the console module appears not to be loaded");
156 end 157 end
157 end 158 end
158 159
159 -- setup error handling 160 -- Global function to initiate prosody shutdown
161 function prosody_shutdown(reason)
162 log("info", "Shutting down: %s", reason or "unknown reason");
163 server.setquitting(true);
164 end
165
166 -- Catch global accesses --
160 local locked_globals_mt = { __index = function (t, k) error("Attempt to read a non-existent global '"..k.."'", 2); end, __newindex = function (t, k, v) error("Attempt to set a global: "..tostring(k).." = "..tostring(v), 2); end } 167 local locked_globals_mt = { __index = function (t, k) error("Attempt to read a non-existent global '"..k.."'", 2); end, __newindex = function (t, k, v) error("Attempt to set a global: "..tostring(k).." = "..tostring(v), 2); end }
161 168
162 function unlock_globals() 169 function unlock_globals()
163 setmetatable(_G, nil); 170 setmetatable(_G, nil);
164 end 171 end
165 172
166 function lock_globals() 173 function lock_globals()
167 setmetatable(_G, locked_globals_mt); 174 setmetatable(_G, locked_globals_mt);
168 end 175 end
169 176
177 -- And lock now...
170 lock_globals(); 178 lock_globals();
171 179
172 eventmanager.fire_event("server-started"); 180 eventmanager.fire_event("server-started");
173 181
174 local quitting; 182 -- Error handler for errors that make it this far
175 while not quitting do 183 local function catch_uncaught_error(err)
176 xpcall(server.loop, function (err) 184 if err:match("%d*: interrupted!$") then
177 if err:match("%d*: interrupted!$") then 185 return "quitting";
178 quitting = true; 186 end
179 return; 187
180 end 188 log("error", "Top-level error, please report:\n%s", tostring(err));
181 189 local traceback = debug.traceback("", 2);
182 log("error", "Top-level error, please report:\n%s", tostring(err)); 190 if traceback then
183 191 log("error", "%s", traceback);
184 local traceback = debug.traceback("", 2); 192 end
185 if traceback then 193
186 log("error", "%s", traceback); 194 eventmanager.fire_event("very-bad-error", "*", err, traceback);
187 end 195 end
188 196
189 eventmanager.fire_event("very-bad-error", "*", err, traceback); 197 while select(2, xpcall(server.loop, catch_uncaught_error)) ~= "quitting" do
190 end); 198 socket.sleep(0.2);
191 end 199 end
200
201 -- Ok, we're quitting I know, but we
202 -- need to do some tidying before we go :)
203 server.setquitting(false);
204
205 for hostname, host in pairs(hosts) do
206 if host.sessions then
207 for username, user in pairs(host.sessions) do
208 for resource, session in pairs(user.sessions) do
209 log("debug", "Closing connection for %s@%s/%s", username, hostname, resource);
210 session:close("system-shutdown");
211 end
212 end
213 end
214
215 if host.s2sout then
216 for remotehost, session in pairs(host.s2sout) do
217 if session.close then
218 session:close("system-shutdown");
219 else
220 log("warn", "Unable to close outgoing s2s session to %s, no session:close()?!", remotehost);
221 end
222 end
223 end
224 end
225
226 server.closeall();

mercurial