Simple thread PAL type (until core/ is rewritten).
This commit is contained in:
parent
88431eadce
commit
da23c00d31
|
@ -18,5 +18,6 @@
|
|||
#include <xenia/core/mutex.h>
|
||||
#include <xenia/core/pal.h>
|
||||
#include <xenia/core/ref.h>
|
||||
#include <xenia/core/thread.h>
|
||||
|
||||
#endif // XENIA_CORE_H_
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
'pal.h',
|
||||
'ref.cc',
|
||||
'ref.h',
|
||||
'thread.cc',
|
||||
'thread.h',
|
||||
],
|
||||
|
||||
'conditions': [
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/thread.h>
|
||||
|
||||
|
||||
typedef struct xe_thread {
|
||||
xe_ref_t ref;
|
||||
|
||||
char* name;
|
||||
|
||||
xe_thread_callback callback;
|
||||
void* callback_param;
|
||||
|
||||
void* handle;
|
||||
} xe_thread_t;
|
||||
|
||||
|
||||
|
||||
xe_thread_ref xe_thread_create(
|
||||
xe_pal_ref pal, const char* name, xe_thread_callback callback,
|
||||
void* param) {
|
||||
xe_thread_ref thread = (xe_thread_ref)xe_calloc(sizeof(xe_thread_t));
|
||||
xe_ref_init((xe_ref)thread);
|
||||
|
||||
thread->name = xestrdupa(name);
|
||||
thread->callback = callback;
|
||||
thread->callback_param = param;
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
void xe_thread_dealloc(xe_thread_ref thread) {
|
||||
thread->handle = NULL;
|
||||
xe_free(thread->name);
|
||||
}
|
||||
|
||||
xe_thread_ref xe_thread_retain(xe_thread_ref thread) {
|
||||
xe_ref_retain((xe_ref)thread);
|
||||
return thread;
|
||||
}
|
||||
|
||||
void xe_thread_release(xe_thread_ref thread) {
|
||||
xe_ref_release((xe_ref)thread, (xe_ref_dealloc_t)xe_thread_dealloc);
|
||||
}
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
||||
#pragma pack(push,8)
|
||||
typedef struct tagTHREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma warning(disable : 6320; disable : 6322)
|
||||
static uint32_t __stdcall xe_thread_callback_win32(void* param) {
|
||||
xe_thread_t* thread = reinterpret_cast<xe_thread_t*>(param);
|
||||
|
||||
if (IsDebuggerPresent()) {
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = thread->name;
|
||||
info.dwThreadID = (DWORD)-1;
|
||||
info.dwFlags = 0;
|
||||
__try {
|
||||
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR),
|
||||
(ULONG_PTR*)&info);
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
}
|
||||
}
|
||||
|
||||
thread->callback(thread->callback_param);
|
||||
return 0;
|
||||
}
|
||||
#pragma warning(default : 6320; default : 6322)
|
||||
|
||||
int xe_thread_start(xe_thread_ref thread) {
|
||||
HANDLE thread_handle = CreateThread(
|
||||
NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)xe_thread_callback_win32,
|
||||
thread,
|
||||
0,
|
||||
NULL);
|
||||
if (!handle) {
|
||||
uint32_t last_error = GetLastError();
|
||||
// TODO(benvanik): translate?
|
||||
XELOGE(XT("CreateThread failed with %d"), last_error);
|
||||
return last_error;
|
||||
}
|
||||
|
||||
thread->handle = reinterpret_cast<void*>(thread_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void* xe_thread_callback_pthreads(void* param) {
|
||||
xe_thread_t* thread = reinterpret_cast<xe_thread_t*>(param);
|
||||
XEIGNORE(pthread_setname_np(thread->name));
|
||||
thread->callback(thread->callback_param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xe_thread_start(xe_thread_ref thread) {
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_t thread_handle;
|
||||
int result_code = pthread_create(
|
||||
&thread_handle,
|
||||
&attr,
|
||||
&xe_thread_callback_pthreads,
|
||||
thread);
|
||||
pthread_attr_destroy(&attr);
|
||||
if (result_code) {
|
||||
return result_code;
|
||||
}
|
||||
|
||||
thread->handle = reinterpret_cast<void*>(thread_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_THREAD_H_
|
||||
#define XENIA_CORE_THREAD_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core/pal.h>
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
struct xe_thread;
|
||||
typedef struct xe_thread* xe_thread_ref;
|
||||
|
||||
|
||||
typedef void (*xe_thread_callback)(void* param);
|
||||
|
||||
|
||||
xe_thread_ref xe_thread_create(
|
||||
xe_pal_ref pal, const char* name, xe_thread_callback callback, void* param);
|
||||
xe_thread_ref xe_thread_retain(xe_thread_ref thread);
|
||||
void xe_thread_release(xe_thread_ref thread);
|
||||
|
||||
int xe_thread_start(xe_thread_ref thread);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_THREAD_H_
|
|
@ -48,6 +48,10 @@ Debugger::~Debugger() {
|
|||
xe_pal_release(pal_);
|
||||
}
|
||||
|
||||
xe_pal_ref Debugger::pal() {
|
||||
return xe_pal_retain(pal_);
|
||||
}
|
||||
|
||||
void Debugger::RegisterContentSource(ContentSource* content_source) {
|
||||
content_sources_.insert(std::pair<uint32_t, ContentSource*>(
|
||||
content_source->source_id(), content_source));
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
Debugger(xe_pal_ref pal);
|
||||
virtual ~Debugger();
|
||||
|
||||
xe_pal_ref pal();
|
||||
|
||||
void RegisterContentSource(ContentSource* content_source);
|
||||
|
||||
int Startup();
|
||||
|
|
|
@ -30,6 +30,7 @@ using namespace xe::dbg;
|
|||
|
||||
WsClient::WsClient(Debugger* debugger, int socket_id) :
|
||||
Client(debugger),
|
||||
thread_(NULL),
|
||||
socket_id_(socket_id) {
|
||||
mutex_ = xe_mutex_alloc(1000);
|
||||
|
||||
|
@ -49,6 +50,8 @@ WsClient::~WsClient() {
|
|||
xe_mutex_unlock(mutex);
|
||||
xe_mutex_free(mutex);
|
||||
|
||||
xe_thread_release(thread_);
|
||||
|
||||
close(notify_rd_id_);
|
||||
close(notify_wr_id_);
|
||||
}
|
||||
|
@ -67,25 +70,16 @@ int WsClient::Setup() {
|
|||
setsockopt(socket_id_, IPPROTO_TCP, TCP_NODELAY,
|
||||
&opt_value, sizeof(opt_value));
|
||||
|
||||
// TODO(benvanik): win32 support - put simple threads in PAL
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_t thread_handle;
|
||||
int result_code = pthread_create(
|
||||
&thread_handle,
|
||||
&attr,
|
||||
&StartCallbackPthreads,
|
||||
this);
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return result_code;
|
||||
xe_pal_ref pal = debugger_->pal();
|
||||
thread_ = xe_thread_create(pal, "Debugger Client",
|
||||
StartCallback, this);
|
||||
xe_pal_release(pal);
|
||||
return xe_thread_start(thread_);
|
||||
}
|
||||
|
||||
void* WsClient::StartCallbackPthreads(void* param) {
|
||||
WsClient* thread = reinterpret_cast<WsClient*>(param);
|
||||
thread->EventThread();
|
||||
return 0;
|
||||
void WsClient::StartCallback(void* param) {
|
||||
WsClient* client = reinterpret_cast<WsClient*>(param);
|
||||
client->EventThread();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -37,11 +37,13 @@ public:
|
|||
virtual void Write(uint8_t** buffers, size_t* lengths, size_t count);
|
||||
|
||||
private:
|
||||
static void* StartCallbackPthreads(void* param);
|
||||
static void StartCallback(void* param);
|
||||
|
||||
int PerformHandshake();
|
||||
void EventThread();
|
||||
|
||||
xe_thread_ref thread_;
|
||||
|
||||
int socket_id_;
|
||||
|
||||
int notify_rd_id_;
|
||||
|
|
Loading…
Reference in New Issue