2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
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.
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.
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/>.
17 #include "scripting/thread_queue.hpp"
19 #include "scripting/scripting.hpp"
20 #include "scripting/squirrel_util.hpp"
21 #include "util/log.hpp"
26 ThreadQueue::ThreadQueue() :
31 ThreadQueue::~ThreadQueue()
36 ThreadQueue::add(HSQUIRRELVM vm)
38 // create a weakref to the VM
39 HSQOBJECT vm_obj = vm_to_object(vm);
40 sq_pushobject(global_vm, vm_obj);
41 sq_weakref(global_vm, -1);
44 if(SQ_FAILED(sq_getstackobj(global_vm, -1, &object))) {
46 throw SquirrelError(global_vm, "Couldn't get thread weakref from vm");
48 sq_addref(global_vm, &object);
49 threads.push_back(object);
57 // we traverse the list in reverse orders and use indices. This should be
58 // robust for scripts that add new entries to the list while we're traversing
60 size_t i = threads.size() - 1;
61 size_t end = (size_t) 0 - 1;
62 size_t size_begin = threads.size();
64 HSQOBJECT object = threads[i];
66 sq_pushobject(global_vm, object);
67 sq_getweakrefval(global_vm, -1);
69 HSQUIRRELVM scheduled_vm;
70 if(sq_gettype(global_vm, -1) == OT_THREAD &&
71 SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
72 if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
73 log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
77 sq_release(global_vm, &object);
82 threads.erase(threads.begin(), threads.begin() + size_begin);