{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/52119492","id":52119492,"diff_hunk":"@@ -113,6 +113,7 @@ public override string SubProtocol\n                         secureConnection ? Interop.WinHttp.WINHTTP_FLAG_SECURE : 0);\n \n                     ThrowOnInvalidHandle(_operation.RequestHandle);\n+                    _operation.IncrementHandlesOpenWithCallback();","path":"src/System.Net.WebSockets.Client/src/System/Net/WebSockets/WinHttpWebSocket.cs","position":4,"original_position":4,"commit_id":"b2fb65865bc9dfb9af729faca38f4bccb1b7b31e","original_commit_id":"b2fb65865bc9dfb9af729faca38f4bccb1b7b31e","user":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"body":"`WinHttpWebSocketState.Unpin` has a check in it so that it won't do anything unless the GCHandle has been allocated, i.e. `Pin` has been called already.\r\n\r\nThe only way callbacks can happen in general on these handles is if the callback has been fully wired up with the callback and the context value. That is why the Pin() call is right after the final call to wire up the callback.\r\n\r\nIn terms of anything bad going wrong between the `_operation.IncrementHandlesOpenWithCallback' and the `Pin` call, we don't really care.  There is lots of code between those calls. But the callback hasn't been wired up yet. So, there won't be a need to protect the state object (i.e. pin/strong root it) because it will never be dereferenced thru a native callback.\r\n\r\n","created_at":"2016-02-07T15:54:44Z","updated_at":"2016-02-07T15:54:44Z","html_url":"https://github.com/dotnet/corefx/pull/5928#discussion_r52119492","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/5928","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/52119492"},"html":{"href":"https://github.com/dotnet/corefx/pull/5928#discussion_r52119492"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/5928"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/5928","id":58478219,"html_url":"https://github.com/dotnet/corefx/pull/5928","diff_url":"https://github.com/dotnet/corefx/pull/5928.diff","patch_url":"https://github.com/dotnet/corefx/pull/5928.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/5928","number":5928,"state":"open","locked":false,"title":"Fix gchandle leak in WebSockets.Client","user":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"body":"The Windows implementation of WebSockets.Client leaks the WinHttpWebSocketState object. This object was being pinned by `GCHandle.Alloc(this)` in the contructor. And it was never freed.\r\n\r\nThis object needs to be pinned during the WebSocket lifecycle because the address of the object is passed to native WinHTTP and used as the context value during callbacks. However, it needs to be manually freed at the proper time after all WinHTTP callbacks are done via closing down the handles.\r\n\r\nThis fix adds Pin() and Unpin() methods to WinHttpWebSocketState and calls them at appropriate times. While fixing this I discovered other places where the object might be left as pinned. The current logic relies on WinHTTP calling the callback with HANDLE_CLOSING before the object would get unpinned. But since the object is pinned very early on, it's possible due to unexpected errors, that the wiring of the WinHTTP callback never gets done. And thus, the object would never have been unpinned.  This fix delays the pinning of the object until the right time where it is assured that the WinHTTP callback wiring has been completed.\r\n\r\nThis logic is now similar to the state handling in WinHttpHandler. There is still a work item #2501 to merge these design implementations and share code in the future.\r\n\r\nFixes #3256.","created_at":"2016-02-05T20:11:46Z","updated_at":"2016-02-07T15:54:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"05229d5ccc4438ba4fe78881486f3f465d218b49","assignee":null,"milestone":{"url":"https://api.github.com/repos/dotnet/corefx/milestones/4","html_url":"https://github.com/dotnet/corefx/milestones/1.0.0-rtm","labels_url":"https://api.github.com/repos/dotnet/corefx/milestones/4/labels","id":1248719,"number":4,"title":"1.0.0-rtm","description":"Q1 2016 (https://github.com/aspnet/Home/wiki/Roadmap)","creator":{"login":"joshfree","id":1302850,"avatar_url":"https://avatars.githubusercontent.com/u/1302850?v=3","gravatar_id":"","url":"https://api.github.com/users/joshfree","html_url":"https://github.com/joshfree","followers_url":"https://api.github.com/users/joshfree/followers","following_url":"https://api.github.com/users/joshfree/following{/other_user}","gists_url":"https://api.github.com/users/joshfree/gists{/gist_id}","starred_url":"https://api.github.com/users/joshfree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joshfree/subscriptions","organizations_url":"https://api.github.com/users/joshfree/orgs","repos_url":"https://api.github.com/users/joshfree/repos","events_url":"https://api.github.com/users/joshfree/events{/privacy}","received_events_url":"https://api.github.com/users/joshfree/received_events","type":"User","site_admin":false},"open_issues":234,"closed_issues":226,"state":"open","created_at":"2015-08-10T18:04:00Z","updated_at":"2016-02-06T21:55:49Z","due_on":"2016-03-31T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/5928/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/5928/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/5928/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/b2fb65865bc9dfb9af729faca38f4bccb1b7b31e","head":{"label":"davidsh:websocket_leak","ref":"websocket_leak","sha":"b2fb65865bc9dfb9af729faca38f4bccb1b7b31e","user":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"repo":{"id":31976766,"name":"corefx","full_name":"davidsh/corefx","owner":{"login":"davidsh","id":7684835,"avatar_url":"https://avatars.githubusercontent.com/u/7684835?v=3","gravatar_id":"","url":"https://api.github.com/users/davidsh","html_url":"https://github.com/davidsh","followers_url":"https://api.github.com/users/davidsh/followers","following_url":"https://api.github.com/users/davidsh/following{/other_user}","gists_url":"https://api.github.com/users/davidsh/gists{/gist_id}","starred_url":"https://api.github.com/users/davidsh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidsh/subscriptions","organizations_url":"https://api.github.com/users/davidsh/orgs","repos_url":"https://api.github.com/users/davidsh/repos","events_url":"https://api.github.com/users/davidsh/events{/privacy}","received_events_url":"https://api.github.com/users/davidsh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/davidsh/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/davidsh/corefx","forks_url":"https://api.github.com/repos/davidsh/corefx/forks","keys_url":"https://api.github.com/repos/davidsh/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/davidsh/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/davidsh/corefx/teams","hooks_url":"https://api.github.com/repos/davidsh/corefx/hooks","issue_events_url":"https://api.github.com/repos/davidsh/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/davidsh/corefx/events","assignees_url":"https://api.github.com/repos/davidsh/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/davidsh/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/davidsh/corefx/tags","blobs_url":"https://api.github.com/repos/davidsh/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/davidsh/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/davidsh/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/davidsh/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/davidsh/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/davidsh/corefx/languages","stargazers_url":"https://api.github.com/repos/davidsh/corefx/stargazers","contributors_url":"https://api.github.com/repos/davidsh/corefx/contributors","subscribers_url":"https://api.github.com/repos/davidsh/corefx/subscribers","subscription_url":"https://api.github.com/repos/davidsh/corefx/subscription","commits_url":"https://api.github.com/repos/davidsh/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/davidsh/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/davidsh/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/davidsh/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/davidsh/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/davidsh/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/davidsh/corefx/merges","archive_url":"https://api.github.com/repos/davidsh/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/davidsh/corefx/downloads","issues_url":"https://api.github.com/repos/davidsh/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/davidsh/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/davidsh/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/davidsh/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/davidsh/corefx/labels{/name}","releases_url":"https://api.github.com/repos/davidsh/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/davidsh/corefx/deployments","created_at":"2015-03-10T19:16:38Z","updated_at":"2016-01-12T17:03:56Z","pushed_at":"2016-02-07T04:15:53Z","git_url":"git://github.com/davidsh/corefx.git","ssh_url":"git@github.com:davidsh/corefx.git","clone_url":"https://github.com/davidsh/corefx.git","svn_url":"https://github.com/davidsh/corefx","homepage":"","size":51538,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"fc7e20bfc67f58d1cd19c577f1fdbdd7260e173b","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/corefx/deployments","created_at":"2014-11-06T23:42:48Z","updated_at":"2016-02-07T15:29:38Z","pushed_at":"2016-02-07T15:43:00Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/","size":61889,"stargazers_count":9086,"watchers_count":9086,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2108,"mirror_url":null,"open_issues_count":827,"forks":2108,"open_issues":827,"watchers":9086,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/5928"},"html":{"href":"https://github.com/dotnet/corefx/pull/5928"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/5928"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/5928/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/5928/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/5928/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/b2fb65865bc9dfb9af729faca38f4bccb1b7b31e"}}}}