Jump to content

engine->runWorldFunction


photo

Recommended Posts

struct padSendData
{
int buttonPushedID;
int controlMoveState;
int controlTurnState;
};
 

Repeat the call

engine->runWorldFunction(Unigine::Variable("setPadControl"),Unigine::Variable(padp->buttonPushedID),Unigine::Variable(padp->controlMoveState),

Unigine::Variable(padp->controlTurnState));

 

10:19:54 Interpreter::runWaits(): depth of stack is not zero
 
10:19:54 World::update(): world update function return 0
 
 
 
10:22:51 D:\BuildAgent\work\cd5ab32b6eb0bda3\Unigine\source\engine\EngineInterpreter.h:74: Assertion: 'depth > 0 && "EngineInterpreterInstance::end(): stack underflow"'
 
10:23:26 Shutdown
 
 
How to solve this problem?
 

 

 

 

Link to comment
 Engine *engine;

 

void runReceiveThread(void* lpparam)

{

while(true)

{

Sleep(10);

engine->runWorldFunction(Unigine::Variable("Test"),Unigine::Variable(1),Unigine::Variable(2),Unigine::Variable(3));

}

}

 

int main(int argc,char **argv) {

 

engine = Engine::init(UNIGINE_VERSION,argc,argv);

_beginthread(runReceiveThread,0,0);

 

 // enter the main loop 

while(engine->isDone() == 0)

{  

engine->update();

engine->render();

engine->swap();

}

Engine::shutdown();

 

return 0;

}

Link to comment

Hi,

 

 

_beginthread(runReceiveThread,0,0);

 

 

This is the root cause. You're accessing *engine object from a separate thread. That is currently unsafe in multiple ways.

 

First, engine is not yet exactly thread-safe in general. That is, attempting to use it concurrently from different threads might cause pretty much any kind of unexpected behavior: crashes, freezes, data corruption, you name it.

 

Second, the runWorldFunction() specifically is definitely not thread-safe. We might be able to fix this particular function as soon as the upcoming 2.2 release. (We can't guarantee that timeline though; there's some more analysis and testing to be done.)

 

Third, and more importantly, even merely accessing the *engine object in this way is not thread-safe. Assume your thread wakes up while the engine is reinitialized, or being shut down, so that the *engine object is no longer valid, even though the pointer is still valid. Crash, boom, bang.

 

At the very least, you should add a flag that the engine pointer is still alive. Or better yet, at least in versions 2.1 and before, you could protect all the engine accesses with a mutex, as follows:

MyMutex g_engine_mutex;

void MyThreadFunc()
{
	g_engine_mutex.lock();
	if (engine)
		engine->doThings(...);
	g_engine_mutex.unlock();
}

void main()
{
	...
	// enter the main loop 
	while(engine->isDone() == 0)
	{  
		g_engine_mutex.lock();
		engine->update();
		g_engine_mutex.unlock();

		g_engine_mutex.lock();
		engine->render();
		g_engine_mutex.unlock();

		g_engine_mutex.lock();
		engine->swap();
		g_engine_mutex.unlock();
	}

	g_engine_mutex.lock();
	Engine::shutdown();
	...
}

Link to comment
×
×
  • Create New...