<div dir="ltr"><div>Hi,</div><div><br></div><div>For what it's worth, In the Python package named rasterio we're using the push/pop API: <a href="https://github.com/mapbox/rasterio/blob/master/rasterio/_env.pyx#L336">https://github.com/mapbox/rasterio/blob/master/rasterio/_env.pyx#L336</a>. While Rust's needs may differ, a single handler without any support for user data works well for Python: everything goes to the logging infrastructure, one of the kind of globals that Howard refers to in <a href="https://github.com/OSGeo/gdal/blob/master/gdal/doc/source/development/rfc/rfc37_cplerror_userdata.rst#rationale">https://github.com/OSGeo/gdal/blob/master/gdal/doc/source/development/rfc/rfc37_cplerror_userdata.rst#rationale</a>, and Python developers extend the logger if they want behavior that is different from the basic defaults. </div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Sep 12, 2021 at 8:12 AM Even Rouault <<a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    <p>Hi,</p>
    <p>no there's no thread safe API to do what you want. You'd need a
      new function<br>
    </p>
    <p>CPLErrorHandler CPLSetErrorHandlerEx2( CPLErrorHandler
      pfnErrorHandlerNew, void* pUserData, void** ppOldUserData )</p>
    <p>to do that.</p>
    <p>But as you mention threads that might compete to set an error
      handler, using CPLSetErrorHandlerEx() is probably not the best
      strategy. You'd be better with CPLPushErrorHandler() /
      CPLPopErrorHandler() that only affects the current thread.</p>
    <p>Even<br>
    </p>
    <div>Le 12/09/2021 à 16:03, Rajsekar
      Manokaran a écrit :<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">
        <div>Hi,</div>
        <div><br>
        </div>
        <div>In the gdal rust bindings (<a href="https://github.com/georust/gdal" target="_blank">https://github.com/georust/gdal</a>),
          we're trying to facilitate the use of CPLSetErrorHandlerEx and
          related APIs.  While setting a handler, we may pass a heap
          allocated data pointer to the second argument, which is then
          read via the CPLGetErrorHandlerUserData in the handler and
          passed to the user.</div>
        <div><br>
        </div>
        <div>However, while removing or setting another handler, we're
          unable to find a race-free method to get the associated user
          data of the previous handler.   This is needed to properly
          deallocate the memory.</div>
        <div><br>
        </div>
        <div>Is there an atomic way to get both the previous handler (as
          returned by CPLSetErrorHandler), along with the associated
          user data?  The issue with making two calls, is that another
          thread might make changes in between the two calls.</div>
        <div><br>
        </div>
        <div>We could synchronize in our API, but it still has the same
          issue if the user parallely used the C APIs directly or via a
          different interface.<br>
        </div>
        <br>
        <div>Relevant PR in rust gdal bindings: <a href="https://github.com/georust/gdal/pull/215" target="_blank">https://github.com/georust/gdal/pull/215</a></div>
        <div><br>
        </div>
        <div>-</div>
        <div>Regards</div></div></blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">Sean Gillies</div></div></div>