mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-30 11:19:51 +02:00
Use C++11 threads
This commit is contained in:
@@ -21,8 +21,6 @@ namespace http
|
||||
post_fields_last(NULL)
|
||||
#endif
|
||||
{
|
||||
pthread_cond_init(&done_cv, NULL);
|
||||
pthread_mutex_init(&rm_mutex, NULL);
|
||||
easy = curl_easy_init();
|
||||
RequestManager::Ref().AddRequest(this);
|
||||
}
|
||||
@@ -36,8 +34,6 @@ namespace http
|
||||
curl_formfree(post_fields_first);
|
||||
#endif
|
||||
curl_slist_free_all(headers);
|
||||
pthread_mutex_destroy(&rm_mutex);
|
||||
pthread_cond_destroy(&done_cv);
|
||||
}
|
||||
|
||||
void Request::AddHeader(ByteString name, ByteString value)
|
||||
@@ -179,9 +175,10 @@ namespace http
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, Request::WriteDataHandler);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
rm_started = true;
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
rm_started = true;
|
||||
}
|
||||
RequestManager::Ref().StartRequest(this);
|
||||
}
|
||||
|
||||
@@ -194,19 +191,18 @@ namespace http
|
||||
return ""; // shouldn't happen but just in case
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
while (!rm_finished)
|
||||
ByteString response_out;
|
||||
{
|
||||
pthread_cond_wait(&done_cv, &rm_mutex);
|
||||
std::unique_lock<std::mutex> l(rm_mutex);
|
||||
done_cv.wait(l, [this]() { return rm_finished; });
|
||||
rm_started = false;
|
||||
rm_canceled = true;
|
||||
if (status_out)
|
||||
{
|
||||
*status_out = status;
|
||||
}
|
||||
response_out = std::move(response_body);
|
||||
}
|
||||
rm_started = false;
|
||||
rm_canceled = true;
|
||||
if (status_out)
|
||||
{
|
||||
*status_out = status;
|
||||
}
|
||||
ByteString response_out = std::move(response_body);
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
|
||||
RequestManager::Ref().RemoveRequest(this);
|
||||
return response_out;
|
||||
@@ -214,7 +210,7 @@ namespace http
|
||||
|
||||
void Request::CheckProgress(int *total, int *done)
|
||||
{
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
if (total)
|
||||
{
|
||||
*total = rm_total;
|
||||
@@ -223,43 +219,37 @@ namespace http
|
||||
{
|
||||
*done = rm_done;
|
||||
}
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
}
|
||||
|
||||
// returns true if the request has finished
|
||||
bool Request::CheckDone()
|
||||
{
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
bool ret = rm_finished;
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
return ret;
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
return rm_finished;
|
||||
}
|
||||
|
||||
// returns true if the request was canceled
|
||||
bool Request::CheckCanceled()
|
||||
{
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
bool ret = rm_canceled;
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
return ret;
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
return rm_canceled;
|
||||
}
|
||||
|
||||
// returns true if the request is running
|
||||
bool Request::CheckStarted()
|
||||
{
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
bool ret = rm_started;
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
return ret;
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
return rm_started;
|
||||
|
||||
}
|
||||
|
||||
// cancels the request, the request thread will delete the Request* when it finishes (do not use Request in any way after canceling)
|
||||
void Request::Cancel()
|
||||
{
|
||||
pthread_mutex_lock(&rm_mutex);
|
||||
rm_canceled = true;
|
||||
pthread_mutex_unlock(&rm_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rm_mutex);
|
||||
rm_canceled = true;
|
||||
}
|
||||
RequestManager::Ref().RemoveRequest(this);
|
||||
}
|
||||
|
||||
|
@@ -3,10 +3,10 @@
|
||||
|
||||
#include <map>
|
||||
#include "common/tpt-minmax.h" // for MSVC, ensures windows.h doesn't cause compile errors by defining min/max
|
||||
#include "common/tpt-thread.h"
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <curl/curl.h>
|
||||
#include "common/String.h"
|
||||
#undef GetUserName // pthreads defines this, breaks stuff
|
||||
|
||||
#if defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 55, 0)
|
||||
# define REQUEST_USE_CURL_OFFSET_T
|
||||
@@ -32,7 +32,7 @@ namespace http
|
||||
volatile bool rm_finished;
|
||||
volatile bool rm_canceled;
|
||||
volatile bool rm_started;
|
||||
pthread_mutex_t rm_mutex;
|
||||
std::mutex rm_mutex;
|
||||
|
||||
bool added_to_multi;
|
||||
int status;
|
||||
@@ -46,7 +46,7 @@ namespace http
|
||||
std::map<ByteString, ByteString> post_fields_map;
|
||||
#endif
|
||||
|
||||
pthread_cond_t done_cv;
|
||||
std::condition_variable done_cv;
|
||||
|
||||
static size_t WriteDataHandler(char * ptr, size_t size, size_t count, void * userdata);
|
||||
|
||||
|
@@ -21,36 +21,27 @@ namespace http
|
||||
rt_shutting_down(false),
|
||||
multi(NULL)
|
||||
{
|
||||
pthread_cond_init(&rt_cv, NULL);
|
||||
pthread_mutex_init(&rt_mutex, NULL);
|
||||
}
|
||||
|
||||
RequestManager::~RequestManager()
|
||||
{
|
||||
pthread_mutex_destroy(&rt_mutex);
|
||||
pthread_cond_destroy(&rt_cv);
|
||||
}
|
||||
|
||||
void RequestManager::Shutdown()
|
||||
{
|
||||
pthread_mutex_lock(&rt_mutex);
|
||||
rt_shutting_down = true;
|
||||
pthread_cond_signal(&rt_cv);
|
||||
pthread_mutex_unlock(&rt_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rt_mutex);
|
||||
rt_shutting_down = true;
|
||||
}
|
||||
rt_cv.notify_one();
|
||||
|
||||
pthread_join(worker_thread, NULL);
|
||||
worker_thread.join();
|
||||
|
||||
curl_multi_cleanup(multi);
|
||||
multi = NULL;
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
TH_ENTRY_POINT void *RequestManager::RequestManagerHelper(void *obj)
|
||||
{
|
||||
((RequestManager *)obj)->Worker();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RequestManager::Initialise(ByteString Proxy)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
@@ -64,7 +55,7 @@ namespace http
|
||||
|
||||
user_agent = ByteString::Build("PowderToy/", SAVE_VERSION, ".", MINOR_VERSION, " (", IDENT_PLATFORM, "; ", IDENT_BUILD, "; M", MOD_ID, ") TPTPP/", SAVE_VERSION, ".", MINOR_VERSION, ".", BUILD_NUM, IDENT_RELTYPE, ".", SNAPSHOT_ID);
|
||||
|
||||
pthread_create(&worker_thread, NULL, &RequestManager::RequestManagerHelper, this);
|
||||
worker_thread = std::thread([this]() { Worker(); });
|
||||
}
|
||||
|
||||
void RequestManager::Worker()
|
||||
@@ -72,24 +63,25 @@ namespace http
|
||||
bool shutting_down = false;
|
||||
while (!shutting_down)
|
||||
{
|
||||
pthread_mutex_lock(&rt_mutex);
|
||||
if (!requests_added_to_multi)
|
||||
{
|
||||
while (!rt_shutting_down && requests_to_add.empty() && !requests_to_start && !requests_to_remove)
|
||||
std::unique_lock<std::mutex> l(rt_mutex);
|
||||
if (!requests_added_to_multi)
|
||||
{
|
||||
pthread_cond_wait(&rt_cv, &rt_mutex);
|
||||
while (!rt_shutting_down && requests_to_add.empty() && !requests_to_start && !requests_to_remove)
|
||||
{
|
||||
rt_cv.wait(l);
|
||||
}
|
||||
}
|
||||
shutting_down = rt_shutting_down;
|
||||
requests_to_remove = false;
|
||||
requests_to_start = false;
|
||||
for (Request *request : requests_to_add)
|
||||
{
|
||||
request->status = 0;
|
||||
requests.insert(request);
|
||||
}
|
||||
requests_to_add.clear();
|
||||
}
|
||||
shutting_down = rt_shutting_down;
|
||||
requests_to_remove = false;
|
||||
requests_to_start = false;
|
||||
for (Request *request : requests_to_add)
|
||||
{
|
||||
request->status = 0;
|
||||
requests.insert(request);
|
||||
}
|
||||
requests_to_add.clear();
|
||||
pthread_mutex_unlock(&rt_mutex);
|
||||
|
||||
if (multi && requests_added_to_multi)
|
||||
{
|
||||
@@ -157,52 +149,60 @@ namespace http
|
||||
std::set<Request *> requests_to_remove;
|
||||
for (Request *request : requests)
|
||||
{
|
||||
pthread_mutex_lock(&request->rm_mutex);
|
||||
if (shutting_down)
|
||||
bool signal_done = false;
|
||||
|
||||
{
|
||||
// In the weird case that a http::Request::Simple* call is
|
||||
// waiting on this Request, we should fail the request
|
||||
// instead of cancelling it ourselves.
|
||||
request->status = 610;
|
||||
}
|
||||
if (!request->rm_canceled && request->rm_started && !request->added_to_multi && !request->status)
|
||||
{
|
||||
if (multi && request->easy)
|
||||
std::lock_guard<std::mutex> g(request->rm_mutex);
|
||||
if (shutting_down)
|
||||
{
|
||||
MultiAdd(request);
|
||||
// In the weird case that a http::Request::Simple* call is
|
||||
// waiting on this Request, we should fail the request
|
||||
// instead of cancelling it ourselves.
|
||||
request->status = 610;
|
||||
}
|
||||
else
|
||||
if (!request->rm_canceled && request->rm_started && !request->added_to_multi && !request->status)
|
||||
{
|
||||
request->status = 604;
|
||||
if (multi && request->easy)
|
||||
{
|
||||
MultiAdd(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
request->status = 604;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!request->rm_canceled && request->rm_started && !request->rm_finished)
|
||||
{
|
||||
if (multi && request->easy)
|
||||
if (!request->rm_canceled && request->rm_started && !request->rm_finished)
|
||||
{
|
||||
if (multi && request->easy)
|
||||
{
|
||||
#ifdef REQUEST_USE_CURL_OFFSET_T
|
||||
curl_easy_getinfo(request->easy, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &request->rm_total);
|
||||
curl_easy_getinfo(request->easy, CURLINFO_SIZE_DOWNLOAD_T, &request->rm_done);
|
||||
curl_easy_getinfo(request->easy, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &request->rm_total);
|
||||
curl_easy_getinfo(request->easy, CURLINFO_SIZE_DOWNLOAD_T, &request->rm_done);
|
||||
#else
|
||||
double total, done;
|
||||
curl_easy_getinfo(request->easy, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &total);
|
||||
curl_easy_getinfo(request->easy, CURLINFO_SIZE_DOWNLOAD, &done);
|
||||
request->rm_total = (curl_off_t)total;
|
||||
request->rm_done = (curl_off_t)done;
|
||||
double total, done;
|
||||
curl_easy_getinfo(request->easy, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &total);
|
||||
curl_easy_getinfo(request->easy, CURLINFO_SIZE_DOWNLOAD, &done);
|
||||
request->rm_total = (curl_off_t)total;
|
||||
request->rm_done = (curl_off_t)done;
|
||||
#endif
|
||||
}
|
||||
if (request->status)
|
||||
{
|
||||
request->rm_finished = true;
|
||||
MultiRemove(request);
|
||||
signal_done = true;
|
||||
}
|
||||
}
|
||||
if (request->status)
|
||||
if (request->rm_canceled)
|
||||
{
|
||||
request->rm_finished = true;
|
||||
MultiRemove(request);
|
||||
pthread_cond_signal(&request->done_cv);
|
||||
requests_to_remove.insert(request);
|
||||
}
|
||||
}
|
||||
if (request->rm_canceled)
|
||||
|
||||
if (signal_done)
|
||||
{
|
||||
requests_to_remove.insert(request);
|
||||
request->done_cv.notify_one();
|
||||
}
|
||||
pthread_mutex_unlock(&request->rm_mutex);
|
||||
}
|
||||
for (Request *request : requests_to_remove)
|
||||
{
|
||||
@@ -235,25 +235,28 @@ namespace http
|
||||
|
||||
void RequestManager::AddRequest(Request *request)
|
||||
{
|
||||
pthread_mutex_lock(&rt_mutex);
|
||||
requests_to_add.insert(request);
|
||||
pthread_cond_signal(&rt_cv);
|
||||
pthread_mutex_unlock(&rt_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rt_mutex);
|
||||
requests_to_add.insert(request);
|
||||
}
|
||||
rt_cv.notify_one();
|
||||
}
|
||||
|
||||
void RequestManager::StartRequest(Request *request)
|
||||
{
|
||||
pthread_mutex_lock(&rt_mutex);
|
||||
requests_to_start = true;
|
||||
pthread_cond_signal(&rt_cv);
|
||||
pthread_mutex_unlock(&rt_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rt_mutex);
|
||||
requests_to_start = true;
|
||||
}
|
||||
rt_cv.notify_one();
|
||||
}
|
||||
|
||||
void RequestManager::RemoveRequest(Request *request)
|
||||
{
|
||||
pthread_mutex_lock(&rt_mutex);
|
||||
requests_to_remove = true;
|
||||
pthread_cond_signal(&rt_cv);
|
||||
pthread_mutex_unlock(&rt_mutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(rt_mutex);
|
||||
requests_to_remove = true;
|
||||
}
|
||||
rt_cv.notify_one();
|
||||
}
|
||||
}
|
||||
|
@@ -2,20 +2,21 @@
|
||||
#define REQUESTMANAGER_H
|
||||
|
||||
#include "common/tpt-minmax.h" // for MSVC, ensures windows.h doesn't cause compile errors by defining min/max
|
||||
#include "common/tpt-thread.h"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <curl/curl.h>
|
||||
#include "common/Singleton.h"
|
||||
#include "common/String.h"
|
||||
#undef GetUserName // pthreads (included by curl) defines this, breaks stuff
|
||||
|
||||
namespace http
|
||||
{
|
||||
class Request;
|
||||
class RequestManager : public Singleton<RequestManager>
|
||||
{
|
||||
pthread_t worker_thread;
|
||||
std::thread worker_thread;
|
||||
std::set<Request *> requests;
|
||||
int requests_added_to_multi;
|
||||
|
||||
@@ -23,8 +24,8 @@ namespace http
|
||||
bool requests_to_start;
|
||||
bool requests_to_remove;
|
||||
bool rt_shutting_down;
|
||||
pthread_mutex_t rt_mutex;
|
||||
pthread_cond_t rt_cv;
|
||||
std::mutex rt_mutex;
|
||||
std::condition_variable rt_cv;
|
||||
|
||||
CURLM *multi;
|
||||
|
||||
@@ -36,8 +37,6 @@ namespace http
|
||||
void StartRequest(Request *request);
|
||||
void RemoveRequest(Request *request);
|
||||
|
||||
static TH_ENTRY_POINT void *RequestManagerHelper(void *obj);
|
||||
|
||||
public:
|
||||
RequestManager();
|
||||
~RequestManager();
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common/tpt-thread.h"
|
||||
#include "String.h"
|
||||
|
||||
ByteString ConversionError::formatError(ByteString::value_type const *at, ByteString::value_type const *upto)
|
||||
@@ -374,31 +373,10 @@ struct LocaleImpl
|
||||
}
|
||||
};
|
||||
|
||||
static void destroyLocaleImpl(void *ptr)
|
||||
{
|
||||
delete static_cast<LocaleImpl *>(ptr);
|
||||
}
|
||||
|
||||
static pthread_once_t localeOnce = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t localeKey;
|
||||
|
||||
static void createLocaleKey()
|
||||
{
|
||||
if(int error = pthread_key_create(&localeKey, destroyLocaleImpl))
|
||||
throw std::system_error(error, std::system_category(), "Could not create TLS key for LocaleImpl");
|
||||
}
|
||||
|
||||
static LocaleImpl *getLocaleImpl()
|
||||
{
|
||||
pthread_once(&localeOnce, createLocaleKey);
|
||||
void *ptr = pthread_getspecific(localeKey);
|
||||
if(!ptr)
|
||||
{
|
||||
ptr = static_cast<void *>(new LocaleImpl());
|
||||
if(int error = pthread_setspecific(localeKey, ptr))
|
||||
throw std::system_error(error, std::system_category(), "Could not put LocaleImpl into TLS");
|
||||
}
|
||||
return static_cast<LocaleImpl *>(ptr);
|
||||
thread_local LocaleImpl li;
|
||||
return &li;
|
||||
}
|
||||
|
||||
ByteString ByteStringBuilder::Build() const
|
||||
|
@@ -1,26 +0,0 @@
|
||||
#ifndef TPT_THREAD_H
|
||||
#define TPT_THREAD_H
|
||||
|
||||
#if defined(WIN) && defined(__GNUC__)
|
||||
#define TH_ENTRY_POINT __attribute__((force_align_arg_pointer))
|
||||
#define _TIMESPEC_DEFINED
|
||||
#else
|
||||
#define TH_ENTRY_POINT
|
||||
#endif
|
||||
|
||||
// fix 'timespec' error in VS 2015
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
|
||||
#define _TIMESPEC_DEFINED 1
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#undef GetUserName
|
||||
|
||||
// Fix deprecation warnings with recent pthread versions on Windows
|
||||
#if defined(_PTW32_STATIC_LIB) && defined(WIN)
|
||||
#if PTW32_VERSION <= 2, 8, 0, 0
|
||||
#define PTW32_STATIC_LIB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -128,9 +128,6 @@ public:
|
||||
|
||||
VideoBuffer DumpFrame();
|
||||
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
void blendpixel(int x, int y, int r, int g, int b, int a);
|
||||
void addpixel(int x, int y, int r, int g, int b, int a);
|
||||
|
||||
|
@@ -1,22 +1,12 @@
|
||||
#include "Graphics.h"
|
||||
#include "FontReader.h"
|
||||
#include "common/tpt-thread.h"
|
||||
#ifdef OGLI
|
||||
|
||||
static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
//static pthread_mutex_t TMPMUT = PTHREAD_MUTEX_INITIALIZER;
|
||||
Graphics::Graphics():
|
||||
sdl_scale(1)
|
||||
{
|
||||
// if(gMutex == TMPMUT)
|
||||
// pthread_mutex_init (&gMutex, NULL);
|
||||
LoadDefaults();
|
||||
InitialiseTextures();
|
||||
|
||||
|
||||
|
||||
//Texture for main UI
|
||||
|
||||
}
|
||||
|
||||
void Graphics::LoadDefaults()
|
||||
@@ -68,16 +58,6 @@ void Graphics::DestroyTextures()
|
||||
//Todo...
|
||||
}
|
||||
|
||||
void Graphics::Acquire()
|
||||
{
|
||||
pthread_mutex_lock(&gMutex);
|
||||
}
|
||||
|
||||
void Graphics::Release()
|
||||
{
|
||||
pthread_mutex_unlock(&gMutex);
|
||||
}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
}
|
||||
|
@@ -9,16 +9,6 @@ sdl_scale(1)
|
||||
|
||||
}
|
||||
|
||||
void Graphics::Acquire()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Graphics::Release()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
free(vid);
|
||||
|
@@ -225,7 +225,6 @@ void Engine::Draw()
|
||||
{
|
||||
if(lastBuffer && !(state_ && state_->Position.X == 0 && state_->Position.Y == 0 && state_->Size.X == width_ && state_->Size.Y == height_))
|
||||
{
|
||||
g->Acquire();
|
||||
g->Clear();
|
||||
#ifndef OGLI
|
||||
memcpy(g->vid, lastBuffer, (width_ * height_) * PIXELSIZE);
|
||||
@@ -242,7 +241,6 @@ void Engine::Draw()
|
||||
state_->DoDraw();
|
||||
|
||||
g->Finalise();
|
||||
g->Release();
|
||||
FrameIndex++;
|
||||
FrameIndex %= 7200;
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "client/Client.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
SearchModel::SearchModel():
|
||||
loadedSave(NULL),
|
||||
currentSort("best"),
|
||||
@@ -14,8 +16,10 @@ SearchModel::SearchModel():
|
||||
saveListLoaded(false),
|
||||
updateSaveListWorking(false),
|
||||
updateSaveListFinished(false),
|
||||
updateSaveListResult(nullptr),
|
||||
updateTagListWorking(false),
|
||||
updateTagListFinished(false)
|
||||
updateTagListFinished(false),
|
||||
updateTagListResult(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,36 +33,26 @@ bool SearchModel::GetShowTags()
|
||||
return showTags;
|
||||
}
|
||||
|
||||
TH_ENTRY_POINT void * SearchModel::updateSaveListTHelper(void * obj)
|
||||
{
|
||||
return ((SearchModel *)obj)->updateSaveListT();
|
||||
}
|
||||
|
||||
void * SearchModel::updateSaveListT()
|
||||
void SearchModel::updateSaveListT()
|
||||
{
|
||||
ByteString category = "";
|
||||
if(showFavourite)
|
||||
category = "Favourites";
|
||||
if(showOwn && Client::Ref().GetAuthUser().UserID)
|
||||
category = "by:"+Client::Ref().GetAuthUser().Username;
|
||||
vector<SaveInfo*> * saveList = Client::Ref().SearchSaves((currentPage-1)*20, 20, lastQuery, currentSort=="new"?"date":"votes", category, thResultCount);
|
||||
std::vector<SaveInfo*> * saveList = Client::Ref().SearchSaves((currentPage-1)*20, 20, lastQuery, currentSort=="new"?"date":"votes", category, thResultCount);
|
||||
|
||||
updateSaveListResult = saveList;
|
||||
updateSaveListFinished = true;
|
||||
return saveList;
|
||||
}
|
||||
|
||||
TH_ENTRY_POINT void * SearchModel::updateTagListTHelper(void * obj)
|
||||
{
|
||||
return ((SearchModel *)obj)->updateTagListT();
|
||||
}
|
||||
|
||||
void * SearchModel::updateTagListT()
|
||||
void SearchModel::updateTagListT()
|
||||
{
|
||||
int tagResultCount;
|
||||
std::vector<std::pair<ByteString, int> > * tagList = Client::Ref().GetTags(0, 24, "", tagResultCount);
|
||||
|
||||
updateTagListResult = tagList;
|
||||
updateTagListFinished = true;
|
||||
return tagList;
|
||||
}
|
||||
|
||||
bool SearchModel::UpdateSaveList(int pageNumber, String query)
|
||||
@@ -88,12 +82,12 @@ bool SearchModel::UpdateSaveList(int pageNumber, String query)
|
||||
{
|
||||
updateTagListFinished = false;
|
||||
updateTagListWorking = true;
|
||||
pthread_create(&updateTagListThread, 0, &SearchModel::updateTagListTHelper, this);
|
||||
std::thread([this]() { updateTagListT(); }).detach();
|
||||
}
|
||||
|
||||
updateSaveListFinished = false;
|
||||
updateSaveListWorking = true;
|
||||
pthread_create(&updateSaveListThread, 0, &SearchModel::updateSaveListTHelper, this);
|
||||
std::thread([this]() { updateSaveListT(); }).detach();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -117,12 +111,12 @@ SaveInfo * SearchModel::GetLoadedSave(){
|
||||
return loadedSave;
|
||||
}
|
||||
|
||||
vector<SaveInfo*> SearchModel::GetSaveList()
|
||||
std::vector<SaveInfo*> SearchModel::GetSaveList()
|
||||
{
|
||||
return saveList;
|
||||
}
|
||||
|
||||
vector<pair<ByteString, int> > SearchModel::GetTagList()
|
||||
std::vector<std::pair<ByteString, int> > SearchModel::GetTagList()
|
||||
{
|
||||
return tagList;
|
||||
}
|
||||
@@ -137,8 +131,8 @@ void SearchModel::Update()
|
||||
lastError = "";
|
||||
saveListLoaded = true;
|
||||
|
||||
vector<SaveInfo*> * tempSaveList;
|
||||
pthread_join(updateSaveListThread, (void**)&tempSaveList);
|
||||
std::vector<SaveInfo *> *tempSaveList = updateSaveListResult;
|
||||
updateSaveListResult = nullptr;
|
||||
|
||||
if(tempSaveList)
|
||||
{
|
||||
@@ -164,8 +158,8 @@ void SearchModel::Update()
|
||||
{
|
||||
updateTagListWorking = false;
|
||||
|
||||
vector<pair<ByteString, int> > * tempTagList;
|
||||
pthread_join(updateTagListThread, (void**)&tempTagList);
|
||||
std::vector<std::pair<ByteString, int>> *tempTagList = updateTagListResult;
|
||||
updateTagListResult = nullptr;
|
||||
|
||||
if(tempTagList)
|
||||
{
|
||||
|
@@ -4,13 +4,11 @@
|
||||
#include <vector>
|
||||
#include "common/String.h"
|
||||
#include "common/tpt-minmax.h"
|
||||
#include "common/tpt-thread.h"
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include "client/SaveInfo.h"
|
||||
#include "SearchView.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SearchView;
|
||||
class SearchModel
|
||||
{
|
||||
@@ -19,10 +17,10 @@ private:
|
||||
ByteString currentSort;
|
||||
String lastQuery;
|
||||
String lastError;
|
||||
vector<int> selected;
|
||||
vector<SearchView*> observers;
|
||||
vector<SaveInfo*> saveList;
|
||||
vector<pair<ByteString, int> > tagList;
|
||||
std::vector<int> selected;
|
||||
std::vector<SearchView*> observers;
|
||||
std::vector<SaveInfo*> saveList;
|
||||
std::vector<std::pair<ByteString, int> > tagList;
|
||||
int currentPage;
|
||||
int resultCount;
|
||||
int thResultCount;
|
||||
@@ -40,16 +38,14 @@ private:
|
||||
//Variables and methods for background save request
|
||||
bool saveListLoaded;
|
||||
bool updateSaveListWorking;
|
||||
volatile bool updateSaveListFinished;
|
||||
pthread_t updateSaveListThread;
|
||||
TH_ENTRY_POINT static void * updateSaveListTHelper(void * obj);
|
||||
void * updateSaveListT();
|
||||
std::atomic<bool> updateSaveListFinished;
|
||||
void updateSaveListT();
|
||||
std::vector<SaveInfo *> *updateSaveListResult;
|
||||
|
||||
bool updateTagListWorking;
|
||||
volatile bool updateTagListFinished;
|
||||
pthread_t updateTagListThread;
|
||||
TH_ENTRY_POINT static void * updateTagListTHelper(void * obj);
|
||||
void * updateTagListT();
|
||||
std::atomic<bool> updateTagListFinished;
|
||||
void updateTagListT();
|
||||
std::vector<std::pair<ByteString, int>> *updateTagListResult;
|
||||
public:
|
||||
SearchModel();
|
||||
virtual ~SearchModel();
|
||||
@@ -58,8 +54,8 @@ public:
|
||||
bool GetShowTags();
|
||||
void AddObserver(SearchView * observer);
|
||||
bool UpdateSaveList(int pageNumber, String query);
|
||||
vector<SaveInfo*> GetSaveList();
|
||||
vector<pair<ByteString, int> > GetTagList();
|
||||
std::vector<SaveInfo*> GetSaveList();
|
||||
std::vector<std::pair<ByteString, int> > GetTagList();
|
||||
String GetLastError() { return lastError; }
|
||||
int GetPageCount()
|
||||
{
|
||||
@@ -79,7 +75,7 @@ public:
|
||||
void SetLoadedSave(SaveInfo * save);
|
||||
SaveInfo * GetLoadedSave();
|
||||
bool GetSavesLoaded() { return saveListLoaded; }
|
||||
vector<int> GetSelected() { return selected; }
|
||||
std::vector<int> GetSelected() { return selected; }
|
||||
void ClearSelected() { selected.clear(); notifySelectedChanged(); }
|
||||
void SelectSave(int saveID);
|
||||
void DeselectSave(int saveID);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#include <cmath>
|
||||
#include <sys/types.h>
|
||||
#include "common/tpt-thread.h"
|
||||
#include "Config.h"
|
||||
#include "Gravity.h"
|
||||
#include "Misc.h"
|
||||
@@ -85,13 +84,15 @@ void Gravity::gravity_update_async()
|
||||
int result;
|
||||
if (ngrav_enable)
|
||||
{
|
||||
if (!pthread_mutex_trylock(&gravmutex))
|
||||
bool signal_grav = false;
|
||||
|
||||
{
|
||||
result = grav_ready;
|
||||
if (result) //Did the gravity thread finish?
|
||||
std::unique_lock<std::mutex> l(gravmutex, std::defer_lock);
|
||||
if (l.try_lock())
|
||||
{
|
||||
//if (!sys_pause||framerender){ //Only update if not paused
|
||||
//Switch the full size gravmaps, we don't really need the two above any more
|
||||
result = grav_ready;
|
||||
if (result) //Did the gravity thread finish?
|
||||
{
|
||||
float *tmpf;
|
||||
|
||||
if (th_gravchanged && !ignoreNextResult)
|
||||
@@ -121,10 +122,14 @@ void Gravity::gravity_update_async()
|
||||
th_gravmap = tmpf;
|
||||
|
||||
grav_ready = 0; //Tell the other thread that we're ready for it to continue
|
||||
pthread_cond_signal(&gravcv);
|
||||
//}
|
||||
signal_grav = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (signal_grav)
|
||||
{
|
||||
gravcv.notify_one();
|
||||
}
|
||||
pthread_mutex_unlock(&gravmutex);
|
||||
}
|
||||
//Apply the gravity mask
|
||||
membwand(gravy, gravmask, (XRES/CELL)*(YRES/CELL)*sizeof(float), (XRES/CELL)*(YRES/CELL)*sizeof(unsigned));
|
||||
@@ -133,12 +138,6 @@ void Gravity::gravity_update_async()
|
||||
}
|
||||
}
|
||||
|
||||
TH_ENTRY_POINT void *Gravity::update_grav_async_helper(void * context)
|
||||
{
|
||||
((Gravity *)context)->update_grav_async();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Gravity::update_grav_async()
|
||||
{
|
||||
int done = 0;
|
||||
@@ -155,7 +154,8 @@ void Gravity::update_grav_async()
|
||||
if (!grav_fft_status)
|
||||
grav_fft_init();
|
||||
#endif
|
||||
pthread_mutex_lock(&gravmutex);
|
||||
|
||||
std::unique_lock<std::mutex> l(gravmutex);
|
||||
while (!thread_done)
|
||||
{
|
||||
if (!done)
|
||||
@@ -167,13 +167,11 @@ void Gravity::update_grav_async()
|
||||
thread_done = gravthread_done;
|
||||
} else {
|
||||
// wait for main thread
|
||||
pthread_cond_wait(&gravcv, &gravmutex);
|
||||
gravcv.wait(l);
|
||||
done = grav_ready;
|
||||
thread_done = gravthread_done;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&gravmutex);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void Gravity::start_grav_async()
|
||||
@@ -183,9 +181,7 @@ void Gravity::start_grav_async()
|
||||
|
||||
gravthread_done = 0;
|
||||
grav_ready = 0;
|
||||
pthread_mutex_init (&gravmutex, NULL);
|
||||
pthread_cond_init(&gravcv, NULL);
|
||||
pthread_create(&gravthread, NULL, &Gravity::update_grav_async_helper, this); //Start asynchronous gravity simulation
|
||||
gravthread = std::thread([this]() { update_grav_async(); }); //Start asynchronous gravity simulation
|
||||
ngrav_enable = 1;
|
||||
|
||||
memset(gravy, 0, (XRES/CELL)*(YRES/CELL)*sizeof(float));
|
||||
@@ -198,12 +194,12 @@ void Gravity::stop_grav_async()
|
||||
{
|
||||
if (ngrav_enable)
|
||||
{
|
||||
pthread_mutex_lock(&gravmutex);
|
||||
gravthread_done = 1;
|
||||
pthread_cond_signal(&gravcv);
|
||||
pthread_mutex_unlock(&gravmutex);
|
||||
pthread_join(gravthread, NULL);
|
||||
pthread_mutex_destroy(&gravmutex); //Destroy the mutex
|
||||
{
|
||||
std::lock_guard<std::mutex> g(gravmutex);
|
||||
gravthread_done = 1;
|
||||
}
|
||||
gravcv.notify_one();
|
||||
gravthread.join();
|
||||
ngrav_enable = 0;
|
||||
}
|
||||
//Clear the grav velocities
|
||||
|
@@ -1,7 +1,9 @@
|
||||
#ifndef GRAVITY_H
|
||||
#define GRAVITY_H
|
||||
|
||||
#include "common/tpt-thread.h"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include "Config.h"
|
||||
#include "Simulation.h"
|
||||
|
||||
@@ -18,28 +20,6 @@ struct mask_el {
|
||||
};
|
||||
typedef struct mask_el mask_el;
|
||||
|
||||
|
||||
/*
|
||||
* float *gravmap = NULL;//Maps to be used by the main thread
|
||||
float *gravp = NULL;
|
||||
float *gravy = NULL;
|
||||
float *gravx = NULL;
|
||||
unsigned *gravmask = NULL;
|
||||
|
||||
float *th_ogravmap = NULL;// Maps to be processed by the gravity thread
|
||||
float *th_gravmap = NULL;
|
||||
float *th_gravx = NULL;
|
||||
float *th_gravy = NULL;
|
||||
float *th_gravp = NULL;
|
||||
|
||||
int th_gravchanged = 0;
|
||||
|
||||
pthread_t gravthread;
|
||||
pthread_mutex_t gravmutex;
|
||||
pthread_cond_t gravcv;
|
||||
int grav_ready = 0;
|
||||
int gravthread_done = 0;
|
||||
*/
|
||||
class Gravity
|
||||
{
|
||||
private:
|
||||
@@ -52,9 +32,9 @@ private:
|
||||
|
||||
int th_gravchanged;
|
||||
|
||||
pthread_t gravthread;
|
||||
pthread_mutex_t gravmutex;
|
||||
pthread_cond_t gravcv;
|
||||
std::thread gravthread;
|
||||
std::mutex gravmutex;
|
||||
std::condition_variable gravcv;
|
||||
int grav_ready;
|
||||
int gravthread_done;
|
||||
|
||||
@@ -84,7 +64,6 @@ public:
|
||||
void gravity_cleanup();
|
||||
void gravity_update_async();
|
||||
|
||||
TH_ENTRY_POINT static void *update_grav_async_helper(void * context);
|
||||
void update_grav_async();
|
||||
|
||||
void start_grav_async();
|
||||
|
@@ -29,13 +29,11 @@ SaveRenderer::SaveRenderer(){
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
||||
pthread_mutex_init(&renderMutex, NULL);
|
||||
}
|
||||
|
||||
VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
||||
{
|
||||
pthread_mutex_lock(&renderMutex);
|
||||
std::lock_guard<std::mutex> gx(renderMutex);
|
||||
|
||||
int width, height;
|
||||
VideoBuffer * tempThumb = NULL;
|
||||
@@ -43,7 +41,6 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
||||
height = save->blockHeight;
|
||||
bool doCollapse = save->Collapsed();
|
||||
|
||||
g->Acquire();
|
||||
g->Clear();
|
||||
sim->clear_sim();
|
||||
|
||||
@@ -148,15 +145,13 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire)
|
||||
}
|
||||
if(doCollapse)
|
||||
save->Collapse();
|
||||
g->Release();
|
||||
|
||||
pthread_mutex_unlock(&renderMutex);
|
||||
return tempThumb;
|
||||
}
|
||||
|
||||
VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool decorations, bool fire)
|
||||
{
|
||||
pthread_mutex_lock(&renderMutex);
|
||||
std::lock_guard<std::mutex> g(renderMutex);
|
||||
|
||||
GameSave * tempSave;
|
||||
try {
|
||||
@@ -167,17 +162,15 @@ VideoBuffer * SaveRenderer::Render(unsigned char * saveData, int dataSize, bool
|
||||
VideoBuffer * buffer = new VideoBuffer(64, 64);
|
||||
buffer->BlendCharacter(32, 32, 'x', 255, 255, 255, 255);
|
||||
|
||||
pthread_mutex_unlock(&renderMutex);
|
||||
return buffer;
|
||||
}
|
||||
VideoBuffer * thumb = Render(tempSave, decorations, fire);
|
||||
delete tempSave;
|
||||
|
||||
pthread_mutex_unlock(&renderMutex);
|
||||
return thumb;
|
||||
}
|
||||
|
||||
SaveRenderer::~SaveRenderer() {
|
||||
pthread_mutex_destroy(&renderMutex);
|
||||
SaveRenderer::~SaveRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "graphics/OpenGLHeaders.h"
|
||||
#endif
|
||||
#include "common/Singleton.h"
|
||||
#include "common/tpt-thread.h"
|
||||
#include <mutex>
|
||||
|
||||
class GameSave;
|
||||
class VideoBuffer;
|
||||
@@ -16,7 +16,7 @@ class SaveRenderer: public Singleton<SaveRenderer> {
|
||||
Graphics * g;
|
||||
Simulation * sim;
|
||||
Renderer * ren;
|
||||
pthread_mutex_t renderMutex;
|
||||
std::mutex renderMutex;
|
||||
public:
|
||||
SaveRenderer();
|
||||
VideoBuffer * Render(GameSave * save, bool decorations = true, bool fire = true);
|
||||
|
@@ -5,11 +5,13 @@
|
||||
void AbandonableTask::doWork_wrapper()
|
||||
{
|
||||
Task::doWork_wrapper();
|
||||
pthread_cond_signal(&done_cv);
|
||||
done_cv.notify_one();
|
||||
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
bool abandoned = thAbandoned;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
bool abandoned;
|
||||
{
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
abandoned = thAbandoned;
|
||||
}
|
||||
if (abandoned)
|
||||
{
|
||||
delete this;
|
||||
@@ -18,12 +20,10 @@ void AbandonableTask::doWork_wrapper()
|
||||
|
||||
void AbandonableTask::Finish()
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
while (!thDone)
|
||||
{
|
||||
pthread_cond_wait(&done_cv, &taskMutex);
|
||||
std::unique_lock<std::mutex> l(taskMutex);
|
||||
done_cv.wait(l, [this]() { return thDone; });
|
||||
}
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
|
||||
// Poll to make sure that the rest of the Task knows that it's
|
||||
// done, not just us. This has to be done because the thread that started
|
||||
@@ -37,23 +37,24 @@ void AbandonableTask::Finish()
|
||||
void AbandonableTask::Abandon()
|
||||
{
|
||||
bool delete_this = false;
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
if (thDone)
|
||||
{
|
||||
// If thDone is true, the thread has already finished. We're
|
||||
// not calling Poll because it may call callbacks, which
|
||||
// an abandoned task shouldn't do. Instead we just delete the
|
||||
// AbandonableTask after unlocking the mutex.
|
||||
delete_this = true;
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
if (thDone)
|
||||
{
|
||||
// If thDone is true, the thread has already finished. We're
|
||||
// not calling Poll because it may call callbacks, which
|
||||
// an abandoned task shouldn't do. Instead we just delete the
|
||||
// AbandonableTask after unlocking the mutex.
|
||||
delete_this = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If at this point thDone is still false, the thread is still
|
||||
// running, meaning we can safely set thAbandoned and let
|
||||
// AbandonableTask::doWork_wrapper delete the AbandonableTask later.
|
||||
thAbandoned = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If at this point thDone is still false, the thread is still
|
||||
// running, meaning we can safely set thAbandoned and let
|
||||
// AbandonableTask::doWork_wrapper delete the AbandonableTask later.
|
||||
thAbandoned = true;
|
||||
}
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
|
||||
if (delete_this)
|
||||
{
|
||||
@@ -64,11 +65,9 @@ void AbandonableTask::Abandon()
|
||||
AbandonableTask::AbandonableTask() :
|
||||
thAbandoned(false)
|
||||
{
|
||||
pthread_cond_init(&done_cv, NULL);
|
||||
}
|
||||
|
||||
AbandonableTask::~AbandonableTask()
|
||||
{
|
||||
pthread_cond_destroy(&done_cv);
|
||||
}
|
||||
|
||||
|
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "Task.h"
|
||||
|
||||
#include <condition_variable>
|
||||
|
||||
class AbandonableTask : public Task
|
||||
{
|
||||
pthread_cond_t done_cv;
|
||||
std::condition_variable done_cv;
|
||||
|
||||
public:
|
||||
void Finish();
|
||||
|
@@ -12,10 +12,7 @@ void Task::AddTaskListener(TaskListener * listener)
|
||||
void Task::Start()
|
||||
{
|
||||
before();
|
||||
// This would use a lambda if we didn't use pthreads and if I dared omit
|
||||
// the TH_ENTRY_POINT from the function type.
|
||||
pthread_create(&doWorkThread, 0, &Task::doWork_helper, this);
|
||||
pthread_detach(doWorkThread);
|
||||
std::thread([this]() { doWork_wrapper(); }).detach();
|
||||
}
|
||||
|
||||
int Task::GetProgress()
|
||||
@@ -52,13 +49,14 @@ void Task::Poll()
|
||||
bool newSuccess = false;
|
||||
String newStatus;
|
||||
String newError;
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
newProgress = thProgress;
|
||||
newDone = thDone;
|
||||
newSuccess = thSuccess;
|
||||
newStatus = thStatus;
|
||||
newError = thError;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
{
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
newProgress = thProgress;
|
||||
newDone = thDone;
|
||||
newSuccess = thSuccess;
|
||||
newStatus = thStatus;
|
||||
newError = thError;
|
||||
}
|
||||
|
||||
success = newSuccess;
|
||||
|
||||
@@ -93,12 +91,10 @@ Task::Task() :
|
||||
thDone(false),
|
||||
listener(NULL)
|
||||
{
|
||||
pthread_mutex_init(&taskMutex, NULL);
|
||||
}
|
||||
|
||||
Task::~Task()
|
||||
{
|
||||
pthread_mutex_destroy(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::before()
|
||||
@@ -124,37 +120,29 @@ void Task::after()
|
||||
void Task::doWork_wrapper()
|
||||
{
|
||||
bool newSuccess = doWork();
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
thSuccess = newSuccess;
|
||||
thDone = true;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
TH_ENTRY_POINT void *Task::doWork_helper(void *ref)
|
||||
{
|
||||
((Task *)ref)->doWork_wrapper();
|
||||
return NULL;
|
||||
{
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
thSuccess = newSuccess;
|
||||
thDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Task::notifyProgress(int progress)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
thProgress = progress;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::notifyStatus(String status)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
thStatus = status;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::notifyError(String error)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
std::lock_guard<std::mutex> g(taskMutex);
|
||||
thError = error;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::notifyProgressMain()
|
||||
|
@@ -2,9 +2,10 @@
|
||||
#define TASK_H_
|
||||
|
||||
#include "common/String.h"
|
||||
#include "common/tpt-thread.h"
|
||||
#include "TaskListener.h"
|
||||
#include "Config.h"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
class TaskListener;
|
||||
class Task {
|
||||
@@ -19,6 +20,7 @@ public:
|
||||
virtual void Poll();
|
||||
Task();
|
||||
virtual ~Task();
|
||||
|
||||
protected:
|
||||
int progress;
|
||||
bool done;
|
||||
@@ -32,16 +34,13 @@ protected:
|
||||
String thStatus;
|
||||
String thError;
|
||||
|
||||
TaskListener * listener;
|
||||
pthread_t doWorkThread;
|
||||
pthread_mutex_t taskMutex;
|
||||
|
||||
TaskListener *listener;
|
||||
std::mutex taskMutex;
|
||||
|
||||
virtual void before();
|
||||
virtual void after();
|
||||
virtual bool doWork();
|
||||
virtual void doWork_wrapper();
|
||||
TH_ENTRY_POINT static void * doWork_helper(void * ref);
|
||||
|
||||
virtual void notifyProgress(int progress);
|
||||
virtual void notifyError(String error);
|
||||
|
Reference in New Issue
Block a user