-
Notifications
You must be signed in to change notification settings - Fork 2
/
tasks.cpp
137 lines (118 loc) · 3.98 KB
/
tasks.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//You need also accept Additional conditions.
//Additional conditions:
//1. Software's author gives no guarantee and takes no responsibility for working and any possible uncommon effects or/and faults caused.
//2. Any individuals using, modyfing and sharing this software cannot remove any information like authorship, software's sources, properties of DevLand.exe file and information attached in programe icon i.e. software's title.
//
//Terms and conditions apply.
//////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include "tasks.h"
#include "outputmessage.h"
#include "game.h"
extern Game g_game;
#if defined __EXCEPTION_TRACER__
#include "exception.h"
#endif
bool Dispatcher::m_shutdown = false;
Dispatcher::Dispatcher()
{
OTSYS_THREAD_LOCKVARINIT(m_taskLock);
OTSYS_THREAD_SIGNALVARINIT(m_taskSignal);
OTSYS_CREATE_THREAD(Dispatcher::dispatcherThread, NULL);
}
OTSYS_THREAD_RETURN Dispatcher::dispatcherThread(void* p)
{
#if defined __EXCEPTION_TRACER__
ExceptionHandler dispatcherExceptionHandler;
dispatcherExceptionHandler.InstallHandler();
#endif
srand((unsigned int)OTSYS_TIME());
while(!Dispatcher::m_shutdown){
Task* task = NULL;
// check if there are tasks waiting
OTSYS_THREAD_LOCK(getDispatcher().m_taskLock, "")
if(getDispatcher().m_taskList.empty()){
//if the list is empty wait for signal
OTSYS_THREAD_WAITSIGNAL(getDispatcher().m_taskSignal, getDispatcher().m_taskLock);
}
if(!getDispatcher().m_taskList.empty() && !Dispatcher::m_shutdown){
// take the first task
task = getDispatcher().m_taskList.front();
getDispatcher().m_taskList.pop_front();
}
OTSYS_THREAD_UNLOCK(getDispatcher().m_taskLock, "");
// finally execute the task...
if(task){
OutputMessagePool::getInstance()->startExecutionFrame();
(*task)();
delete task;
OutputMessagePool::getInstance()->sendAll();
g_game.clearSpectatorCache();
}
}
#if defined __EXCEPTION_TRACER__
dispatcherExceptionHandler.RemoveHandler();
#endif
#if defined WIN32 || defined __WINDOWS__
//
#else
return 0;
#endif
}
void Dispatcher::addTask(Task* task)
{
OTSYS_THREAD_LOCK(m_taskLock, "");
bool do_signal = false;
if(!Dispatcher::m_shutdown){
do_signal = m_taskList.empty();
m_taskList.push_back(task);
}
#ifdef _DEBUG
else{
std::cout << "Error: [Dispatcher::addTask] Dispatcher thread is terminated." << std::endl;
}
#endif
OTSYS_THREAD_UNLOCK(m_taskLock, "");
// send a signal if the list was empty
if(do_signal){
OTSYS_THREAD_SIGNAL_SEND(m_taskSignal);
}
}
void Dispatcher::flush()
{
Task* task = NULL;
while(!m_taskList.empty()){
task = getDispatcher().m_taskList.front();
m_taskList.pop_front();
(*task)();
delete task;
OutputMessagePool::getInstance()->sendAll();
g_game.clearSpectatorCache();
}
}
void Dispatcher::stop()
{
OTSYS_THREAD_LOCK(m_taskLock, "");
flush();
m_shutdown = true;
OTSYS_THREAD_UNLOCK(m_taskLock, "");
}