Changeset View
Changeset View
Standalone View
Standalone View
source/ps/UserReport.cpp
Show All 24 Lines | |||||
#include "lib/external_libraries/libsdl.h" | #include "lib/external_libraries/libsdl.h" | ||||
#include "lib/external_libraries/zlib.h" | #include "lib/external_libraries/zlib.h" | ||||
#include "lib/file/archive/stream.h" | #include "lib/file/archive/stream.h" | ||||
#include "lib/os_path.h" | #include "lib/os_path.h" | ||||
#include "lib/sysdep/sysdep.h" | #include "lib/sysdep/sysdep.h" | ||||
#include "ps/ConfigDB.h" | #include "ps/ConfigDB.h" | ||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||
#include "ps/Profiler2.h" | #include "ps/Profiler2.h" | ||||
#include "ps/ThreadUtil.h" | |||||
#include <fstream> | #include <fstream> | ||||
#include <mutex> | #include <mutex> | ||||
#include <string> | #include <string> | ||||
#include <thread> | |||||
#define DEBUG_UPLOADS 0 | #define DEBUG_UPLOADS 0 | ||||
/* | /* | ||||
* The basic idea is that the game submits reports to us, which we send over | * The basic idea is that the game submits reports to us, which we send over | ||||
* HTTP to a server for storage and analysis. | * HTTP to a server for storage and analysis. | ||||
* | * | ||||
* We can't use libcurl's asynchronous 'multi' API, because DNS resolution can | * We can't use libcurl's asynchronous 'multi' API, because DNS resolution can | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | #endif | ||||
// Set up the worker thread: | // Set up the worker thread: | ||||
// Use SDL semaphores since OS X doesn't implement sem_init | // Use SDL semaphores since OS X doesn't implement sem_init | ||||
m_WorkerSem = SDL_CreateSemaphore(0); | m_WorkerSem = SDL_CreateSemaphore(0); | ||||
ENSURE(m_WorkerSem); | ENSURE(m_WorkerSem); | ||||
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); | m_WorkerThread = std::thread(RunThread, this); | ||||
ENSURE(ret == 0); | |||||
} | } | ||||
~CUserReporterWorker() | ~CUserReporterWorker() | ||||
{ | { | ||||
// Clean up resources | // Clean up resources | ||||
SDL_DestroySemaphore(m_WorkerSem); | SDL_DestroySemaphore(m_WorkerSem); | ||||
Show All 30 Lines | bool Shutdown() | ||||
m_Shutdown = true; | m_Shutdown = true; | ||||
} | } | ||||
// Wake up the worker thread | // Wake up the worker thread | ||||
SDL_SemPost(m_WorkerSem); | SDL_SemPost(m_WorkerSem); | ||||
// Wait for it to shut down cleanly | // Wait for it to shut down cleanly | ||||
// TODO: should have a timeout in case of network hangs | // TODO: should have a timeout in case of network hangs | ||||
pthread_join(m_WorkerThread, NULL); | m_WorkerThread.join(); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Called by main thread to determine the current status of the uploader. | * Called by main thread to determine the current status of the uploader. | ||||
*/ | */ | ||||
std::string GetStatus() | std::string GetStatus() | ||||
Show All 28 Lines | if (now > m_LastUpdateTime + TIMER_CHECK_INTERVAL) | ||||
// Wake up the worker thread | // Wake up the worker thread | ||||
SDL_SemPost(m_WorkerSem); | SDL_SemPost(m_WorkerSem); | ||||
m_LastUpdateTime = now; | m_LastUpdateTime = now; | ||||
} | } | ||||
} | } | ||||
private: | private: | ||||
static void* RunThread(void* data) | static void RunThread(CUserReporterWorker* data) | ||||
{ | { | ||||
debug_SetThreadName("CUserReportWorker"); | debug_SetThreadName("CUserReportWorker"); | ||||
g_Profiler2.RegisterCurrentThread("userreport"); | g_Profiler2.RegisterCurrentThread("userreport"); | ||||
static_cast<CUserReporterWorker*>(data)->Run(); | data->Run(); | ||||
return NULL; | |||||
} | } | ||||
void Run() | void Run() | ||||
{ | { | ||||
// Set libcurl's proxy configuration | // Set libcurl's proxy configuration | ||||
// (This has to be done in the thread because it's potentially very slow) | // (This has to be done in the thread because it's potentially very slow) | ||||
SetStatus("proxy"); | SetStatus("proxy"); | ||||
std::wstring proxy; | std::wstring proxy; | ||||
▲ Show 20 Lines • Show All 229 Lines • ▼ Show 20 Lines | static size_t SendCallback(char* bufptr, size_t size, size_t nmemb, void* userp) | ||||
self->SetStatus("sending:" + CStr::FromDouble((double)self->m_RequestDataOffset / self->m_RequestData.size())); | self->SetStatus("sending:" + CStr::FromDouble((double)self->m_RequestDataOffset / self->m_RequestData.size())); | ||||
return amount; | return amount; | ||||
} | } | ||||
private: | private: | ||||
// Thread-related members: | // Thread-related members: | ||||
pthread_t m_WorkerThread; | std::thread m_WorkerThread; | ||||
std::mutex m_WorkerMutex; | std::mutex m_WorkerMutex; | ||||
SDL_sem* m_WorkerSem; | SDL_sem* m_WorkerSem; | ||||
// Shared by main thread and worker thread: | // Shared by main thread and worker thread: | ||||
// These variables are all protected by m_WorkerMutex | // These variables are all protected by m_WorkerMutex | ||||
std::deque<shared_ptr<CUserReport> > m_ReportQueue; | std::deque<shared_ptr<CUserReport> > m_ReportQueue; | ||||
bool m_Enabled; | bool m_Enabled; | ||||
bool m_Shutdown; | bool m_Shutdown; | ||||
▲ Show 20 Lines • Show All 152 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator