Menu

#302 Deadlock in Persistent Streams

6.40.6
closed
1
2015-09-26
2015-03-02
No

After fixes in 6.40 for multi-threading issues, there is a deadlock in the persistent streams, more specifically in __TStreamableCont::CreateTypes, defined in "objstrm.cpp".

This issue was reported by Igor Epatko (wavesimsoft). See "object stream (objstrm) issue" [discussion:25092ed5] in the Open Discussion forum.

Related

Discussion: 25092ed5
Discussion: object stream (objstrm) issue
Discussion: object stream (objstrm) issue
Wiki: OWLNext_Stable_Releases

Discussion

  • Igor Epatko

    Igor Epatko - 2015-03-09
    • status: open --> pending
    • assigned_to: Igor Epatko
     
  • Vidar Hasfjord

    Vidar Hasfjord - 2015-03-11
    • status: pending --> open

    Before setting the ticket status to "pending", please check in the fix and post an update including a link to the revision, e.g. "This issue has been fixed [r42]".

     

    Related

    Commit: [r42]


    Last edit: Vidar Hasfjord 2015-03-11
  • Vidar Hasfjord

    Vidar Hasfjord - 2015-04-16

    Hi Igor, are you working on this bug?

    There is a problem with your proposed fix:

    :::C++
    if (!Types)
    {
      LOCKTYPES(false);
      Types = new TStreamableTypes;
    }
    


    This code sequence allows multiple threads to enter the if-clause at once, leading to multiple initialisation of Types. Naively, we may handle this issue using double-checking:

    :::C++
    if (!Types)
    {
      LOCKTYPES(false);
      if (!Types)
        Types = new TStreamableTypes;
    }
    


    However, this may still not be 100% safe due to the way the compiler and CPU might rearrange instructions and memory accesses. See Double-checked locking at Wikipedia for an explanation of the issues.

    That said, I think this solution is good enough. It is already unsafe to multi-thread OWLNext (see Multi-threading and OWLNext), and we advice against it, so the slight possibility of a problem here does not matter much.

     

    Related

    Wiki: Multi-threading_and_OWLNext

  • Vidar Hasfjord

    Vidar Hasfjord - 2015-04-16

    By the way, the existing preceding code is not thread-safe either:

    :::C++
    #if defined(BI_MULTI_THREAD_RTL)
      if(!Lock)
      {
        Lock = new TMRSWSection;
      }
    #endif
    


    Here, multiple threads may enter the if-clause at the same time. Also, the compiler may rearrange instructions so that Lock is assigned before completing the constructor, after which a secondary thread may skip the if-clause and proceed to use Lock pointing to an uninitialised (or partially initialised) object.

     
  • Vidar Hasfjord

    Vidar Hasfjord - 2015-04-16
    • status: open --> pending

    This issue was fixed in [r3004], and merged into 6.40 in [r3005].

    Note the multi-threading issues pointed out in the preceding posts. The fix does not attempt to handle these issues. It only circumvents the reentrancy deadlock.

     

    Related

    Commit: [r3004]
    Commit: [r3005]


    Last edit: Vidar Hasfjord 2015-04-16
  • Vidar Hasfjord

    Vidar Hasfjord - 2015-04-19
    • Status: pending --> closed
     
  • Vidar Hasfjord

    Vidar Hasfjord - 2015-09-26
    • labels: Multi-threading, Serialization --> Multi-threading, Serialization, Persistent Streams
     

Log in to post a comment.

MongoDB Logo MongoDB