{"action":"created","comment":{"url":"https://api.github.com/repos/docker/libnetwork/pulls/comments/30004265","id":30004265,"diff_hunk":"@@ -947,3 +953,162 @@ func TestNoEnableIPv6(t *testing.T) {\n \t\tt.Fatal(err)\n \t}\n }\n+\n+var (\n+\tonce   sync.Once\n+\tctrlr  libnetwork.NetworkController\n+\tstart  = make(chan struct{})\n+\tdone   = make(chan chan struct{}, numThreads-1)\n+\torigns = netns.None()\n+\ttestns = netns.None()\n+)\n+\n+const (\n+\titerCnt    = 25\n+\tnumThreads = 3\n+\tfirst      = 1\n+\tlast       = numThreads\n+\tdebug      = false\n+)\n+\n+func createGlobalInstance(t *testing.T) {\n+\tvar err error\n+\tdefer close(start)\n+\n+\torigns, err = netns.Get()\n+\tif err != nil {\n+\t\tt.Fatal(err)\n+\t}\n+\n+\t//testns = origns\n+\ttestns, err = netns.New()\n+\tif err != nil {\n+\t\tt.Fatal(err)\n+\t}\n+\n+\tctrlr = libnetwork.New()\n+\n+\terr = ctrlr.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption())\n+\tif err != nil {\n+\t\tt.Fatal(\"configure driver\")\n+\t}\n+\n+\tnet, err := ctrlr.NewNetwork(bridgeNetType, \"network1\")\n+\tif err != nil {\n+\t\tt.Fatal(\"new network\")\n+\t}\n+\n+\t_, err = net.CreateEndpoint(\"ep1\")\n+\tif err != nil {\n+\t\tt.Fatal(\"createendpoint\")\n+\t}\n+}\n+\n+func debugf(format string, a ...interface{}) (int, error) {\n+\tif debug {\n+\t\treturn fmt.Printf(format, a...)\n+\t}\n+\n+\treturn 0, nil\n+}\n+\n+func parallelJoin(t *testing.T, ep libnetwork.Endpoint, thrNumber int) {\n+\tdebugf(\"J%d.\", thrNumber)\n+\t_, err := ep.Join(\"racing_container\")\n+\truntime.LockOSThread()\n+\tif err != nil {\n+\t\tif err != libnetwork.ErrNoContainer && err != libnetwork.ErrInvalidJoin {\n+\t\t\tt.Fatal(err)\n+\t\t}\n+\t\tdebugf(\"JE%d(%v).\", thrNumber, err)\n+\t}\n+\tdebugf(\"JD%d.\", thrNumber)\n+}\n+\n+func parallelLeave(t *testing.T, ep libnetwork.Endpoint, thrNumber int) {\n+\tdebugf(\"L%d.\", thrNumber)\n+\terr := ep.Leave(\"racing_container\")\n+\truntime.LockOSThread()\n+\tif err != nil {\n+\t\tif err != libnetwork.ErrNoContainer && err != libnetwork.ErrInvalidJoin {\n+\t\t\tt.Fatal(err)\n+\t\t}\n+\t\tdebugf(\"LE%d(%v).\", thrNumber, err)\n+\t}\n+\tdebugf(\"LD%d.\", thrNumber)\n+}\n+\n+func runParallelTests(t *testing.T, thrNumber int) {\n+\tvar err error\n+","path":"libnetwork_test.go","position":125,"original_position":123,"commit_id":"d3f628541cd89e0e40a96deb0e2b6cc3455d0af1","original_commit_id":"d861260b86574d078d48ebc26a5d9a6639b2c0d0","user":{"login":"mavenugo","id":5056191,"avatar_url":"https://avatars.githubusercontent.com/u/5056191?v=3","gravatar_id":"","url":"https://api.github.com/users/mavenugo","html_url":"https://github.com/mavenugo","followers_url":"https://api.github.com/users/mavenugo/followers","following_url":"https://api.github.com/users/mavenugo/following{/other_user}","gists_url":"https://api.github.com/users/mavenugo/gists{/gist_id}","starred_url":"https://api.github.com/users/mavenugo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mavenugo/subscriptions","organizations_url":"https://api.github.com/users/mavenugo/orgs","repos_url":"https://api.github.com/users/mavenugo/repos","events_url":"https://api.github.com/users/mavenugo/events{/privacy}","received_events_url":"https://api.github.com/users/mavenugo/received_events","type":"User","site_admin":false},"body":":+1: ","created_at":"2015-05-10T17:39:30Z","updated_at":"2015-05-10T17:39:30Z","html_url":"https://github.com/docker/libnetwork/pull/140#discussion_r30004265","pull_request_url":"https://api.github.com/repos/docker/libnetwork/pulls/140","_links":{"self":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/comments/30004265"},"html":{"href":"https://github.com/docker/libnetwork/pull/140#discussion_r30004265"},"pull_request":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/140"}}},"pull_request":{"url":"https://api.github.com/repos/docker/libnetwork/pulls/140","id":35075468,"html_url":"https://github.com/docker/libnetwork/pull/140","diff_url":"https://github.com/docker/libnetwork/pull/140.diff","patch_url":"https://github.com/docker/libnetwork/pull/140.patch","issue_url":"https://api.github.com/repos/docker/libnetwork/issues/140","number":140,"state":"open","locked":false,"title":"Make endpoint Join and Leave multi-thread safe","user":{"login":"mrjana","id":1693482,"avatar_url":"https://avatars.githubusercontent.com/u/1693482?v=3","gravatar_id":"","url":"https://api.github.com/users/mrjana","html_url":"https://github.com/mrjana","followers_url":"https://api.github.com/users/mrjana/followers","following_url":"https://api.github.com/users/mrjana/following{/other_user}","gists_url":"https://api.github.com/users/mrjana/gists{/gist_id}","starred_url":"https://api.github.com/users/mrjana/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrjana/subscriptions","organizations_url":"https://api.github.com/users/mrjana/orgs","repos_url":"https://api.github.com/users/mrjana/repos","events_url":"https://api.github.com/users/mrjana/events{/privacy}","received_events_url":"https://api.github.com/users/mrjana/received_events","type":"User","site_admin":false},"body":"    - Refactored the Join/Leave code so they are synchronized across multiple go-routines\r\n    - Added parallel test coverage to test mult-thread access to Join/Leave\r\n    - Updated sandbox code to revert back to caller namespace when removing interfaces\r\n    - Changed the netns path to /var/run/netns so the cleanup is simpler on machine\r\n      reboot scenario\r\n\r\nSigned-off-by: Jana Radhakrishnan <mrjana@docker.com>","created_at":"2015-05-10T00:53:54Z","updated_at":"2015-05-10T17:39:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b97c00d5654148f94dea03c60fa5d1ee8ad30a80","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/docker/libnetwork/pulls/140/commits","review_comments_url":"https://api.github.com/repos/docker/libnetwork/pulls/140/comments","review_comment_url":"https://api.github.com/repos/docker/libnetwork/pulls/comments{/number}","comments_url":"https://api.github.com/repos/docker/libnetwork/issues/140/comments","statuses_url":"https://api.github.com/repos/docker/libnetwork/statuses/d3f628541cd89e0e40a96deb0e2b6cc3455d0af1","head":{"label":"mrjana:cnm_integ","ref":"cnm_integ","sha":"d3f628541cd89e0e40a96deb0e2b6cc3455d0af1","user":{"login":"mrjana","id":1693482,"avatar_url":"https://avatars.githubusercontent.com/u/1693482?v=3","gravatar_id":"","url":"https://api.github.com/users/mrjana","html_url":"https://github.com/mrjana","followers_url":"https://api.github.com/users/mrjana/followers","following_url":"https://api.github.com/users/mrjana/following{/other_user}","gists_url":"https://api.github.com/users/mrjana/gists{/gist_id}","starred_url":"https://api.github.com/users/mrjana/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrjana/subscriptions","organizations_url":"https://api.github.com/users/mrjana/orgs","repos_url":"https://api.github.com/users/mrjana/repos","events_url":"https://api.github.com/users/mrjana/events{/privacy}","received_events_url":"https://api.github.com/users/mrjana/received_events","type":"User","site_admin":false},"repo":{"id":33910102,"name":"libnetwork","full_name":"mrjana/libnetwork","owner":{"login":"mrjana","id":1693482,"avatar_url":"https://avatars.githubusercontent.com/u/1693482?v=3","gravatar_id":"","url":"https://api.github.com/users/mrjana","html_url":"https://github.com/mrjana","followers_url":"https://api.github.com/users/mrjana/followers","following_url":"https://api.github.com/users/mrjana/following{/other_user}","gists_url":"https://api.github.com/users/mrjana/gists{/gist_id}","starred_url":"https://api.github.com/users/mrjana/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrjana/subscriptions","organizations_url":"https://api.github.com/users/mrjana/orgs","repos_url":"https://api.github.com/users/mrjana/repos","events_url":"https://api.github.com/users/mrjana/events{/privacy}","received_events_url":"https://api.github.com/users/mrjana/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mrjana/libnetwork","description":"networking for containers","fork":true,"url":"https://api.github.com/repos/mrjana/libnetwork","forks_url":"https://api.github.com/repos/mrjana/libnetwork/forks","keys_url":"https://api.github.com/repos/mrjana/libnetwork/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrjana/libnetwork/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrjana/libnetwork/teams","hooks_url":"https://api.github.com/repos/mrjana/libnetwork/hooks","issue_events_url":"https://api.github.com/repos/mrjana/libnetwork/issues/events{/number}","events_url":"https://api.github.com/repos/mrjana/libnetwork/events","assignees_url":"https://api.github.com/repos/mrjana/libnetwork/assignees{/user}","branches_url":"https://api.github.com/repos/mrjana/libnetwork/branches{/branch}","tags_url":"https://api.github.com/repos/mrjana/libnetwork/tags","blobs_url":"https://api.github.com/repos/mrjana/libnetwork/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrjana/libnetwork/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrjana/libnetwork/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrjana/libnetwork/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrjana/libnetwork/statuses/{sha}","languages_url":"https://api.github.com/repos/mrjana/libnetwork/languages","stargazers_url":"https://api.github.com/repos/mrjana/libnetwork/stargazers","contributors_url":"https://api.github.com/repos/mrjana/libnetwork/contributors","subscribers_url":"https://api.github.com/repos/mrjana/libnetwork/subscribers","subscription_url":"https://api.github.com/repos/mrjana/libnetwork/subscription","commits_url":"https://api.github.com/repos/mrjana/libnetwork/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrjana/libnetwork/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrjana/libnetwork/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrjana/libnetwork/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrjana/libnetwork/contents/{+path}","compare_url":"https://api.github.com/repos/mrjana/libnetwork/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrjana/libnetwork/merges","archive_url":"https://api.github.com/repos/mrjana/libnetwork/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrjana/libnetwork/downloads","issues_url":"https://api.github.com/repos/mrjana/libnetwork/issues{/number}","pulls_url":"https://api.github.com/repos/mrjana/libnetwork/pulls{/number}","milestones_url":"https://api.github.com/repos/mrjana/libnetwork/milestones{/number}","notifications_url":"https://api.github.com/repos/mrjana/libnetwork/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrjana/libnetwork/labels{/name}","releases_url":"https://api.github.com/repos/mrjana/libnetwork/releases{/id}","created_at":"2015-04-14T04:08:13Z","updated_at":"2015-04-17T04:44:34Z","pushed_at":"2015-05-10T17:36:36Z","git_url":"git://github.com/mrjana/libnetwork.git","ssh_url":"git@github.com:mrjana/libnetwork.git","clone_url":"https://github.com/mrjana/libnetwork.git","svn_url":"https://github.com/mrjana/libnetwork","homepage":"","size":728,"stargazers_count":0,"watchers_count":0,"language":"Go","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":"docker:master","ref":"master","sha":"731ffc20d91ed93c0eeda0785f4de4d1e2da7f80","user":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"repo":{"id":31046054,"name":"libnetwork","full_name":"docker/libnetwork","owner":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/docker/libnetwork","description":"networking for containers","fork":false,"url":"https://api.github.com/repos/docker/libnetwork","forks_url":"https://api.github.com/repos/docker/libnetwork/forks","keys_url":"https://api.github.com/repos/docker/libnetwork/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/libnetwork/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/libnetwork/teams","hooks_url":"https://api.github.com/repos/docker/libnetwork/hooks","issue_events_url":"https://api.github.com/repos/docker/libnetwork/issues/events{/number}","events_url":"https://api.github.com/repos/docker/libnetwork/events","assignees_url":"https://api.github.com/repos/docker/libnetwork/assignees{/user}","branches_url":"https://api.github.com/repos/docker/libnetwork/branches{/branch}","tags_url":"https://api.github.com/repos/docker/libnetwork/tags","blobs_url":"https://api.github.com/repos/docker/libnetwork/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/libnetwork/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/libnetwork/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/libnetwork/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/libnetwork/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/libnetwork/languages","stargazers_url":"https://api.github.com/repos/docker/libnetwork/stargazers","contributors_url":"https://api.github.com/repos/docker/libnetwork/contributors","subscribers_url":"https://api.github.com/repos/docker/libnetwork/subscribers","subscription_url":"https://api.github.com/repos/docker/libnetwork/subscription","commits_url":"https://api.github.com/repos/docker/libnetwork/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/libnetwork/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/libnetwork/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/libnetwork/issues/comments{/number}","contents_url":"https://api.github.com/repos/docker/libnetwork/contents/{+path}","compare_url":"https://api.github.com/repos/docker/libnetwork/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/libnetwork/merges","archive_url":"https://api.github.com/repos/docker/libnetwork/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/libnetwork/downloads","issues_url":"https://api.github.com/repos/docker/libnetwork/issues{/number}","pulls_url":"https://api.github.com/repos/docker/libnetwork/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/libnetwork/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/libnetwork/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/libnetwork/labels{/name}","releases_url":"https://api.github.com/repos/docker/libnetwork/releases{/id}","created_at":"2015-02-20T01:20:15Z","updated_at":"2015-05-10T12:17:37Z","pushed_at":"2015-05-10T17:36:37Z","git_url":"git://github.com/docker/libnetwork.git","ssh_url":"git@github.com:docker/libnetwork.git","clone_url":"https://github.com/docker/libnetwork.git","svn_url":"https://github.com/docker/libnetwork","homepage":"","size":2591,"stargazers_count":169,"watchers_count":169,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":40,"mirror_url":null,"open_issues_count":27,"forks":40,"open_issues":27,"watchers":169,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/140"},"html":{"href":"https://github.com/docker/libnetwork/pull/140"},"issue":{"href":"https://api.github.com/repos/docker/libnetwork/issues/140"},"comments":{"href":"https://api.github.com/repos/docker/libnetwork/issues/140/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/140/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/docker/libnetwork/pulls/140/commits"},"statuses":{"href":"https://api.github.com/repos/docker/libnetwork/statuses/d3f628541cd89e0e40a96deb0e2b6cc3455d0af1"}}}}