Skip to content

Commit

Permalink
修复Android平台下多线程崩溃问题
Browse files Browse the repository at this point in the history
  • Loading branch information
vimfung committed Apr 16, 2019
1 parent e14e2ae commit f0d999f
Show file tree
Hide file tree
Showing 16 changed files with 245 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class LuaJavaExportTypeDescriptor : public LuaExportTypeDescriptor
/**
* 释放对象
*/
~LuaJavaExportTypeDescriptor();
virtual ~LuaJavaExportTypeDescriptor();

/**
* 获取Java类型
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ JNIEXPORT void JNICALL Java_cn_vimfung_luascriptcore_LuaNativeUtil_runThread(JNI

LuaScriptController *scriptController = LuaJavaConverter::convertToScriptControllerByJScriptController(env, jscriptController);

context -> runThread(value -> toFunction(), &argumentList, scriptController);
context -> runThread(value -> toFunction(), argumentList, scriptController);

//释放参数内存
for (LuaArgumentList::iterator it = argumentList.begin(); it != argumentList.end() ; ++it)
Expand Down
148 changes: 41 additions & 107 deletions Source/lua-common/LuaContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#endif

#include "LuaError.h"
#include "LuaScriptController.h"

using namespace cn::vimfung::luascriptcore;

Expand All @@ -57,86 +58,6 @@ static void _raiseLuaException(lua_State *state, void *ud)
LuaEngineAdapter::error(state, msg);
}

/**
* 线程处理器
* @param context 上下文对象
* @param handler 线程处理器
* @param arguments 参数列表
* @param scriptController 脚本控制器
*/
static void threadHandler(LuaCoroutine *coroutine, LuaFunction *handler, LuaArgumentList *arguments, LuaScriptController *scriptController)
{
lua_State *state = coroutine -> getState();

//设置脚本执行配置
coroutine->setScriptController(scriptController);

//获取捕获错误方法索引
int errFuncIndex = 0;
LuaEngineAdapter::getGlobal(state, CatchLuaExceptionHandlerName);
if (LuaEngineAdapter::isFunction(state, -1))
{
errFuncIndex = LuaEngineAdapter::getTop(state);
}
else
{
LuaEngineAdapter::pop(state, 1);
}

int top = LuaEngineAdapter::getTop(state);
coroutine -> getContext() -> getDataExchanger() -> getLuaObject(handler, state, NULL);

if (LuaEngineAdapter::isFunction(state, -1))
{

int returnCount = 0;

for (LuaArgumentList::iterator i = arguments -> begin(); i != arguments -> end() ; ++i)
{
LuaValue *item = *i;
coroutine -> getContext() -> getDataExchanger() -> pushStack(item);
}

if (LuaEngineAdapter::pCall(state, (int)arguments -> size(), LUA_MULTRET, errFuncIndex) == LUA_OK)
{
returnCount = LuaEngineAdapter::getTop(state) - top;
}
else
{
//调用失败
returnCount = LuaEngineAdapter::getTop(state) - top;
}

//弹出返回值
LuaEngineAdapter::pop(state, returnCount);
}
else
{
//弹出func
LuaEngineAdapter::pop(state, 1);
}

//移除异常捕获方法
LuaEngineAdapter::remove(state, errFuncIndex);

//释放参数
for (LuaArgumentList::iterator i = arguments -> begin(); i != arguments -> end() ; ++i)
{
LuaValue *item = *i;
item -> release();
}
delete arguments;

//释放内存
coroutine -> getContext() -> gc();

//取消设置脚本执行配置
coroutine -> setScriptController(NULL);

//释放协程
coroutine -> release();
}

