/* Copyright (C) 2019 Mr Goldberg
This file is part of the Goldberg Emulator
The Goldberg Emulator is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
The Goldberg Emulator 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the Goldberg Emulator; if not, see
. */
#include "dll/steam_client.h"
#include "dll/dll.h"
void Client_Background_Thread::thread_proc()
{
// wait for some time
{
std::unique_lock lck(kill_background_thread_mutex);
if (kill_background_thread_cv.wait_for(lck, initial_delay, [&] { return kill_background_thread; })) {
PRINT_DEBUG("early exit");
return;
}
}
PRINT_DEBUG("starting");
while (1) {
{
std::unique_lock lck(kill_background_thread_mutex);
if (kill_background_thread_cv.wait_for(lck, max_stall_ms, [&] { return kill_background_thread; })) {
PRINT_DEBUG("exit");
return;
}
}
auto now_ms = (unsigned long long)std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count();
// if our time exceeds last run time of callbacks and it wasn't processing already
const auto runcallbacks_timeout_ms = client_instance->get_last_runcallbacks_time() + max_stall_ms.count();
if (!client_instance->runcallbacks_active() && (now_ms >= runcallbacks_timeout_ms)) {
std::lock_guard lock(global_mutex);
PRINT_DEBUG("run @@@@@@@@@@@@@@@@@@@@@@@@@@@");
client_instance->set_last_runcallbacks_time(now_ms); // update the time counter just to avoid overlap
client_instance->network->Run(); // networking must run first since it receives messages used by each run_callback()
client_instance->run_every_runcb->run(); // call each run_callback()
}
}
}
Client_Background_Thread::Client_Background_Thread()
{
}
Client_Background_Thread::~Client_Background_Thread()
{
kill();
}
void Client_Background_Thread::start(Steam_Client *client_instance)
{
if (background_keepalive.joinable()) return; // alrady spawned
this->client_instance = client_instance;
background_keepalive = std::thread([this] { thread_proc(); });
PRINT_DEBUG("spawned background thread *********");
}
void Client_Background_Thread::kill()
{
if (!background_keepalive.joinable()) return; // already killed
{
std::lock_guard lk(kill_background_thread_mutex);
kill_background_thread = true;
}
kill_background_thread_cv.notify_one();
PRINT_DEBUG("joining worker thread");
background_keepalive.join();
PRINT_DEBUG("worker thread killed");
}