/// <summary>
/// This function is called when user invokes zmq_term. If there are
/// no more sockets open it'll cause all the infrastructure to be shut
/// down. If there are open sockets still, the deallocation happens
/// after the last one is closed.
/// </summary>
public void Terminate()
{
m_disposed = true;
Monitor.Enter(m_slotSync);
if (!m_starting)
{
// Check whether termination was already underway, but interrupted and now
// restarted.
bool restarted = m_terminating;
m_terminating = true;
Monitor.Exit(m_slotSync);
// First attempt to terminate the context.
if (!restarted)
{
// First send stop command to sockets so that any blocking calls
// can be interrupted. If there are no sockets we can ask reaper
// thread to stop.
Monitor.Enter(m_slotSync);
try
{
foreach (var socket in m_sockets)
{
socket.Stop();
}
if (m_sockets.Count == 0)
{
m_reaper.Stop();
}
}
finally
{
Monitor.Exit(m_slotSync);
}
}
// Wait till reaper thread closes all the sockets.
Command command;
var found = m_termMailbox.TryRecv(-1, out command);
Debug.Assert(found);
Debug.Assert(command.CommandType == CommandType.Done);
Monitor.Enter(m_slotSync);
Debug.Assert(m_sockets.Count == 0);
}
Monitor.Exit(m_slotSync);
// Deallocate the resources.
Destroy();
}