{"action":"created","issue":{"url":"https://api.github.com/repos/EventStore/EventStore/issues/396","labels_url":"https://api.github.com/repos/EventStore/EventStore/issues/396/labels{/name}","comments_url":"https://api.github.com/repos/EventStore/EventStore/issues/396/comments","events_url":"https://api.github.com/repos/EventStore/EventStore/issues/396/events","html_url":"https://github.com/EventStore/EventStore/issues/396","id":57650067,"number":396,"title":"Potential data race in .NET Client API","user":{"login":"eulerfx","id":609910,"avatar_url":"https://avatars.githubusercontent.com/u/609910?v=3","gravatar_id":"","url":"https://api.github.com/users/eulerfx","html_url":"https://github.com/eulerfx","followers_url":"https://api.github.com/users/eulerfx/followers","following_url":"https://api.github.com/users/eulerfx/following{/other_user}","gists_url":"https://api.github.com/users/eulerfx/gists{/gist_id}","starred_url":"https://api.github.com/users/eulerfx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eulerfx/subscriptions","organizations_url":"https://api.github.com/users/eulerfx/orgs","repos_url":"https://api.github.com/users/eulerfx/repos","events_url":"https://api.github.com/users/eulerfx/events{/privacy}","received_events_url":"https://api.github.com/users/eulerfx/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/EventStore/EventStore/labels/Bug","name":"Bug","color":"fc2929"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-02-13T20:30:06Z","updated_at":"2015-02-13T20:54:15Z","closed_at":null,"body":"I was following the workflow that occurs when a TCP connection is closed and the client attempts to reconnect. The short version is that it seems accesses to `_state` and `_connectingPhase` fields in `EventStoreConnectionLogicHandler` require a memory barrier. (https://github.com/EventStore/EventStore/blob/dev/src/EventStore.ClientAPI/Internal/EventStoreConnectionLogicHandler.cs#L35)\r\n\r\nTo the extend I was able to trace it out, the connection closed to reconnect workflow is as follows:\r\n\r\n1. `EventStoreConnectionLogicHandler.TcpConnectionClosed` is called either explicitly from `CloseTcpConnection` or via the message pump `SimpleQueuedHandler`.  It sets the fields to `ConnectionState.Connecting` and `ConnectingPhase.Reconnecting` respectively. \r\n\r\n2. Concurrently, a `TimerTick` is invoked checking to see if a reconnect needs to be performed. It reads the `_state` field without a memory barrier. Most cases this should be OK, but it seems like it has a potentially to read stale data. \r\n\r\n3. If step 2 succeeds, `DiscoverEndPoint` is called which also reads the fields and returns if they aren't in the expected state. If everything is as expected, it begins end point discovery via `_endPointDiscoverer.DiscoverAsync`. This completes via `Task.ContinueWith` which queues message `EstablishTcpConnectionMessage`.\r\n\r\n4. The message `EstablishTcpConnectionMessage` gets handled by `EstablishTcpConnection` which also reads the fields `_state` and `_connectingPhase` and if they aren't in the expected state, the connection isn't established. However, the message  `LogDebug(\"EstablishTcpConnection to [{0}]\", endPoint);` still gets logged because that is before the return statement.\r\n\r\nSince `SimpleQueuedHandler` processes the queue via `ThreadPool.QueueUserWorkItem(ProcessQueue)`, despite the fact that only one thread may be running at a given time, it can be a different thread, resulting in the potential to read stale data from the fields. "},"comment":{"url":"https://api.github.com/repos/EventStore/EventStore/issues/comments/74325087","html_url":"https://github.com/EventStore/EventStore/issues/396#issuecomment-74325087","issue_url":"https://api.github.com/repos/EventStore/EventStore/issues/396","id":74325087,"user":{"login":"jen20","id":548524,"avatar_url":"https://avatars.githubusercontent.com/u/548524?v=3","gravatar_id":"","url":"https://api.github.com/users/jen20","html_url":"https://github.com/jen20","followers_url":"https://api.github.com/users/jen20/followers","following_url":"https://api.github.com/users/jen20/following{/other_user}","gists_url":"https://api.github.com/users/jen20/gists{/gist_id}","starred_url":"https://api.github.com/users/jen20/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jen20/subscriptions","organizations_url":"https://api.github.com/users/jen20/orgs","repos_url":"https://api.github.com/users/jen20/repos","events_url":"https://api.github.com/users/jen20/events{/privacy}","received_events_url":"https://api.github.com/users/jen20/received_events","type":"User","site_admin":false},"created_at":"2015-02-13T20:54:15Z","updated_at":"2015-02-13T20:54:15Z","body":"OK a race condition on `_state` as you describe seems intuitive. I'll trace this one through later today and come back to it."}}