felipecrv commented on code in PR #38797:
URL: https://github.com/apache/arrow/pull/38797#discussion_r1399886745


##########
go/arrow/datatype_fixedwidth.go:
##########
@@ -398,10 +402,15 @@ func (t *TimestampType) ClearCachedLocation() {
 // so if you change the value of TimeZone after calling this, make sure to call
 // ClearCachedLocation.
 func (t *TimestampType) GetZone() (*time.Location, error) {
+       t.mx.RLock()
        if t.loc != nil {
+               defer t.mx.RUnlock()
                return t.loc, nil
        }
 
+       t.mx.RUnlock()
+       t.mx.Lock()
+       defer t.mx.Unlock()

Review Comment:
   Wait... :)
   
   A full execution of `GetZone` is possible between `RUnlock()` and `Lock()`, 
so it's probably a good idea to check `t.loc` after the write lock is acquired.
   
   For a lock-free way of doing this, you can combine atomic load/stores with a 
writers-only mutex. Porting this C++ snippet [1] to Go:
   
   ```cpp
   std::atomic<Singleton*> Singleton::m_instance;
   std::mutex Singleton::m_mutex;
   
   Singleton* Singleton::getInstance() {
       Singleton* tmp = m_instance.load();
       if (tmp == nullptr) {
           std::lock_guard<std::mutex> lock(m_mutex);
           tmp = m_instance.load();
           if (tmp == nullptr) {
               tmp = new Singleton;
               m_instance.store(tmp);
           }
       }
       return tmp;
   }
   ```
   
   [1] 
https://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/#using-c11-sequentially-consistent-atomics
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to