/// <summary> /// Dump all of this object's resources /// by stopping and destroying all of it's threads, destroying the reaper, and closing the mailbox. /// </summary> private void Destroy() { foreach (IOThread it in m_ioThreads) { it.Stop(); } foreach (IOThread it in m_ioThreads) { it.Destroy(); } if (m_reaper != null) { m_reaper.Destroy(); } m_termMailbox.Close(); m_disposed = true; }
/// <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(bool block) { 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 (!block) { m_reaper.ForceStop(); } else if (m_sockets.Count == 0) { m_reaper.Stop(); } } finally { Monitor.Exit(m_slotSync); } } // Wait till reaper thread closes all the sockets. var found = m_termMailbox.TryRecv(-1, out Command command); Debug.Assert(found); Debug.Assert(command.CommandType == CommandType.Done); Monitor.Enter(m_slotSync); } Monitor.Exit(m_slotSync); // Deallocate the resources. foreach (IOThread it in m_ioThreads) { it.Stop(); } foreach (IOThread it in m_ioThreads) { it.Destroy(); } m_reaper?.Destroy(); m_termMailbox.Close(); m_disposed = true; }