{"action":"created","issue":{"url":"https://api.github.com/repos/zeromq/netmq/issues/539","repository_url":"https://api.github.com/repos/zeromq/netmq","labels_url":"https://api.github.com/repos/zeromq/netmq/issues/539/labels{/name}","comments_url":"https://api.github.com/repos/zeromq/netmq/issues/539/comments","events_url":"https://api.github.com/repos/zeromq/netmq/issues/539/events","html_url":"https://github.com/zeromq/netmq/issues/539","id":152499866,"number":539,"title":"NetMQMonitor can cause NetMQ.TerminatingException on exit and iothread to hang","user":{"login":"mjmckp","id":7776787,"avatar_url":"https://avatars.githubusercontent.com/u/7776787?v=3","gravatar_id":"","url":"https://api.github.com/users/mjmckp","html_url":"https://github.com/mjmckp","followers_url":"https://api.github.com/users/mjmckp/followers","following_url":"https://api.github.com/users/mjmckp/following{/other_user}","gists_url":"https://api.github.com/users/mjmckp/gists{/gist_id}","starred_url":"https://api.github.com/users/mjmckp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjmckp/subscriptions","organizations_url":"https://api.github.com/users/mjmckp/orgs","repos_url":"https://api.github.com/users/mjmckp/repos","events_url":"https://api.github.com/users/mjmckp/events{/privacy}","received_events_url":"https://api.github.com/users/mjmckp/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-05-02T08:08:57Z","updated_at":"2016-05-03T08:56:34Z","closed_at":null,"body":"If you run the F# program below, occasionally it will fail with NetMQ.TerminatingException (call stack follows).  I am getting this error in other situations as well, but so far this is the only simple reproduction of the error I have come up with.\r\n\r\nI think what is happening is that when the request socket is closed, InternalClose calls m_monitoringSocket.Disconnect, which ultimately calls ZObject.SendPipeTerm.  This causes a monitor event of type SocketEvents.Closed to be generated, however this is not able to be written to the PairSocket because it is in the pending state and CheckWrite returns false.\r\n\r\nIn other situations (not this repro), I have found that the iothread hangs indefinitely trying to send the MonitorEvent of type Closed, which prevents any other sockets from communicating at all.\r\n\r\n```\r\nopen System\r\nopen System.Threading\r\nopen System.Threading.Tasks\r\nopen NetMQ\r\n\r\nlet repro () =   \r\n    let task1 =\r\n        Task.Run (fun () ->\r\n            try\r\n                printfn \"starting server\"\r\n                use socket = new NetMQ.Sockets.ResponseSocket()\r\n                socket.Options.Linger <- TimeSpan.Zero\r\n                let serverEndpoint = \"tcp://*:5555\"\r\n                socket.Bind(serverEndpoint)\r\n                let input = socket.ReceiveFrameString()\r\n                printfn \"input: %s\" input\r\n                socket.SendFrame(\"hello \" + input)\r\n                //socket.Unbind(serverEndpoint)\r\n                printfn \"task complete\"\r\n            with e ->\r\n                printfn \"Main task failed: %O\" e\r\n        )\r\n\r\n    let socket = new NetMQ.Sockets.RequestSocket()\r\n    socket.Options.Linger <- TimeSpan.Zero\r\n    let monitor = new NetMQ.Monitoring.NetMQMonitor(socket, \"inproc://pub.inproc.repro\", NetMQ.SocketEvents.All)\r\n    monitor.EventReceived.Add (fun x -> printfn \"%O\" x.SocketEvent)\r\n    let task2 = monitor.StartAsync()\r\n    socket.Connect(\"tcp://127.0.0.1:5555\")\r\n\r\n    socket.SendFrame(\"world\")\r\n    let output = socket.ReceiveFrameString()\r\n    printfn \"output: %s\" output\r\n        \r\n    Threading.Thread.Sleep(2000)\r\n\r\n    socket.Disconnect(\"tcp://127.0.0.1:5555\")\r\n    monitor.Dispose()\r\n    task2.Wait()\r\n    socket.Dispose()\r\n    task1.Wait()\r\n\r\n[<EntryPoint>]\r\nlet main args = \r\n    repro()\r\n    0\r\n```\r\n\r\nCall stack\r\n```\r\n>\tNetMQ.dll!NetMQ.Core.SocketBase.CheckContextTerminated() Line 146\tC#\r\n \tNetMQ.dll!NetMQ.Core.SocketBase.ProcessCommands(int timeout, bool throttle) Line 1073\tC#\r\n \tNetMQ.dll!NetMQ.Core.SocketBase.TrySend(ref NetMQ.Msg msg, System.TimeSpan timeout, bool more) Line 852\tC#\r\n \tNetMQ.dll!NetMQ.Core.MonitorEvent.Write(NetMQ.Core.SocketBase s) Line 110\tC#\r\n \tNetMQ.dll!NetMQ.Core.SocketBase.MonitorEvent(NetMQ.Core.MonitorEvent monitorEvent) Line 1483\tC#\r\n \tNetMQ.dll!NetMQ.Core.SocketBase.EventClosed(string addr, AsyncIO.AsyncSocket ch) Line 1459\tC#\r\n \tNetMQ.dll!NetMQ.Core.Transports.Tcp.TcpConnector.Close() Line 336\tC#\r\n \tNetMQ.dll!NetMQ.Core.Transports.Tcp.TcpConnector.ProcessTerm(int linger) Line 158\tC#\r\n \tNetMQ.dll!NetMQ.Core.ZObject.ProcessCommand(NetMQ.Core.Command cmd) Line 304\tC#\r\n \tNetMQ.dll!NetMQ.Core.IOThread.Ready() Line 97\tC#\r\n \tNetMQ.dll!NetMQ.Core.IOThreadMailbox.RaiseEvent() Line 105\tC#\r\n \tNetMQ.dll!NetMQ.Core.Utils.Proactor.Loop() Line 114\tC#\r\n \tmscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)\tUnknown\r\n \tmscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)\tUnknown\r\n \tmscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)\tUnknown\r\n \tmscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)\tUnknown\r\n \tmscorlib.dll!System.Threading.ThreadHelper.ThreadStart()\tUnknown\r\n\r\n```"},"comment":{"url":"https://api.github.com/repos/zeromq/netmq/issues/comments/216472004","html_url":"https://github.com/zeromq/netmq/issues/539#issuecomment-216472004","issue_url":"https://api.github.com/repos/zeromq/netmq/issues/539","id":216472004,"user":{"login":"somdoron","id":2715638,"avatar_url":"https://avatars.githubusercontent.com/u/2715638?v=3","gravatar_id":"","url":"https://api.github.com/users/somdoron","html_url":"https://github.com/somdoron","followers_url":"https://api.github.com/users/somdoron/followers","following_url":"https://api.github.com/users/somdoron/following{/other_user}","gists_url":"https://api.github.com/users/somdoron/gists{/gist_id}","starred_url":"https://api.github.com/users/somdoron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/somdoron/subscriptions","organizations_url":"https://api.github.com/users/somdoron/orgs","repos_url":"https://api.github.com/users/somdoron/repos","events_url":"https://api.github.com/users/somdoron/events{/privacy}","received_events_url":"https://api.github.com/users/somdoron/received_events","type":"User","site_admin":false},"created_at":"2016-05-03T08:56:34Z","updated_at":"2016-05-03T08:56:34Z","body":"Actually this is a bug on libzmq as well. \r\nI think the TrySend in MonitorEvent.Write should be with timeout zero.\r\n\r\nMonitoring implementation is both libzmq and NetMQ is buggy, sometimes violating the only access socket from one thread. \r\nAnyway, my suggestion is to not use the Monitor feature, if I could I would remove it. Try to implement those features at the application level.\r\n\r\nWhat is the problem you are using the monitor for?"}}