{"action":"created","issue":{"url":"https://api.github.com/repos/OData/odata.net/issues/693","repository_url":"https://api.github.com/repos/OData/odata.net","labels_url":"https://api.github.com/repos/OData/odata.net/issues/693/labels{/name}","comments_url":"https://api.github.com/repos/OData/odata.net/issues/693/comments","events_url":"https://api.github.com/repos/OData/odata.net/issues/693/events","html_url":"https://github.com/OData/odata.net/issues/693","id":173207724,"number":693,"title":"V3 Client deadlock issue in multi-thread","user":{"login":"LaylaLiu","id":6811112,"avatar_url":"https://avatars.githubusercontent.com/u/6811112?v=3","gravatar_id":"","url":"https://api.github.com/users/LaylaLiu","html_url":"https://github.com/LaylaLiu","followers_url":"https://api.github.com/users/LaylaLiu/followers","following_url":"https://api.github.com/users/LaylaLiu/following{/other_user}","gists_url":"https://api.github.com/users/LaylaLiu/gists{/gist_id}","starred_url":"https://api.github.com/users/LaylaLiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LaylaLiu/subscriptions","organizations_url":"https://api.github.com/users/LaylaLiu/orgs","repos_url":"https://api.github.com/users/LaylaLiu/repos","events_url":"https://api.github.com/users/LaylaLiu/events{/privacy}","received_events_url":"https://api.github.com/users/LaylaLiu/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-08-25T13:47:51Z","updated_at":"2016-11-10T01:40:39Z","closed_at":"2016-11-10T01:40:39Z","body":"Deadlock might happen when two threads accessing the same type on client side.\n\nAssemblies : Microsoft.Data.Services.Client/Microsoft.Data.Edm 5.7.0\n\nAlthough, we have different DataServiceContext for different threads. But since DataServiceContext has a model which is from a static modelCache. So different DataServiceContext in the same process share the same model. \n\nThen in client code, There are four instances which are used by these two threads.\n1.  A ClientTypeAnnotation instance \n2.  A EdmComplexTypeWithDelayLoadedProperties instance (this is a property of the ClientTypeAnnotation instance) \n3.  A propertiesDictionary cache instance (this is a private field of the EdmComplexTypeWithDelayLoadedProperties instance)\n4.  An object used for lock in the EnsurePropertyLoaded() method in EdmComplexTypeWithDelayLoadedProperties\n\nThen here came the two threads.\n\n1f80:\n1f80 was tring to FindProperty from the EdmComplexTypeWithDelayLoadedProperties instance which finally accessed the propertiesDictionary to get its properties by using following code:\n\n```\n    protected IDictionary<string, IEdmProperty> PropertiesDictionary\n    {\n        get { return this.propertiesDictionary.GetValue(this, ComputePropertiesDictionaryFunc, null); }\n    }\n```\n1.  In the GetValue method, this.propertiesDictionary (it is of Microsoft.Data.Edm.Internal.Cache type) locked itself.\n2.  It called the ComputePropertiesDictionaryFunc which called the EnsurePropertyLoaded() method. EnsurePropertyLoaded() tried to lock the private object ( it is of System.Object type).\n\n1b60:\n1b60 was trying to use the same EdmComplexTypeWithDelayLoadedProperties instance to get its DeclaredProperties which called EnsurePropertyLoaded()\n1.  EnsurePropertyLoaded locked the private object (same as the one in step 2 that 1f80 thread tried to lock)\n2.  Then it called propertyLoadAction to load property which will finally call the following API.\npublic void AddProperty(IEdmProperty property)\n        {\n            …\n            this.declaredProperties.Add(property);\n            this.propertiesDictionary.Clear(null);\n        }\nYou will find that it called this.propertiesDictionary.Clear(null) in which it tried to lock itself (same as the propertiesDictionary in step 1 of 1f80 which tried to lock)\n\nThen the deadlock happened. \n"},"comment":{"url":"https://api.github.com/repos/OData/odata.net/issues/comments/259579060","html_url":"https://github.com/OData/odata.net/issues/693#issuecomment-259579060","issue_url":"https://api.github.com/repos/OData/odata.net/issues/693","id":259579060,"user":{"login":"LaylaLiu","id":6811112,"avatar_url":"https://avatars.githubusercontent.com/u/6811112?v=3","gravatar_id":"","url":"https://api.github.com/users/LaylaLiu","html_url":"https://github.com/LaylaLiu","followers_url":"https://api.github.com/users/LaylaLiu/followers","following_url":"https://api.github.com/users/LaylaLiu/following{/other_user}","gists_url":"https://api.github.com/users/LaylaLiu/gists{/gist_id}","starred_url":"https://api.github.com/users/LaylaLiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LaylaLiu/subscriptions","organizations_url":"https://api.github.com/users/LaylaLiu/orgs","repos_url":"https://api.github.com/users/LaylaLiu/repos","events_url":"https://api.github.com/users/LaylaLiu/events{/privacy}","received_events_url":"https://api.github.com/users/LaylaLiu/received_events","type":"User","site_admin":false},"created_at":"2016-11-10T01:40:39Z","updated_at":"2016-11-10T01:40:39Z","body":"Fixed by using a single lock for both base type and derived type."}}
{"actor":{"display_login":"LaylaLiu"}}