Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
3
Question by LarrxX · Aug 04, 2017 at 08:12 AM · dllnative pluginc++multithreading

Editor freezing with multithreaded DLL native plugin in Release but not in Debug

I have a DLL with a native plugin that runs a very time consuming infinite loop which runs in a separate thread to avoid freezing the main Unity rendering thread. Everything works flawlessly when I compile and run my DLL in Debug mode, but if I compile it in Release, it runs perfectly fine the first time in the editor but if I press play again, everything freezes (Start is never even called the second time, neither is UnityPluginLoad). I'm at the end of my rope with this issue and any help would be greatly appreciated.

And now for the technical details, a dumbed down version of my architecture.

I used SWIG to create an interface between my C++ code and C# code. The interface itself has nothing really fancy going on and there is absolutely no extra SWIG magic needed to get it to work.

On the Unity side I'm doing:

 public class myBehavior : MonoBehaviour
 {
     private myDLLInterface m_interface;
 
     private delegate void eventCallbackDelegate( int eventID );
     eventCallbackDelegate m_eventCallback = null;
 
     void OnDestroy()
     {
         StopCoroutine( "CallPluginAtEndOfFrames" );
         m_interface = null;
     }
 
     IEnumerator Start()
     {
         m_interface= new myDLLInterface ();
         m_eventCallback = new eventCallbackDelegate( m_interface.updateFrameDataOGL );
         m_interface.run();
         yield return StartCoroutine( "CallPluginAtEndOfFrames" );
     }
 
     void Update()
     { }
 
     private IEnumerator CallPluginAtEndOfFrames()
     {
         if( m_eventCallback != null )
         {
             while( m_poseEstimator != null )
             {
                 // Wait until all frame rendering is done
                 yield return null;
 
                 GL.IssuePluginEvent( Marshal.GetFunctionPointerForDelegate( m_eventCallback ), 1 );
                 //Play can stop in the middle of coroutine.
                 if( m_interface!= null )
                 {
                     doStuff();
                 }
             }
         }
     }
 }

And this is what's happening inside my DLL:

 myDLLInterface::~myDLLInterface()
 {
      if( m_loopRunner)
     {
         m_loopRunner->stop();
         
         while( m_loopRunner->isWorking() )
             ;
         delete m_loopRunner;
         m_loopRunner= NULL;
     }
 }
 
 void myDLLInterface::run()
 {
     std::thread t( &TheLoopRunner::run, m_loopRunner);
     t.detach();
 }
 
 void SolARPoseEsimatorDllInterface::updateFrameDataOGL( int eventID )
 {
     if( m_loopRunner->tryLock() )
     {
             doStuff();
         m_loopRunner->unlock();
     }
 }

And finally, in my TheLoopRunner, this is happening:

 TheLoopRunner has member variable: std::mutex m_myMutex;
 
 TheLoopRunner::run()
 {
    m_runLoop = true;
    m_isWorking = true;
    while( m_runLoop )
    {
        doExpensiveComputations();
        m_myMutex.lock();
        updateOutput();
        unlock();
    }
    m_isWorking = false;
 }
 
 void TheLoopRunner::stop()
 {
    m_runLoop = false;
 }
 
 bool TheLoopRunner::isWorking()
 {
    return m_isWorking();
 }
 
 bool TheLoopRunner::tryLock()
 {
     return m_myMutex.try_lock();
 }
 
 void TheLoopRunner()::unlock()
 {
    m_myMutex.unlock();
 }

I also tried not detaching the thread, and storing it in a std::thread* member variable and deleting it in the myDllInterface destructor (with or without joining before deleting) , but the behavior remains the same.

What happens in Debug that allows this to work 100% of the time and waht happens in release that stops this from working 100% of the time?

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DrummerB · Jul 31, 2018 at 12:19 PM 1
Share

Have you ever been able to figure this out? I have the same issue currently. Thanks.

avatar image Zgore · Apr 21, 2019 at 11:45 PM 0
Share

Ok, I finally solved it.

First, it's important to understand how Unity manage its threads (it can be usefull for further issues): https://blog.tedd.no/2016/10/09/investigating-unity-hang-on-second-run-multi-threading/

This link was also really usefull to understand that is better to explicitly stop the thread in the C++ by calling a dedicated function due to Unity thread management : https://forum.unity.com/threads/problem-with-callbacks.87513/

But, for my case, the error was due to a global object, the one accessed by the C function for my thread initialization, that was not destroyed across different launch of the game in Unity. Now my global object is a smart pointer, and I reset the underlying pointer and make a new one at each call of my thread initialization function.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Zgore · Apr 21, 2019 at 09:42 PM

I'm actually encountering the same issue, how did you manage it @LarrxX ?

EDIT: Ok, I finally solved it.

First, it's important to understand how Unity manage its threads (it can be usefull for further issues): https://blog.tedd.no/2016/10/09/investigating-unity-hang-on-second-run-multi-threading/

This link was also really usefull to understand that is better to explicitly stop the thread in the C++ by calling a dedicated function due to Unity thread management : https://forum.unity.com/threads/problem-with-callbacks.87513/

But, for my case, the error was due to a global object, the one accessed by the C function for my thread initialization, that was not destroyed across different launch of the game in Unity. Now my global object is a smart pointer, and I reset the underlying pointer and make a new one at each call of my thread initialization function.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LarrxX · Apr 23, 2019 at 09:19 AM 0
Share

That's how I finally solved it. I had an explicit "dispose" method that I call when exiting the application, that forcibly stops the thread.

avatar image
0

Answer by LarrxX · Apr 23, 2019 at 09:19 AM

That's how I finally solved it. I had an explicit "dispose" method that I call when exiting the application, that forcibly stops the thread.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

114 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Creating multiple instances of a dll object 0 Answers

How do I integrate our GUI project in Unity with our existing C++ project? DLL's and IL2CPP scripting backend solutions are not working... 0 Answers

Are you missing an assembly reference? Android build 0 Answers

Send Desktop Screencapture to Unity Plugin 0 Answers

DllNotFoundException, C++ dll used with an assembly, not possible? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges