mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-20 01:12:36 +00:00
Added priority setting to eqstream to control cpu usage on thread more effectively
This commit is contained in:
parent
54a7f73e50
commit
82e247f77b
@ -50,6 +50,12 @@ struct EQStreamManagerInterfaceOptions
|
|||||||
EQ::EventLoop *loop;
|
EQ::EventLoop *loop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EQStreamPriority : int32_t {
|
||||||
|
High,
|
||||||
|
Normal,
|
||||||
|
Low
|
||||||
|
};
|
||||||
|
|
||||||
class EQStreamInterface;
|
class EQStreamInterface;
|
||||||
class EQStreamManagerInterface
|
class EQStreamManagerInterface
|
||||||
{
|
{
|
||||||
@ -62,6 +68,7 @@ public:
|
|||||||
|
|
||||||
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) = 0;
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) = 0;
|
||||||
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) = 0;
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) = 0;
|
||||||
|
virtual void SetPriority(EQStreamPriority priority) = 0;
|
||||||
protected:
|
protected:
|
||||||
EQStreamManagerInterfaceOptions m_options;
|
EQStreamManagerInterfaceOptions m_options;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -21,6 +21,7 @@ namespace EQ
|
|||||||
|
|
||||||
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) { m_on_new_connection = func; }
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) { m_on_new_connection = func; }
|
||||||
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||||
|
virtual void SetPriority(EQStreamPriority priority) { }
|
||||||
private:
|
private:
|
||||||
DaybreakConnectionManager m_daybreak;
|
DaybreakConnectionManager m_daybreak;
|
||||||
std::function<void(std::shared_ptr<EQStreamInterface>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<EQStreamInterface>)> m_on_new_connection;
|
||||||
|
|||||||
@ -27,6 +27,7 @@ struct EQ::Net::ConcurrentEQStreamManager::Impl
|
|||||||
std::unordered_map<uint64_t, std::shared_ptr<ConcurrentEQStream>> streams;
|
std::unordered_map<uint64_t, std::shared_ptr<ConcurrentEQStream>> streams;
|
||||||
std::function<void(std::shared_ptr<EQStreamInterface>)> on_new_connection;
|
std::function<void(std::shared_ptr<EQStreamInterface>)> on_new_connection;
|
||||||
std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> on_connection_state_change;
|
std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> on_connection_state_change;
|
||||||
|
EQStreamPriority priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options)
|
EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options)
|
||||||
@ -36,6 +37,7 @@ EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamMana
|
|||||||
_impl->background = std::thread(std::bind(&ConcurrentEQStreamManager::_BackgroundThread, this));
|
_impl->background = std::thread(std::bind(&ConcurrentEQStreamManager::_BackgroundThread, this));
|
||||||
_impl->foreground_loop_timer.reset(new EQ::Timer(options.loop, 16, true,
|
_impl->foreground_loop_timer.reset(new EQ::Timer(options.loop, 16, true,
|
||||||
std::bind(&ConcurrentEQStreamManager::_ForegroundTimer, this, std::placeholders::_1)));
|
std::bind(&ConcurrentEQStreamManager::_ForegroundTimer, this, std::placeholders::_1)));
|
||||||
|
_impl->priority = EQStreamPriority::High;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
|
EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
|
||||||
@ -48,7 +50,7 @@ EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
|
|||||||
|
|
||||||
//Tell the background to shutdown and wait for it to actually do so
|
//Tell the background to shutdown and wait for it to actually do so
|
||||||
ceqs_terminate_msg_t msg;
|
ceqs_terminate_msg_t msg;
|
||||||
msg.type = TerminateBackground;
|
msg.type = ceqs_msg_type::TerminateBackground;
|
||||||
|
|
||||||
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
_impl->background.join();
|
_impl->background.join();
|
||||||
@ -57,7 +59,7 @@ EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
|
|||||||
ceqs_msg_t eqs_msg;
|
ceqs_msg_t eqs_msg;
|
||||||
|
|
||||||
while (_impl->foreground_queue.try_dequeue(eqs_msg)) {
|
while (_impl->foreground_queue.try_dequeue(eqs_msg)) {
|
||||||
if (eqs_msg.type == PacketRecv) {
|
if (eqs_msg.type == ceqs_msg_type::PacketRecv) {
|
||||||
ceqs_packet_recv_msg_t *eqs_msg_in = (ceqs_packet_recv_msg_t*)&eqs_msg;
|
ceqs_packet_recv_msg_t *eqs_msg_in = (ceqs_packet_recv_msg_t*)&eqs_msg;
|
||||||
|
|
||||||
delete eqs_msg_in->packet;
|
delete eqs_msg_in->packet;
|
||||||
@ -85,7 +87,18 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
|
|||||||
|
|
||||||
while (true == _impl->background_running) {
|
while (true == _impl->background_running) {
|
||||||
loop.Process();
|
loop.Process();
|
||||||
|
|
||||||
|
switch (_impl->priority) {
|
||||||
|
case EQStreamPriority::Low:
|
||||||
|
Sleep(10);
|
||||||
|
break;
|
||||||
|
case EQStreamPriority::Normal:
|
||||||
|
Sleep(5);
|
||||||
|
break;
|
||||||
|
case EQStreamPriority::High:
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_impl->background_loop_timer.release();
|
_impl->background_loop_timer.release();
|
||||||
@ -94,7 +107,7 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
|
|||||||
|
|
||||||
ceqs_msg_t eqs_msg;
|
ceqs_msg_t eqs_msg;
|
||||||
while (_impl->background_queue.try_dequeue(eqs_msg)) {
|
while (_impl->background_queue.try_dequeue(eqs_msg)) {
|
||||||
if (eqs_msg.type == QueuePacket) {
|
if (eqs_msg.type == ceqs_msg_type::QueuePacket) {
|
||||||
ceqs_queue_packet_msg_t *eqs_msg_in = (ceqs_queue_packet_msg_t*)&eqs_msg;
|
ceqs_queue_packet_msg_t *eqs_msg_in = (ceqs_queue_packet_msg_t*)&eqs_msg;
|
||||||
delete eqs_msg_in->packet;
|
delete eqs_msg_in->packet;
|
||||||
}
|
}
|
||||||
@ -142,7 +155,7 @@ void EQ::Net::ConcurrentEQStreamManager::_BackgroundUpdateStatsTimer(EQ::Timer *
|
|||||||
void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_msg_t &msg)
|
void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_msg_t &msg)
|
||||||
{
|
{
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case QueuePacket:
|
case ceqs_msg_type::QueuePacket:
|
||||||
{
|
{
|
||||||
ceqs_queue_packet_msg_t *msg_in = (ceqs_queue_packet_msg_t*)&msg;
|
ceqs_queue_packet_msg_t *msg_in = (ceqs_queue_packet_msg_t*)&msg;
|
||||||
|
|
||||||
@ -154,12 +167,12 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
|
|||||||
delete msg_in->packet;
|
delete msg_in->packet;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TerminateBackground:
|
case ceqs_msg_type::TerminateBackground:
|
||||||
{
|
{
|
||||||
_impl->background_running = false;
|
_impl->background_running = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CloseConnection:
|
case ceqs_msg_type::CloseConnection:
|
||||||
{
|
{
|
||||||
ceqs_close_connection_msg_t *msg_in = (ceqs_close_connection_msg_t*)&msg;
|
ceqs_close_connection_msg_t *msg_in = (ceqs_close_connection_msg_t*)&msg;
|
||||||
auto iter = _impl->connections.find(msg_in->stream_id);
|
auto iter = _impl->connections.find(msg_in->stream_id);
|
||||||
@ -168,7 +181,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ResetStats:
|
case ceqs_msg_type::ResetStats:
|
||||||
{
|
{
|
||||||
ceqs_reset_stats_msg_t *msg_in = (ceqs_reset_stats_msg_t*)&msg;
|
ceqs_reset_stats_msg_t *msg_in = (ceqs_reset_stats_msg_t*)&msg;
|
||||||
auto iter = _impl->connections.find(msg_in->stream_id);
|
auto iter = _impl->connections.find(msg_in->stream_id);
|
||||||
@ -177,6 +190,12 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_ms
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ceqs_msg_type::SetPriority:
|
||||||
|
{
|
||||||
|
ceqs_set_priority_msg_t *msg_in = (ceqs_set_priority_msg_t*)&msg;
|
||||||
|
_impl->priority = msg_in->priority;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -198,7 +217,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ForegroundTimer(EQ::Timer *t)
|
|||||||
void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_msg_t &msg)
|
void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_msg_t &msg)
|
||||||
{
|
{
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case NewConnection:
|
case ceqs_msg_type::NewConnection:
|
||||||
{
|
{
|
||||||
ceqs_new_connection_msg_t *msg_in = (ceqs_new_connection_msg_t*)&msg;
|
ceqs_new_connection_msg_t *msg_in = (ceqs_new_connection_msg_t*)&msg;
|
||||||
|
|
||||||
@ -214,7 +233,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectionStateChange:
|
case ceqs_msg_type::ConnectionStateChange:
|
||||||
{
|
{
|
||||||
ceqs_connection_state_change_msg_t *msg_in = (ceqs_connection_state_change_msg_t*)&msg;
|
ceqs_connection_state_change_msg_t *msg_in = (ceqs_connection_state_change_msg_t*)&msg;
|
||||||
|
|
||||||
@ -228,7 +247,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PacketRecv:
|
case ceqs_msg_type::PacketRecv:
|
||||||
{
|
{
|
||||||
ceqs_packet_recv_msg_t *msg_in = (ceqs_packet_recv_msg_t*)&msg;
|
ceqs_packet_recv_msg_t *msg_in = (ceqs_packet_recv_msg_t*)&msg;
|
||||||
std::unique_ptr<EQ::Net::Packet> p(msg_in->packet);
|
std::unique_ptr<EQ::Net::Packet> p(msg_in->packet);
|
||||||
@ -239,7 +258,7 @@ void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_ms
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UpdateStats:
|
case ceqs_msg_type::UpdateStats:
|
||||||
{
|
{
|
||||||
ceqs_update_stats_msg_t *msg_in = (ceqs_update_stats_msg_t*)&msg;
|
ceqs_update_stats_msg_t *msg_in = (ceqs_update_stats_msg_t*)&msg;
|
||||||
auto iter = _impl->streams.find(msg_in->stream_id);
|
auto iter = _impl->streams.find(msg_in->stream_id);
|
||||||
@ -275,6 +294,15 @@ void EQ::Net::ConcurrentEQStreamManager::OnConnectionStateChange(std::function<v
|
|||||||
_impl->on_connection_state_change = func;
|
_impl->on_connection_state_change = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::SetPriority(EQStreamPriority priority)
|
||||||
|
{
|
||||||
|
ceqs_set_priority_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::SetPriority;
|
||||||
|
msg.priority = priority;
|
||||||
|
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
//Called by background
|
//Called by background
|
||||||
void EQ::Net::ConcurrentEQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
void EQ::Net::ConcurrentEQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||||
{
|
{
|
||||||
@ -451,7 +479,7 @@ void EQ::Net::ConcurrentEQStream::Close()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ceqs_close_connection_msg_t msg;
|
ceqs_close_connection_msg_t msg;
|
||||||
msg.type = CloseConnection;
|
msg.type = ceqs_msg_type::CloseConnection;
|
||||||
msg.stream_id = _impl->id;
|
msg.stream_id = _impl->id;
|
||||||
|
|
||||||
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ namespace EQ
|
|||||||
|
|
||||||
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func);
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func);
|
||||||
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func);
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func);
|
||||||
|
virtual void SetPriority(EQStreamPriority priority);
|
||||||
|
|
||||||
void _PushToBackgroundQueue(ceqs_msg_t* msg);
|
void _PushToBackgroundQueue(ceqs_msg_t* msg);
|
||||||
void _PushToForegroundQueue(ceqs_msg_t* msg);
|
void _PushToForegroundQueue(ceqs_msg_t* msg);
|
||||||
|
|||||||
@ -18,7 +18,8 @@ namespace EQ
|
|||||||
QueuePacket,
|
QueuePacket,
|
||||||
TerminateBackground,
|
TerminateBackground,
|
||||||
CloseConnection,
|
CloseConnection,
|
||||||
ResetStats
|
ResetStats,
|
||||||
|
SetPriority
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -85,5 +86,10 @@ namespace EQ
|
|||||||
ceqs_msg_type type;
|
ceqs_msg_type type;
|
||||||
} ceqs_terminate_msg_t;
|
} ceqs_terminate_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
EQStreamPriority priority;
|
||||||
|
} ceqs_set_priority_msg_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -594,10 +594,12 @@ int main(int argc, char** argv) {
|
|||||||
if (previous_loaded && !current_loaded) {
|
if (previous_loaded && !current_loaded) {
|
||||||
process_timer.Stop();
|
process_timer.Stop();
|
||||||
process_timer.Start(1000, true);
|
process_timer.Start(1000, true);
|
||||||
|
eqsm->SetPriority(EQStreamPriority::Low);
|
||||||
}
|
}
|
||||||
else if (!previous_loaded && current_loaded) {
|
else if (!previous_loaded && current_loaded) {
|
||||||
process_timer.Stop();
|
process_timer.Stop();
|
||||||
process_timer.Start(32, true);
|
process_timer.Start(32, true);
|
||||||
|
eqsm->SetPriority(EQStreamPriority::High);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_loaded) {
|
if (current_loaded) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user