Skip to content

Commit

Permalink
Revert "Improvements in engine process exit and termination (#145)" (#…
Browse files Browse the repository at this point in the history
…146)

This reverts commit 0743675.
  • Loading branch information
josesimoes authored Jun 8, 2018
1 parent 0743675 commit b74c164
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ public partial class SerialPort : PortBase, IPort
/// </summary>
private List<NanoDeviceBase> _tentativeNanoFrameworkDevices = new List<NanoDeviceBase>();

DataWriter outputStreamWriter = null;
DataReader inputStreamReader = null;


/// <summary>
/// Creates an Serial debug client
/// </summary>
Expand Down Expand Up @@ -665,17 +661,16 @@ public async Task<uint> SendBufferAsync(byte[] buffer, TimeSpan waiTimeout, Canc
// device must be connected
if (EventHandlerForSerialDevice.Current.IsDeviceConnected && !cancellationToken.IsCancellationRequested)
{
DataWriter outputStreamWriter = new DataWriter(EventHandlerForSerialDevice.Current.Device.OutputStream);

try
{
outputStreamWriter = new DataWriter(EventHandlerForSerialDevice.Current.Device.OutputStream);

// write buffer to device
outputStreamWriter.WriteBytes(buffer);

cancellationToken.ThrowIfCancellationRequested();
Task<UInt32> storeAsyncTask = outputStreamWriter.StoreAsync().AsTask(cancellationToken.AddTimeout(waiTimeout));

return await outputStreamWriter.StoreAsync().AsTask(cancellationToken.AddTimeout(waiTimeout));
return await storeAsyncTask;
}
catch (TaskCanceledException)
{
Expand Down Expand Up @@ -706,12 +701,10 @@ public async Task<byte[]> ReadBufferAsync(uint bytesToRead, TimeSpan waiTimeout,
// device must be connected
if (EventHandlerForSerialDevice.Current.IsDeviceConnected && !cancellationToken.IsCancellationRequested)
{
DataReader inputStreamReader = new DataReader(EventHandlerForSerialDevice.Current.Device.InputStream);

try
{
inputStreamReader = new DataReader(EventHandlerForSerialDevice.Current.Device.InputStream);

cancellationToken.ThrowIfCancellationRequested();

Task<UInt32> loadAsyncTask = inputStreamReader.LoadAsync(bytesToRead).AsTask(cancellationToken.AddTimeout(waiTimeout));

UInt32 bytesRead = await loadAsyncTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ public async Task<uint> SendBufferAsync(byte[] buffer, TimeSpan waiTimeout, Canc
}
else
{
throw new DeviceNotConnectedException();
// FIXME
// NotifyDeviceNotConnected
}

return bytesWritten;
Expand Down Expand Up @@ -624,7 +625,8 @@ public async Task<byte[]> ReadBufferAsync(uint bytesToRead, TimeSpan waiTimeout,
}
else
{
throw new DeviceNotConnectedException();
// FIXME
// NotifyDeviceNotConnected
}

// return empty byte array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ public Converter CreateConverter()
return new Converter(Capabilities);
}

private void ProcessExit()
{
App.ProcessExited();
}

public async Task<bool> SendAsync(MessageRaw raw, CancellationToken cancellationToken)
{
_sendSemaphore.WaitOne();
Expand Down Expand Up @@ -100,10 +95,6 @@ public async Task<bool> SendAsync(MessageRaw raw, CancellationToken cancellation
{
// don't do anything here, as this is expected
}
catch(DeviceNotConnectedException)
{
App.ProcessExited();
}
finally
{
_sendSemaphore.Release();
Expand Down Expand Up @@ -175,13 +166,8 @@ internal async Task<int> ReadBufferAsync(byte[] buffer, int offset, int bytesToR
{
// don't do anything here, as this is expected
}
catch (DeviceNotConnectedException)
{
App.ProcessExited();
}

return bytesToReadRequested - bytesToRead;
}

}
}
104 changes: 74 additions & 30 deletions source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public partial class Engine : IDisposable, IControllerHostLocal
ManualResetEvent m_evtShutdown;
ManualResetEvent m_evtPing;
TypeSysLookup m_typeSysLookup;
EngineState _state;
//bool m_fProcessExited;

private Task _backgroundProcessor;

Expand All @@ -79,9 +81,13 @@ internal Engine(NanoDeviceBase device)
// default to false
IsCRC32EnabledForWireProtocol = false;

_state.SetValue(EngineState.Value.Starting, true);

// start task to process background messages
_backgroundProcessor = Task.Factory.StartNew(() => IncomingMessagesListenerAsync(), _backgroundProcessorCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);

_state.SetValue(EngineState.Value.Started, false);

_pendingRequestsTimer = new Timer(ClearPendingRequests, null, 1000, 1000);
}

Expand All @@ -98,6 +104,8 @@ private void Initialize()

m_notifyNoise = new FifoBuffer();
m_typeSysLookup = new TypeSysLookup();
_state = new EngineState(this);
//m_fProcessExited = false;

//default capabilities, used until clr can be queried.
Capabilities = new CLRCapabilities();
Expand All @@ -112,7 +120,7 @@ private void InitializeLocal(NanoDeviceBase device)
_controlller = new Controller(this);

Device = (INanoDevice)device;

Initialize();
}

Expand Down Expand Up @@ -147,11 +155,6 @@ public async Task<bool> ConnectAsync(int timeout, bool force = false, Connection
// connect to device
if (await Device.ConnectAsync())
{
if (_backgroundProcessor.Status != TaskStatus.Running)
{
// background processor is not running, start it
ResumeProcessing();
}

Commands.Monitor_Ping cmd = new Commands.Monitor_Ping();

Expand Down Expand Up @@ -259,28 +262,48 @@ public async Task IncomingMessagesListenerAsync()
{
var reassembler = new MessageReassembler(_controlller);

while (!_backgroundProcessorCancellation.IsCancellationRequested)
while (!_backgroundProcessorCancellation.IsCancellationRequested && _state.IsRunning)
{
try
{
await reassembler.ProcessAsync(_backgroundProcessorCancellation.Token);
}
catch (DeviceNotConnectedException)
{
ProcessExited();
}
catch (Exception ex)
if (await Device.ConnectAsync())
{
// look for I/O exception
// 0x800703E3
if (ex.HResult == -2147023901)
try
{
ProcessExited();
await reassembler.ProcessAsync(_backgroundProcessorCancellation.Token);
}

if (_backgroundProcessorCancellation.IsCancellationRequested)
catch (DeviceNotConnectedException)
{
break;
if (_backgroundProcessorCancellation.IsCancellationRequested || !_state.IsRunning)
{
return;
}
else
{
await Task.Delay(1000);
await Device.ConnectAsync();
}
}
catch (Exception ex)
{
if (_backgroundProcessorCancellation.IsCancellationRequested || !_state.IsRunning)
{
return;
}
else
{

if (ex.GetType().Equals(typeof(AggregateException)))
{
if (ex.GetBaseException().GetType().Name == typeof(DeviceNotConnectedException).Name)
{
await Task.Delay(1000);
await Device.ConnectAsync();
}
}
else if (ex.HResult == 0x80070006)
{
return;
}
}
}
}
}
Expand Down Expand Up @@ -621,9 +644,7 @@ public void SpuriousCharacters(byte[] buf, int offset, int count)

public void ProcessExited()
{
Stop();

_eventProcessExit?.Invoke(this, null);
throw new NotImplementedException();
}

public async Task<byte[]> ReadBufferAsync(uint bytesToRead, TimeSpan waitTimeout, CancellationToken cancellationToken)
Expand All @@ -638,6 +659,8 @@ private OutgoingMessage CreateMessage(uint cmd, uint flags, object payload)

public void StopProcessing()
{
_state.SetValue(EngineState.Value.Stopping, false);

m_evtShutdown.Set();

if (_backgroundProcessor != null)
Expand All @@ -650,14 +673,18 @@ public void StopProcessing()
Task.WaitAll(_backgroundProcessor);
}
catch { }

_backgroundProcessor = null;
}
}

public void ResumeProcessing()
{
m_evtShutdown.Reset();

if (_backgroundProcessor == null || _backgroundProcessor.IsCompleted)
_state.SetValue(EngineState.Value.Resume, false);

if (_backgroundProcessor == null)
{
_backgroundProcessor = Task.Factory.StartNew(() => IncomingMessagesListenerAsync(), _backgroundProcessorCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);
}
Expand All @@ -670,9 +697,19 @@ public void Stop()
m_evtShutdown.Set();
}

StopProcessing();
if (_state.SetValue(EngineState.Value.Stopping, false))
{
StopProcessing();

//((IController)this).ClosePort();

_state.SetValue(EngineState.Value.Stopped, false);
}
}

public bool IsRunning => _state.IsRunning;


#region RPC Support

// comment from original code REVIEW: Can this be refactored out of here to a separate class dedicated to RPC?
Expand Down Expand Up @@ -974,7 +1011,10 @@ private void RpcReceiveSendDispatch(object obj)
{
EndPointRegistration.InboundRequest ir = (EndPointRegistration.InboundRequest)obj;

ir.Owner.m_ep.DispatchMessage(ir.m_msg);
if (IsRunning)
{
ir.Owner.m_ep.DispatchMessage(ir.m_msg);
}
}

internal bool RpcReply(Commands.Debugging_Messaging_Address addr, byte[] data)
Expand Down Expand Up @@ -1041,7 +1081,11 @@ internal async Task<WireProtocolRequest> RequestAsync(OutgoingMessage message, i
{
using (CancellationTokenSource cts = new CancellationTokenSource())
{
if(_backgroundProcessor.Status != TaskStatus.Running)
//Checking whether IsRunning and adding the request to m_requests
//needs to be atomic to avoid adding a request after the Engine
//has been stopped.

if (!IsRunning)
{
throw new ApplicationException("Engine is not running or process has exited.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// Copyright (c) 2017 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.Tools.Debugger
{
internal class EngineState
{
public enum Value
{
NotStarted,
Starting,
Started,
Stopping,
Resume,
Stopped,
Disposing,
Disposed
}

private Value _value;
public object SyncObject { get; private set; }

public EngineState(object syncObject)
{
_value = Value.NotStarted;
SyncObject = syncObject;
}

public Value GetValue()
{
return _value;
}

public bool SetValue(Value value)
{
return SetValue(value, false);
}

public bool SetValue(Value value, bool fThrow)
{
lock (SyncObject)
{
if (_value == Value.Stopping && value == Value.Resume)
{
_value = Value.Started;
return true;
}
else if (_value < value)
{
_value = value;
return true;
}
else
{
if (fThrow)
{
throw new Exception(string.Format("Cannot set State to {0}", value));
}

return false;
}
}
}

public bool IsRunning
{
get
{
Value val = _value;

return val == Value.Starting || val == Value.Started;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\Converter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\DeploymentBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\Engine.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\EngineState.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\FifoBuffer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\DeploymentSector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WireProtocol\IControllerRemote.cs" />
Expand Down

0 comments on commit b74c164

Please sign in to comment.