Subject: [boost] Proposal for a thread "collision" detector
From: Gaetano Mendola (mendola_at_[hidden])
Date: 2013-06-14 06:43:36


I would like to know if Boost community could be interested in
adopting a check mechanism that is able to detect if a not supposed
thread safe class is used by multiple threads in unsafe way. This
tecnique has saved us a lot of headache especially when code refactoring
on old code is performed.

Better to explain it, without enter in the detail of the implementation,
with some examples:

Example: Queue implementation non thread-safe but still usable if clients
         are synchronized somehow.

  class NonThreadSafeQueue {
   public:
    ...
    void push(int) { DFAKE_SCOPED_LOCK(push_pop_); ... }
    int pop() { DFAKE_SCOPED_LOCK(push_pop_); ... }
    ...
   private:
    DFAKE_MUTEX(push_pop_);
  };

 Example: Queue implementation not usable even if clients are synchronized,
          so only one thread in the class life cycle can use the two members
          push/pop.

          In this case the macro DFAKE_SCOPED_LOCK_THREAD_LOCKED pins the
          specified critical section the first time a thread enters push or
          pop, from that time on only that thread is allowed to execute push
          or pop.

  class NonThreadSafeQueue {
   public:
    ...
    void push(int) { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... }
    int pop() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... }
    ...
   private:
    DFAKE_MUTEX(push_pop_);
  };

  Example: Class that has to be contructed/destroyed on same thread, it has
           a "shareable" method (with external syncronization) and a not
           shareable method (even with external synchronization).

           In this case 3 Critical sections have to be defined

  class ExoticClass {
   public:
    ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }
    ~ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }

    void Shareable() { DFAKE_SCOPED_LOCK(shareable_section_); ... }
    void NotShareable() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }
    ...
   private:
    DFAKE_MUTEX(ctor_dtor_)
    DFAKE_MUTEX(shareable_section_)
  };

DFAKE_SCOPED_LOCK will "throw an exception" or will call an "abort" in
case of check failed.

This tecnique doesn't involve real lock/unlock but uses atomic operations, also
the various macros DFAKE_XXXXXXXXX are defined void when NDEBUG is defined.

Any comment is appreciated.

Regards
Gaetano Mendola