internal T AddCommand <T>(T command) where T : StCommand { if (WidcommBtInterface.IsWidcommSingleThread(this)) { Debug.Assert(Thread.CurrentThread == m_thread); // Yikes the special thread is trying to offload some work!! Debug.Fail("Widcomm main thread calling itself!?!"); throw new NotSupportedException("Internal error -- Widcomm main thread calling itself!?!"); } else { Debug.Assert(Thread.CurrentThread != m_thread); } command.SetRunner(this); //TODO ?if (_ended) throw new InvalidOperationException("Not running!"); lock (m_actions) { m_actions.Enqueue(command); #if NETCF try { _netcfEvent.Set(); } catch (ObjectDisposedException) { bool ended = _ended; Utils.MiscUtils.Trace_WriteLine("!single-threader.AddCommand ObjectDisposedException" + " (_ended: " + _ended + ")"); } #else Monitor.Pulse(m_actions); #endif } return(command); }
public void Destroy(bool disposing) { if (!disposing) // If Finalizing, may be that the thread is dead. { return; } if (!WidcommBtInterface.IsWidcommSingleThread(_st)) { WidcommPortSingleThreader.MiscNoReturnCommand cmd = _st.AddCommand( new WidcommPortSingleThreader.MiscNoReturnCommand(delegate { _child.Destroy(disposing); })); cmd.WaitCompletion(); } else { _child.Destroy(disposing); } }
internal override void EnsureLoaded() { Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty EnsureLoaded ENTRY (for v.L)"); if (_st != null) { if (WidcommBtInterface.IsWidcommSingleThread(_st)) // DEBUG { } } lock (typeof(WidcommBluetoothFactory)) { Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty EnsureLoaded IN lock"); // In case Widcomm is forced to shutdown when CBtIf is extant we monitor // for the stack-down event so we can force reload next time // we're used. var seenStackDownEvent = _seenStackDownEvent; _seenStackDownEvent = false; if (seenStackDownEvent) { Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty seenStackDownEvent"); if (!DoPowerDownUpReset) { Utils.MiscUtils.Trace_WriteLine("Ignoring stack/radio shutdown due to DoPowerDownUpReset=false."); } else { Utils.MiscUtils.Trace_WriteLine("Restarting due to stack/radio shutdown."); bool respectLocks = true; // -- Shutdown -- ThreadStart doDispose = () => Dispose(true, respectLocks); var st = GetSingleThreader(); if (st != null && !WidcommBtInterface.IsWidcommSingleThread(st)) { respectLocks = false; var c = st.AddCommand(new WidcommPortSingleThreader.MiscNoReturnCommand( doDispose)); c.WaitCompletion(); MemoryBarrier(); } else { doDispose(); } Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty done Dispose"); Debug.Assert(s_btIf == null, "After Dispose but NOT s_btIf == null"); Debug.Assert(s_btInterface == null, "After Dispose but NOT s_btInterface == null"); Thread.Sleep(5000); } } //-- Create -- // CBtIf: MUST ONLY be ONE of these, and must be FIRST created! // "Only one object of this class should be instantiated by the application." // "This class must be instantiated before any other DK classes are used" if (s_btIf == null) { #if KILL_SINGLE_THREAD_AT_DISPOSAL Debug.Assert(_st == null); #endif if (_st == null) { _st = new WidcommPortSingleThreader(); } Debug.Assert(GetSingleThreader() != null); IBtIf btIf; Func <IBtIf> f = () => new WidcommBtIf(this); var st = GetSingleThreader(); if (st != null && !WidcommBtInterface.IsWidcommSingleThread(st)) { var c = st.AddCommand(new WidcommPortSingleThreader.MiscReturnCommand <IBtIf>( f)); btIf = c.WaitCompletion(); } else { btIf = f(); } Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty done new WidcommBtIf"); if (st != null) { btIf = new WidcommStBtIf(this, btIf); Utils.MiscUtils.Trace_WriteLine("IBtIf using WidcommStBtIf."); } Debug.Assert(s_btInterface == null); WidcommBtInterface btInterface = new WidcommBtInterface(btIf, this); // Don't set these until we're sure that initialisation has // all completed successfully. s_btIf = btIf; s_btInterface = btInterface; } else { Debug.Assert(s_btInterface != null, "One set but not the other!"); } }//lock Debug.WriteLine(WidcommUtils.GetTime4Log() + ": WcBtFcty EnsureLoaded EXIT"); }