private void WorkerTeardown()
    {
        if (WorkerThread.IsAlive)
        {
            // Signal the thread to stop
            HaltThreadSignal.Set();

            // Wait ten seconds for the thread to finish
            ThreadExitedSignal.WaitOne(10 * 1000);

            // Reset the stop and exited flags so that the thread can be restarted
            HaltThreadSignal.Reset();
            ThreadExitedSignal.Reset();
        }

        //Free any manually loaded DLLs
        if (psmoveapiTrackerHandle != IntPtr.Zero)
        {
            FreeLibrary(psmoveapiTrackerHandle);
            psmoveapiTrackerHandle = IntPtr.Zero;
        }

        if (psmoveapiHandle != IntPtr.Zero)
        {
            FreeLibrary(psmoveapiHandle);
            psmoveapiHandle = IntPtr.Zero;
        }
    }
    private void ThreadProc()
    {
        try
        {
            bool receivedStopSignal = false;

            ThreadSetup();

            //Initial wait before starting.
            Thread.Sleep(30);

            while (!receivedStopSignal)
            {
                ThreadUpdate();

                // See if the main thread signaled us to stop
                if (HaltThreadSignal.WaitOne(0))
                {
                    receivedStopSignal = true;
                }

                if (!receivedStopSignal)
                {
                    System.Threading.Thread.Sleep(1);
                }
            }

            ThreadTeardown();
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError(string.Format("PSMoveWorker: WorkerThread crashed: {0}", e.Message));
            UnityEngine.Debug.LogException(e);
        }
        finally
        {
            ThreadExitedSignal.Set();
        }
    }