@@ -59,8 +59,8 @@ static string outData;
5959static vector<string> g_queue;
6060static std::mutex g_qMutex;
6161static std::mutex g_rwMutex;
62- static bool vmLock = false ;
6362static int clientSocket = -1 ;
63+ static unsigned long s_nestedLoopLevel = 0 ;
6464
6565// server entry point for the bg thread
6666static void serverEntryPoint (void );
@@ -1937,14 +1937,22 @@ jsval FontDefinition_to_jsval(JSContext* cx, const FontDefinition& t)
19371937
19381938#pragma mark - Debug
19391939
1940- void SimpleRunLoop::update (float dt) {
1941- std::lock_guard<std::mutex> lk (g_qMutex);
1942-
1943- while (g_queue.size () > 0 ) {
1940+ void SimpleRunLoop::update (float dt)
1941+ {
1942+ g_qMutex.lock ();
1943+ size_t size = g_queue.size ();
1944+ g_qMutex.unlock ();
1945+
1946+ while (size > 0 )
1947+ {
1948+ g_qMutex.lock ();
19441949 vector<string>::iterator first = g_queue.begin ();
19451950 string str = *first;
1946- ScriptingCore::getInstance ()->debugProcessInput (str);
19471951 g_queue.erase (first);
1952+ size = g_queue.size ();
1953+ g_qMutex.unlock ();
1954+
1955+ ScriptingCore::getInstance ()->debugProcessInput (str);
19481956 }
19491957}
19501958
@@ -1960,6 +1968,73 @@ void ScriptingCore::debugProcessInput(string str) {
19601968 JS_CallFunctionName (cx_, debugGlobal_, " processInput" , 1 , argv, &outval);
19611969}
19621970
1971+ static bool NS_ProcessNextEvent ()
1972+ {
1973+ g_qMutex.lock ();
1974+ size_t size = g_queue.size ();
1975+ g_qMutex.unlock ();
1976+
1977+ while (size > 0 )
1978+ {
1979+ g_qMutex.lock ();
1980+ vector<string>::iterator first = g_queue.begin ();
1981+ string str = *first;
1982+ g_queue.erase (first);
1983+ size = g_queue.size ();
1984+ g_qMutex.unlock ();
1985+
1986+ ScriptingCore::getInstance ()->debugProcessInput (str);
1987+ }
1988+ // std::this_thread::yield();
1989+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
1990+
1991+ return true ;
1992+ }
1993+
1994+ JSBool JSBDebug_enterNestedEventLoop (JSContext* cx, unsigned argc, jsval* vp)
1995+ {
1996+ enum {
1997+ NS_OK = 0 ,
1998+ NS_ERROR_UNEXPECTED
1999+ };
2000+
2001+ #define NS_SUCCEEDED (v ) ((v) == NS_OK)
2002+
2003+ int rv = NS_OK;
2004+
2005+ uint32_t nestLevel = ++s_nestedLoopLevel;
2006+
2007+ while (NS_SUCCEEDED(rv) && s_nestedLoopLevel >= nestLevel) {
2008+ if (!NS_ProcessNextEvent())
2009+ rv = NS_ERROR_UNEXPECTED;
2010+ }
2011+
2012+ CCASSERT (s_nestedLoopLevel <= nestLevel,
2013+ " nested event didn't unwind properly" );
2014+
2015+ JS_SET_RVAL (cx, vp, UINT_TO_JSVAL (s_nestedLoopLevel));
2016+ return JS_TRUE;
2017+ }
2018+
2019+ JSBool JSBDebug_exitNestedEventLoop (JSContext* cx, unsigned argc, jsval* vp)
2020+ {
2021+ if (s_nestedLoopLevel > 0 ) {
2022+ --s_nestedLoopLevel;
2023+ } else {
2024+ JS_SET_RVAL (cx, vp, UINT_TO_JSVAL (0 ));
2025+ return JS_TRUE;
2026+ }
2027+
2028+ JS_SET_RVAL (cx, vp, UINT_TO_JSVAL (s_nestedLoopLevel));
2029+ return JS_TRUE;
2030+ }
2031+
2032+ JSBool JSBDebug_getEventLoopNestLevel (JSContext* cx, unsigned argc, jsval* vp)
2033+ {
2034+ JS_SET_RVAL (cx, vp, UINT_TO_JSVAL (s_nestedLoopLevel));
2035+ return JS_TRUE;
2036+ }
2037+
19632038void ScriptingCore::enableDebugger () {
19642039 if (debugGlobal_ == NULL ) {
19652040 JSAutoCompartment ac0 (cx_, global_);
@@ -1970,8 +2045,9 @@ void ScriptingCore::enableDebugger() {
19702045 JS_DefineFunction (cx_, debugGlobal_, " log" , ScriptingCore::log, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
19712046 JS_DefineFunction (cx_, debugGlobal_, " _bufferWrite" , JSBDebug_BufferWrite, 1 , JSPROP_READONLY | JSPROP_PERMANENT);
19722047 JS_DefineFunction (cx_, debugGlobal_, " _bufferRead" , JSBDebug_BufferRead, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
1973- JS_DefineFunction (cx_, debugGlobal_, " _lockVM" , JSBDebug_LockExecution, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
1974- JS_DefineFunction (cx_, debugGlobal_, " _unlockVM" , JSBDebug_UnlockExecution, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
2048+ JS_DefineFunction (cx_, debugGlobal_, " _enterNestedEventLoop" , JSBDebug_enterNestedEventLoop, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
2049+ JS_DefineFunction (cx_, debugGlobal_, " _exitNestedEventLoop" , JSBDebug_exitNestedEventLoop, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
2050+ JS_DefineFunction (cx_, debugGlobal_, " _getEventLoopNestLevel" , JSBDebug_getEventLoopNestLevel, 0 , JSPROP_READONLY | JSPROP_PERMANENT);
19752051
19762052
19772053 runScript (" jsb_debugger.js" , debugGlobal_);
@@ -2124,21 +2200,21 @@ JSBool JSBDebug_StartDebugger(JSContext* cx, unsigned argc, jsval* vp)
21242200
21252201JSBool JSBDebug_BufferRead (JSContext* cx, unsigned argc, jsval* vp)
21262202{
2127- if (argc == 0 ) {
2128- JSString* str;
2129- // this is safe because we're already inside a lock (from clearBuffers)
2130- if (vmLock) {
2131- g_rwMutex.lock ();
2132- }
2133- str = JS_NewStringCopyZ (cx, inData.c_str ());
2134- inData.clear ();
2135- if (vmLock) {
2136- g_rwMutex.unlock ();
2137- }
2138- JS_SET_RVAL (cx, vp, STRING_TO_JSVAL (str));
2139- } else {
2140- JS_SET_RVAL (cx, vp, JSVAL_NULL);
2141- }
2203+ // if (argc == 0) {
2204+ // JSString* str;
2205+ // // this is safe because we're already inside a lock (from clearBuffers)
2206+ // if (vmLock) {
2207+ // g_rwMutex.lock();
2208+ // }
2209+ // str = JS_NewStringCopyZ(cx, inData.c_str());
2210+ // inData.clear();
2211+ // if (vmLock) {
2212+ // g_rwMutex.unlock();
2213+ // }
2214+ // JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
2215+ // } else {
2216+ // JS_SET_RVAL(cx, vp, JSVAL_NULL);
2217+ // }
21422218 return JS_TRUE;
21432219}
21442220
@@ -2160,47 +2236,9 @@ JSBool JSBDebug_BufferWrite(JSContext* cx, unsigned argc, jsval* vp)
21602236 return JS_TRUE;
21612237}
21622238
2163- // this should lock the execution of the running thread, waiting for a signal
2164- JSBool JSBDebug_LockExecution (JSContext* cx, unsigned argc, jsval* vp)
2165- {
2166- if (argc == 0 )
2167- {
2168- if (vmLock)
2169- {
2170- CCLOG (" %s" , " vm has been locked." );
2171- return JS_TRUE;
2172- }
2173- CCLOG (" %s" ," locking vm\n " );
2174- vmLock = true ;
2175- while (vmLock) {
2176- // try to read the input, if there's anything
2177- g_qMutex.lock ();
2178- while (g_queue.size () > 0 ) {
2179- vector<string>::iterator first = g_queue.begin ();
2180- string str = *first;
2181- ScriptingCore::getInstance ()->debugProcessInput (str);
2182- g_queue.erase (first);
2183- }
2184- g_qMutex.unlock ();
2185- std::this_thread::yield ();
2186- }
2187- CCLOG (" %s" ," vm unlocked\n " );
2188-
2189- return JS_TRUE;
2190- }
2191- JS_ReportError (cx, " invalid call to _lockVM" );
2192- return JS_FALSE;
2193- }
2194-
2195- JSBool JSBDebug_UnlockExecution (JSContext* cx, unsigned argc, jsval* vp)
2196- {
2197- vmLock = false ;
2198- return JS_TRUE;
2199- }
2200-
22012239static void processInput (string data) {
22022240 std::lock_guard<std::mutex> lk (g_qMutex);
2203- g_queue.push_back (string ( data) );
2241+ g_queue.push_back (data);
22042242}
22052243
22062244static void clearBuffers () {
0 commit comments