/**
* 方法路由处理器
*
Expand Down Expand Up @@ -317,7 +238,7 @@ LuaContext::LuaContext(std::string const& platform)

});

_currentSession = NULL;
// _currentSession = NULL;

//初始化类型导出管理器
_exportsTypeManager = new LuaExportsTypeManager(this, platform);
Expand Down Expand Up @@ -350,36 +271,60 @@ LuaSession* LuaContext::getMainSession()

LuaSession* LuaContext::getCurrentSession()
{
if (_currentSession != NULL)
std::thread::id tid = std::this_thread::get_id();

LuaSessionMap::iterator it = _sessionMap.find(tid);
if (it != _sessionMap.end())
{
return _currentSession;
return it -> second;
}

return _mainSession;
}

LuaSession* LuaContext::makeSession(lua_State *state, bool lightweight)
{

std::thread::id tid = std::this_thread::get_id();

LuaSession *session = new LuaSession(state, this, lightweight);
session -> prevSession = _currentSession;
_currentSession = session;

LuaSessionMap::iterator it = _sessionMap.find(tid);
if (it != _sessionMap.end())
{
session -> prevSession = it -> second;
}

_sessionMap[tid] = session;

return getCurrentSession();
}

void LuaContext::destorySession(LuaSession *session)
{
raiseException(session -> getLastError());
session -> clearError();
std::thread::id tid = std::this_thread::get_id();

if (_currentSession == session)
raiseException(session->getLastError());
session->clearError();

LuaSessionMap::iterator it = _sessionMap.find(tid);
if (it != _sessionMap.end() && it -> second == session)
{
_currentSession = _currentSession -> prevSession;
LuaSession *prevSession = it -> second -> prevSession;
if (prevSession != NULL)
{
_sessionMap[tid] = prevSession;
}
else
{
_sessionMap.erase(tid);
}

}

if (_mainSession != session)
{
session -> release();
session->release();
}
}

Expand Down Expand Up @@ -633,12 +578,12 @@ LuaValue* LuaContext::evalScriptFromFile(std::string const& path, LuaScriptContr
retValue = LuaValue::NilValue();
}

//释放内存
gc();

//取消脚本执行配置
session -> setScriptController(NULL);

//释放内存
gc();

});

return retValue;
Expand Down Expand Up @@ -751,27 +696,16 @@ void LuaContext::registerMethod(std::string const& methodName, LuaMethodHandler
}
}

void LuaContext::runThread(LuaFunction *handler, LuaArgumentList *arguments)
void LuaContext::runThread(LuaFunction *handler, LuaArgumentList arguments)
{
LuaContext::runThread(handler, arguments, NULL);
}

void LuaContext::runThread(LuaFunction *handler, LuaArgumentList *arguments, LuaScriptController *scriptController)
void LuaContext::runThread(LuaFunction *handler, LuaArgumentList arguments, LuaScriptController *scriptController)
{
//创建协程
LuaCoroutine *coroutine = new LuaCoroutine(this);

//赋值参数列表
LuaArgumentList *args = new LuaArgumentList();
for (LuaArgumentList::iterator i = arguments -> begin(); i != arguments -> end() ; ++i)
{
LuaValue *item = *i;
item -> retain();
args -> push_back(item);
}

std::thread t(&threadHandler, coroutine, handler, args, scriptController);
t.detach();
coroutine -> run(handler, arguments, scriptController);
}

LuaMethodHandler LuaContext::getMethodHandler(std::string const& methodName)
Expand Down
13 changes: 9 additions & 4 deletions Source/lua-common/LuaContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,15 @@ namespace cn
*/
LuaSession *_mainSession;

/**
* 会话映射表,用于记录各个线程的会话链
*/
LuaSessionMap _sessionMap;

/**
* 当前会话对象
*/
LuaSession *_currentSession;
// LuaSession *_currentSession;

/**
导出类型管理器
Expand Down Expand Up @@ -95,7 +100,7 @@ namespace cn
/**
* 销毁上下文对象
*/
~LuaContext();
virtual ~LuaContext();

private:

Expand Down Expand Up @@ -252,15 +257,15 @@ namespace cn
* @param handler 线程处理器
* @param arguments 参数列表
*/
void runThread(LuaFunction *handler, LuaArgumentList *arguments);
void runThread(LuaFunction *handler, LuaArgumentList arguments);

/**
* 执行线程
* @param handler 线程处理器
* @param arguments 参数列表
* @param scriptController 脚本控制器
*/
void runThread(LuaFunction *handler, LuaArgumentList *arguments, LuaScriptController *scriptController);
void runThread(LuaFunction *handler, LuaArgumentList arguments, LuaScriptController *scriptController);

public:

Expand Down
Loading

0 comments on commit f0d999f

Please sign in to comment.