Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-5225

Mongo Serialization Deadlock

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 3.0.0
    • Affects Version/s: 2.25.0
    • Component/s: Serialization
    • None
    • Fully Compatible
    • Dotnet Drivers
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Hi, 

      During using the MongoDrive, I encounter a deadlock issue which cause the whole application loading data blocked. After doing few research, I figured out the issue was caused by two collections had the same generic parameters, but different dictionary representaion properties. 

      Two threads' call stack as follows:

       
      A Thread:
      -> DictionarySerializerBase<TDictionary, TKey, TValue>.DeserializeValue
      -> Lazy<T>.CreateValue
      -> Lazy<T>.ExecutionAndPublication
      -> Lazy<T>.ViaFactory
      -> BsonSerializerRegistry.GetSerializer
      -> BsonClassMapSerializationProvider.GetSerializer
      -> BsonClassMap.LookupClassMap
      -> BsonSerializer.ConfigLock.EnterReadLock (deadlock)

      B Thread:
      -> BsonSerializerRegistry.CreateSerializer
      -> BsonClassMap.LookupClassMap
      -> BsonSerializer.ConfigLock.EnterWriteLock
      -> BsonClassMap.AutoMap
      -> AttributeConventionPack+AttributeConvention.Apply
      -> DictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>.WithDictionaryRepresentation
      -> DictionarySerializerBase.get_ValueSerializer
      -> Lazy<T>.CreateValue
      -> Lazy<T>.ExecutionAndPublication (deadlock)
       

      1. Thread A first used the default seirializer and registered the DictionaryInterfaceImplementerSerializer

      color: Color value is invalid

      to the

      ** BsonSerializerRegistry.

      color: Color value is invalid

      Visited the

      **

      color: Color value is invalid

      ValueSerializer and casued a lazy object to be created. Finally the thread started to wait for the read lock.

       
      2. Tread B then used the non-default seirializer. The thread got the readlock and need to get a instance from the DictionaryInterfaceImplementerSerializer which need to visit ** its *

      color: Color value is invalid

      ValueSerializer.

      *

      color: Color value is invalid

      Which caused a lazy object creation and lock.

      This bug can reproduced by the code below 
       

      var testData = new TestData { Items = new Dictionary<string, Item>() { { "1", new Item() } } };
      var testData2 = new TestData2 { Items = new Dictionary<string, Item>() { { "2", new Item() } } };
      
      BsonSerializer.SerializerRegistry.GetSerializer<Dictionary<int, Item>>();
      
      _ = Task.Run(() =>
      {
          var stream = new MemoryStream();
          using var bsonWriter = new BsonBinaryWriter(stream);
          BsonSerializer.Serialize(bsonWriter, testData);
      });
      
      await Task.Delay(TimeSpan.FromMilliseconds(100));
      
      {
          var stream = new MemoryStream();
          using var bsonWriter = new BsonBinaryWriter(stream);
          BsonSerializer.Serialize(bsonWriter, testData2);
      }
      
      Console.WriteLine("Hello, World!");
      
      public class Item;
      
      public class TestData
      {
          public Dictionary<string, Item> Items { get; set; } = new();
      }
      
      public class TestData2
      {
          [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
          public Dictionary<string, Item> Items { get; set; } = new();
      }
      

      The modification in the driver as the attachment shows can also increase the probibility to reproduce this issue.
       
      Best Regards.
      Renqiu

            Assignee:
            oleksandr.poliakov@mongodb.com Oleksandr Poliakov
            Reporter:
            chenrenqiu@kurogames.com Renqiu Chen
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: