Thread safety in cocos2d-x

I am making a game that performs a numerical integration for a physics simulation. Being that this is numerical and not analytical, each time step in the simulation needs to be as small as possible to get better precision. I have it working with the time step being each update() call, but I was hoping to make it smaller by having the simulation run on a thread.

I have heard that cocos2d-x is not thread-safe. What exactly is it not thread-safe for? If I wanted to get and update the positions of nodes in the simulation via the thread, will and which locks work, and what kind of thread should I use?

Thanks!

You can use standard c++11 std::thread if you want or any other of the constructs available. The latest Cocos2d-x runs the rendering on one thread, but does support multi-threading and handles a thread pool for loading audio and other resources. As long as you protect the code you add to support running custom simulation code in another thread you should be fine.

If anyone wants to correct me, please do so.

Note any code that updates any visible cocos2d-x component (change Label, change sprite etc) needs to execute in CocosThread.

You can use the follow code to achieve that.

cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread([=](){
}
6 Likes

I have a question, Does internal Physics also runs its logic on main thread( i don’t know never been so deep into engine code), if yes then is it possible to run physics simulation on other thread and synchronize components using above method. Whats the catch in doing this.

OpenGL context is not thread-safe, you can’t call retain(), release(), or create/ addChild() new Node type(which uses GLContext).

yes its possible but i haven’t tried it. Here are some good read about this topic, this should get you started.
http://www.cocos2d-x.org/wiki/How_to_use_pthread


http://www.cocos2d-x.org/wiki/How_to_use_pthread

How crucial is using performFunctionInCocosThread ? I had it running fine with the thread I created setting the position, but I implemented the performFunctionInCocosThread and it is acting funny. If I debug this, will it solve the problem of collision detection not working properly (it just doesn’t recognize every time when the object collides with another object)?

It seems that some of the calls throw the trajectory of my object way off.

I suggest using performFunctionInCocosThread when you want to sync data back to cocos2d-x

Sorry for bumping, but I have a question here.
Should I use performFunctionInCocosThread after having loaded data using cocos2d::network::HttpRequest? Well I got some problems with calling back to a scene from such a request, so that’s what I’m gonna try out right NOW. :slight_smile: But would be good to get a actual confirmation too.

Update: I realized even making sure to call stuff with performFunctionInCocosThread after getting http result did not help my issue. I seem to have some other problem. :frowning: It’s like if a scene disappears very fast before http results are in, sometimes it just crashes… dohh…

I’m guessing you’ve got some reference to an object that destructs with the scene in your callback function. Either retain before you make the HttpRequest and release at the end of the callback, or setResponseCallback(nullptr) when your scene goes out of scope.

Note:
void setResponseCallback(Ref* pTarget, SEL_HttpResponse pSelector) will retain pTarget internally.
void setResponseCallback(const ccHttpRequestCallback& callback) has no such context and so cannot.

This function is useful if you know some operation is performed in another thread. for example if a function display a native UI on Android, it most likely will be executed in the Android UI thread( cocos2dx uses a separate GL thread). And you want to use this function to make sure to process the data in cocos2d thread, especially before rendering.

I worked hard and found the root of those crashes. They were indirectly caused by tapping scene changing buttons fast… Faster than the duration of the transition. I had some delegates set up and it all crashed from that when one of the surplus scenes was deallocated before it even enter onEnter etc. solved by forcing all scene changing buttons to put an invisible touch swallowing node over the whole screen before transitions.:slight_smile:

Hi,

“handles a thread pool for loading audio and other resources” How can i preload sound without stopping the game play. I mean to preload sound effects and not background Music. Would this help me to preload sound after scene is loaded and without effecting gameplay “cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(={ }”

when i minimize game my all scheduler and action should not pause that also should be run in background . how can i do it ? . please help me if any idea you have. @nite

I had been trying to resolve a crash arising due to this thread issue.

Our cocos2d-x android app was fetching data asynchronously from web service, and then was adding it to screen.
For sone reason, things stopped working and after (a long) analysis it occurred to be the threading issue. When the method updating UI was called from successResponse of asynchronous operation’s listener, that happened to be a thread other than the one creating UI in the first place.

This suggestion to use cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(={
} fixed the issue at the best.

Now wondering what was the reason it had been working for over a year out there without notable crashes!

If the data get processed before rendering happens then it could be fine, the problem is that you can’t guarantee that without this function.