• Kirill Smelkov's avatar
    libgolang: Fix globals atexit race condition of ~refptr vs access from another thread · fd2a6fab
    Kirill Smelkov authored
    Until now we were defining errors like this:
    
        const error ErrSomething  = errors::New("abc");
    
    However there is a problem here: the runtime will call ErrSomething
    destructor on program exit, and for refptr<T> the destructor does 2
    things: a) decrefs the object, and b) switches embedded pointer to NULL;
    
    If another thread is still running both "a" and "b" can become race
    conditions if that T2 uses ErrSomething via e.g. just
    
        ...
        if (err == ErrSomething)
            ...
    
    Here is, for example TSAN report about ErrPyStopped usage when accessed by timer thread:
    
        WARNING: ThreadSanitizer: data race (pid=4224)
         Read of size 8 at 0x7f0d6840e150 by thread T92:
           #0 golang::refptr<golang::_error>::refptr(golang::refptr<golang::_error> const&) golang/libgolang.h:525 (liblibpyxruntime.so.0.1+0x4edc)
           #1 golang::pyx::runtime::PyFunc::operator()() const golang/runtime/libpyxruntime.cpp:222 (liblibpyxruntime....
    fd2a6fab