issue #2305: Using std::thread instead of pthread for ScriptingCore.

This commit is contained in:
James Chen 2013-06-26 14:41:19 +08:00
parent 456f422c8a
commit adf6932543
1 changed files with 30 additions and 40 deletions

View File

@ -28,7 +28,8 @@
#include <unistd.h>
#include <netdb.h>
#endif
#include <pthread.h>
#include <thread>
#ifdef ANDROID
#include <android/log.h>
@ -53,18 +54,17 @@
#define BYTE_CODE_FILE_EXT ".jsc"
static pthread_t debugThread;
static string inData;
static string outData;
static vector<string> g_queue;
static pthread_mutex_t g_qMutex;
static pthread_mutex_t g_rwMutex;
static std::mutex g_qMutex;
static std::mutex g_rwMutex;
static bool vmLock = false;
static jsval frame = JSVAL_NULL, script = JSVAL_NULL;
static int clientSocket = -1;
// server entry point for the bg thread
void* serverEntryPoint(void*);
static void serverEntryPoint(void);
js_proxy_t *_native_js_global_ht = NULL;
js_proxy_t *_js_native_global_ht = NULL;
@ -1713,14 +1713,14 @@ jsval ccaffinetransform_to_jsval(JSContext* cx, AffineTransform& t)
#pragma mark - Debug
void SimpleRunLoop::update(float dt) {
pthread_mutex_lock(&g_qMutex);
std::lock_guard<std::mutex> lk(g_qMutex);
while (g_queue.size() > 0) {
vector<string>::iterator first = g_queue.begin();
string str = *first;
ScriptingCore::getInstance()->debugProcessInput(str);
g_queue.erase(first);
}
pthread_mutex_unlock(&g_qMutex);
}
void ScriptingCore::debugProcessInput(string str) {
@ -1759,7 +1759,9 @@ void ScriptingCore::enableDebugger() {
// define the start debugger function
JS_DefineFunction(cx_, global_, "startDebugger", JSBDebug_StartDebugger, 3, JSPROP_READONLY | JSPROP_PERMANENT);
// start bg thread
pthread_create(&debugThread, NULL, serverEntryPoint, NULL);
auto t = std::thread(&serverEntryPoint);
t.detach();
Scheduler* scheduler = Director::sharedDirector()->getScheduler();
scheduler->scheduleUpdateForTarget(this->runLoop, 0, false);
@ -1887,12 +1889,12 @@ JSBool JSBDebug_BufferRead(JSContext* cx, unsigned argc, jsval* vp)
JSString* str;
// this is safe because we're already inside a lock (from clearBuffers)
if (vmLock) {
pthread_mutex_lock(&g_rwMutex);
g_rwMutex.lock();
}
str = JS_NewStringCopyZ(cx, inData.c_str());
inData.clear();
if (vmLock) {
pthread_mutex_unlock(&g_rwMutex);
g_rwMutex.unlock();
}
JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
} else {
@ -1932,14 +1934,14 @@ JSBool JSBDebug_LockExecution(JSContext* cx, unsigned argc, jsval* vp)
vmLock = true;
while (vmLock) {
// try to read the input, if there's anything
pthread_mutex_lock(&g_qMutex);
g_qMutex.lock();
while (g_queue.size() > 0) {
vector<string>::iterator first = g_queue.begin();
string str = *first;
ScriptingCore::getInstance()->debugProcessInput(str);
g_queue.erase(first);
}
pthread_mutex_unlock(&g_qMutex);
g_qMutex.unlock();
sched_yield();
}
printf("vm unlocked\n");
@ -1957,32 +1959,25 @@ JSBool JSBDebug_UnlockExecution(JSContext* cx, unsigned argc, jsval* vp)
return JS_TRUE;
}
void processInput(string data) {
pthread_mutex_lock(&g_qMutex);
static void processInput(string data) {
std::lock_guard<std::mutex> lk(g_qMutex);
g_queue.push_back(string(data));
pthread_mutex_unlock(&g_qMutex);
}
void clearBuffers() {
pthread_mutex_lock(&g_rwMutex);
{
// only process input if there's something and we're not locked
if (inData.length() > 0) {
processInput(inData);
inData.clear();
}
if (outData.length() > 0) {
_clientSocketWriteAndClearString(outData);
}
static void clearBuffers() {
std::lock_guard<std::mutex> lk(g_rwMutex);
// only process input if there's something and we're not locked
if (inData.length() > 0) {
processInput(inData);
inData.clear();
}
if (outData.length() > 0) {
_clientSocketWriteAndClearString(outData);
}
pthread_mutex_unlock(&g_rwMutex);
}
void* serverEntryPoint(void*)
static void serverEntryPoint(void)
{
// init the mutex
assert(pthread_mutex_init(&g_rwMutex, NULL) == 0);
assert(pthread_mutex_init(&g_qMutex, NULL) == 0);
// start a server, accept the connection and keep reading data from it
struct addrinfo hints, *result, *rp;
int s;
@ -2007,14 +2002,14 @@ void* serverEntryPoint(void*)
if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval))) < 0) {
close(s);
TRACE_DEBUGGER_SERVER("debug server : error setting socket option SO_REUSEADDR");
return NULL;
return;
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
if ((setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval))) < 0) {
close(s);
TRACE_DEBUGGER_SERVER("debug server : error setting socket option SO_NOSIGPIPE");
return NULL;
return;
}
#endif //(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
@ -2026,7 +2021,7 @@ void* serverEntryPoint(void*)
}
if (s < 0 || rp == NULL) {
TRACE_DEBUGGER_SERVER("debug server : error creating/binding socket");
return NULL;
return;
}
freeaddrinfo(result);
@ -2038,7 +2033,7 @@ void* serverEntryPoint(void*)
if (clientSocket < 0)
{
TRACE_DEBUGGER_SERVER("debug server : error on accept");
return NULL;
return;
} else {
// read/write data
TRACE_DEBUGGER_SERVER("debug server : client connected");
@ -2055,11 +2050,6 @@ void* serverEntryPoint(void*)
close(clientSocket);
}
} // while(true)
// we're done, destroy the mutex
pthread_mutex_destroy(&g_rwMutex);
pthread_mutex_destroy(&g_qMutex);
return NULL;
}
ccColor3B getColorFromJSObject(JSContext *cx, JSObject *colorObject)