Skip to content

Commit

Permalink
Added a manual reset event to the Device class called DoneEvent which…
Browse files Browse the repository at this point in the history
… will be signaled when the recieve loops end.

This is useful for when you need to wait in a hosting thread for the device thread to complete, or to check if it's completed in a nice and thread safe manner.
Also marked the _run member in Device as volatile so the call to Stop() is garantueed to terminate the thread, as on some architectures (and in some version of the CLR) the _runc heck in RunningLoop could get hoisted if _run was not marked as volatile.
  • Loading branch information
fholm authored and John Gozde committed Dec 15, 2011
1 parent bfee56a commit 4bb3957
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions src/clrzmq-ext/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ namespace ZMQ.ZMQDevice {
public abstract class Device : IDisposable {
private const long PollingInterval = 750000;

protected bool _run;
protected volatile bool _run;
protected Socket _frontend;
protected Socket _backend;

private readonly Thread _runningThread;
private bool _isRunning;
private readonly ManualResetEvent _doneEvent;

private bool _isRunning;

/// <summary>
/// Create Device
Expand All @@ -47,12 +49,20 @@ protected Device(Socket frontend, Socket backend) {
_runningThread = new Thread(RunningLoop);
_frontend.PollInHandler += FrontendHandler;
_backend.PollInHandler += BackendHandler;
_doneEvent = new ManualResetEvent(false);
}

~Device() {
Dispose(false);
}

public ManualResetEvent DoneEvent { get { return _doneEvent; } }

public bool IsRunning {
get { return _isRunning; }
set { _isRunning = value; }
}

public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
Expand All @@ -74,6 +84,7 @@ protected virtual void Dispose(bool disposing) {
/// Start Device
/// </summary>
public virtual void Start() {
_doneEvent.Reset();
_run = true;
_runningThread.Start();
_isRunning = true;
Expand All @@ -86,17 +97,13 @@ public virtual void Stop() {
_run = false;
}

public bool IsRunning {
get { return _isRunning; }
set { _isRunning = value; }
}

protected virtual void RunningLoop() {
var skts = new List<Socket> { _frontend, _backend };
while (_run) {
Context.Poller(skts, PollingInterval);
}
IsRunning = false;
_doneEvent.Set();
}
}

Expand Down

0 comments on commit 4bb3957

Please sign in to comment.