… | |
… | |
174 | sub to_json($) { |
174 | sub to_json($) { |
175 | $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs |
175 | $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs |
176 | JSON::Syck::Dump $_[0] |
176 | JSON::Syck::Dump $_[0] |
177 | } |
177 | } |
178 | |
178 | |
179 | # main coro must never ever "block" except in Event |
179 | =item cf::sync_job { BLOCK } |
180 | # sync_job ensures this by running the job in a coroutine |
180 | |
181 | # and waiting in Event while the server is otherwise frozen |
181 | The design of crossfire+ requires that the main coro ($Coro::main) is |
|
|
182 | always able to handle events or runnable, as crossfire+ is only partly |
|
|
183 | reentrant. Thus "blocking" it by e.g. waiting for I/O is not acceptable. |
|
|
184 | |
|
|
185 | If it must be done, put the blocking parts into C<sync_job>. This will run |
|
|
186 | the given BLOCK in another coroutine while waiting for the result. The |
|
|
187 | server will be frozen during this time, so the block should either finish |
|
|
188 | fast or be very important. |
|
|
189 | |
|
|
190 | =cut |
|
|
191 | |
182 | sub sync_job(&) { |
192 | sub sync_job(&) { |
183 | my ($job) = @_; |
193 | my ($job) = @_; |
184 | |
194 | |
185 | my $busy = 1; |
195 | my $busy = 1; |
186 | my @res; |
196 | my @res; |
187 | |
197 | |
|
|
198 | # TODO: use suspend/resume instead |
188 | local $FREEZE = 1; |
199 | local $FREEZE = 1; |
189 | |
200 | |
190 | my $coro = Coro::async { |
201 | my $coro = Coro::async { |
191 | @res = eval { $job->() }; |
202 | @res = eval { $job->() }; |
192 | warn $@ if $@; |
203 | warn $@ if $@; |
… | |
… | |
1271 | |
1282 | |
1272 | ############################################################################# |
1283 | ############################################################################# |
1273 | # initialisation |
1284 | # initialisation |
1274 | |
1285 | |
1275 | sub _perl_reload() { |
1286 | sub _perl_reload() { |
|
|
1287 | # can/must only be called in main |
|
|
1288 | if ($Coro::current != $Coro::main) { |
|
|
1289 | warn "can only reload from main coroutine\n"; |
|
|
1290 | return; |
|
|
1291 | } |
|
|
1292 | |
1276 | warn "reloading..."; |
1293 | warn "reloading..."; |
1277 | |
1294 | |
|
|
1295 | local $FREEZE = 1; |
|
|
1296 | cf::emergency_save; |
|
|
1297 | |
1278 | eval { |
1298 | eval { |
1279 | local $FREEZE = 1; |
1299 | # if anything goes wrong in here, we should simply crash as we already saved |
1280 | |
|
|
1281 | cf::emergency_save; |
|
|
1282 | |
1300 | |
1283 | # cancel all watchers |
1301 | # cancel all watchers |
1284 | for (Event::all_watchers) { |
1302 | for (Event::all_watchers) { |
1285 | $_->cancel if $_->data & WF_AUTOCANCEL; |
1303 | $_->cancel if $_->data & WF_AUTOCANCEL; |
1286 | } |
1304 | } |
… | |
… | |
1345 | |
1363 | |
1346 | # reattach attachments to objects |
1364 | # reattach attachments to objects |
1347 | warn "reattach"; |
1365 | warn "reattach"; |
1348 | _global_reattach; |
1366 | _global_reattach; |
1349 | }; |
1367 | }; |
1350 | warn $@ if $@; |
|
|
1351 | |
1368 | |
1352 | warn "reloaded"; |
1369 | if ($@) { |
|
|
1370 | warn $@; |
|
|
1371 | warn "error while reloading, exiting."; |
|
|
1372 | exit 1; |
|
|
1373 | } |
|
|
1374 | |
|
|
1375 | warn "reloaded successfully"; |
1353 | }; |
1376 | }; |
1354 | |
1377 | |
1355 | sub perl_reload() { |
1378 | sub perl_reload() { |
1356 | _perl_reload; |
1379 | _perl_reload; |
1357 | } |
1380 | } |