0

Preconditions:

I have to fix synchonization issues in very big legacy spaghetty codebase. There are some classes that must be synchronized. But there are lots of usages for these classes. It is why I am looking for way to catch issues with debug guards.

There is one of ideas to report problem in usage of some classes.

Class for debug purposes:

public class AsyncChecker {

    private readonly Thread myThread;
    private volatile bool myTurnedOn;

    public AsyncChecker() {
        myThread = Thread.CurrentThread;
        myTurnedOn = false;
    }

    public void turnOn() {
        myTurnedOn = true;
    }

    public void checkThread() {
        if ( myTurnedOn && Thread.CurrentThread != myThread ) {
            Debug.LogError( "illegal thread" );
        }
    }

    public void checkMultiThreadSafety() {
        if ( myTurnedOn ) {
            //there is code that can determine if method called from critical
            //section or not even if we call from the same thread
            //Monitor.IsEntered(  ) works only if there is call from another thread
        }
    }
}

Some legacy class that can or cannot be accessed in concurrency:

public class SomeLogic {

    private readonly AsyncChecker myAsyncChecker = new AsyncChecker();

    public void logicOne() {
        myAsyncChecker.checkMultiThreadSafety();
        //some logic A
    }

    public void logicTwo() {
        myAsyncChecker.checkMultiThreadSafety();
        //some logic B
    }
}

There is purpose:

public void someMethodInDeepLegacyCode() {
    lock (someLock) {
        someLogicClassInstance.logicOne();
    }
}
public void anotherSomeMethodInDeepLegacyCode() {
    someLogicClassInstance.logicTwo(); //there is access without synchronization, 
    //would like to have exception, or assertion, or error log or something else
}

Monitor.IsEntered can be used only partially. Only if we called from different thread but not for the same.

zhu
  • 1
  • 3
  • Having a hard time understanding your English. Are you saying that you would like `anotherSomeMethodInDeepLegacyCode()` to log an error because `someLock` is not locked? – Solomon Slow Feb 05 '23 at 01:28
  • The code in your example will log an error if a `SomeLogic` instance is used by a different thread from the thread that created it, but there doesn't seem to be any code in `SomeLogic` or `AsyncChecker` that knows anything about the critical section(s) that is/are protected by `someLock`. – Solomon Slow Feb 05 '23 at 01:48
  • 2
    P.S., Instead of adding code to the `SomeLogic` class to test whether `someLock` is locked, why can't you simply add code to those methods to _lock_ it? The fact that `someMethodInDeepLegacyCode` has already locked `someLock` before it calls `logicOne` should not be a problem because`lock` statements in C# use [_reentrant locking_](https://stackoverflow.com/a/1312282/801894). – Solomon Slow Feb 05 '23 at 01:53
  • I understand how to use reentrant lock, question is about how to detect, in very large spagetty code, places where SomeLogic nethods are not under locks due to lots usages amoung different places. – zhu Feb 05 '23 at 12:17

0 Answers0