1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "squirrel/squirrel_thread_queue.hpp"
18
19#include "squirrel/squirrel_virtual_machine.hpp"
20#include "squirrel/squirrel_util.hpp"
21#include "util/log.hpp"
22
23SquirrelThreadQueue::SquirrelThreadQueue(SquirrelVM& vm) :
24 m_vm(vm),
25 m_threads()
26{
27}
28
29void
30SquirrelThreadQueue::add(HSQUIRRELVM vm)
31{
32 // create a weakref to the VM
33 sq_pushthread(m_vm.get_vm(), vm);
34 sq_weakref(m_vm.get_vm(), -1);
35
36 HSQOBJECT object;
37 if (SQ_FAILED(sq_getstackobj(m_vm.get_vm(), -1, &object))) {
38 sq_pop(m_vm.get_vm(), 2);
39 throw SquirrelError(m_vm.get_vm(), "Couldn't get thread weakref from vm");
40 }
41 sq_addref(m_vm.get_vm(), &object);
42 m_threads.push_back(object);
43
44 sq_pop(m_vm.get_vm(), 2);
45}
46
47void
48SquirrelThreadQueue::wakeup()
49{
50 std::vector<HSQOBJECT> threads = std::move(m_threads);
51 m_threads.clear();
52
53 for (HSQOBJECT object : threads)
54 {
55 sq_pushobject(m_vm.get_vm(), object);
56 sq_getweakrefval(m_vm.get_vm(), -1);
57
58 HSQUIRRELVM scheduled_vm;
59 if (sq_gettype(m_vm.get_vm(), -1) == OT_THREAD &&
60 SQ_SUCCEEDED(sq_getthread(m_vm.get_vm(), -1, &scheduled_vm)))
61 {
62 if (SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
63 log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
64 }
65 }
66
67 sq_release(m_vm.get_vm(), &object);
68 sq_pop(m_vm.get_vm(), 1);
69 }
70}
71
72/* EOF */
73