# HG changeset patch # User Benjamin Golinvaux # Date 1604486355 -3600 # Node ID 74be0f498b08aadf2739062d94173e1b0770542d # Parent 0f8d6791b403471e436b6632b8a7a923848c0f93 Updated mechanism to avoid using deleted objects in RequestAnimationFrame callbacks. diff -r 0f8d6791b403 -r 74be0f498b08 Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp --- a/Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp Tue Nov 03 07:04:02 2020 +0100 +++ b/Applications/Platforms/WebAssembly/WebAssemblyViewport.cpp Wed Nov 04 11:39:15 2020 +0100 @@ -137,10 +137,10 @@ } else { - LOG(INFO) << "WebAssemblyViewport::OnRequestAnimationFrame " - << "-- the WebAssemblyViewport is deleted and Paint will " - << "not be called"; + LOG(TRACE) << "WebAssemblyViewport::OnRequestAnimationFrame: the " << + "WebAssemblyViewport is deleted and Paint will not be called."; } + WebAssemblyViewport::ReleaseObjectCookie(userData); LOG(TRACE) << "Exiting: " << __func__; return true; } @@ -220,36 +220,26 @@ return true; } - void* WebAssemblyViewport::GetObjectCookie() + void* WebAssemblyViewport::CreateObjectCookie() { - if(objectCookie_ != NULL) - return objectCookie_; - - boost::shared_ptr* sharedFromThisPtr = - new boost::shared_ptr(); - - *sharedFromThisPtr = shared_from_this(); - - objectCookie_ = reinterpret_cast(sharedFromThisPtr); + boost::weak_ptr* weakThisPtr = + new boost::weak_ptr(); - return objectCookie_; - } + *weakThisPtr = shared_from_this(); + + void* cookie = reinterpret_cast(weakThisPtr); - void WebAssemblyViewport::ReleaseObjectCookie(void* cookie) - { - WebAssemblyViewport* This = DereferenceObjectCookie(cookie); - - if (This != NULL) - This->objectCookie_ = NULL; + LOG(TRACE) << "WebAssemblyViewport::CreateObjectCookie() => cookie = " + << cookie << "\n"; - boost::weak_ptr* weakThisPtr = - reinterpret_cast*>(cookie); - - delete weakThisPtr; + return cookie; } WebAssemblyViewport* WebAssemblyViewport::DereferenceObjectCookie(void* cookie) { + LOG(TRACE) << "WebAssemblyViewport::DereferenceObjectCookie(cookie = " + << cookie << ")\n"; + boost::weak_ptr* weakThisPtr = reinterpret_cast*>(cookie); @@ -258,11 +248,23 @@ return sharedThis.get(); } + void WebAssemblyViewport::ReleaseObjectCookie(void* cookie) + { + LOG(TRACE) << "WebAssemblyViewport::ReleaseObjectCookie(cookie = " + << cookie << ")\n"; + + boost::weak_ptr* weakThisPtr = + reinterpret_cast*>(cookie); + + delete weakThisPtr; + } + void WebAssemblyViewport::Invalidate() { + LOG(TRACE) << "WebAssemblyViewport::Invalidate()\n"; long id = emscripten_request_animation_frame(OnRequestAnimationFrame, - GetObjectCookie()); - animationFrameCallbackIds_.push_back(id); + CreateObjectCookie()); + //animationFrameCallbackIds_.push_back(id); } void WebAssemblyViewport::FitForPrint() @@ -305,8 +307,7 @@ interactor_(new DefaultViewportInteractor), enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents), canvasWidth_(0), - canvasHeight_(0), - objectCookie_(NULL) + canvasHeight_(0) { } @@ -370,13 +371,8 @@ WebAssemblyViewport::~WebAssemblyViewport() { - // cancel the pending RequestAnimationFrame callbacks - for(size_t i = 0; i < animationFrameCallbackIds_.size(); ++i) - { - long id = animationFrameCallbackIds_[i]; - emscripten_cancel_animation_frame(id); - } - + LOG(TRACE) << "WebAssemblyViewport::~WebAssemblyViewport()\n"; + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, reinterpret_cast(this), false, diff -r 0f8d6791b403 -r 74be0f498b08 Applications/Platforms/WebAssembly/WebAssemblyViewport.h --- a/Applications/Platforms/WebAssembly/WebAssemblyViewport.h Tue Nov 03 07:04:02 2020 +0100 +++ b/Applications/Platforms/WebAssembly/WebAssemblyViewport.h Wed Nov 04 11:39:15 2020 +0100 @@ -61,8 +61,6 @@ bool enableEmscriptenMouseEvents_; unsigned int canvasWidth_; unsigned int canvasHeight_; - std::vector animationFrameCallbackIds_; - void* objectCookie_; static EM_BOOL OnRequestAnimationFrame(double time, void *userData); @@ -109,12 +107,12 @@ * This cookie is a resource and must be freed when it is guaranteed * not to be used anymore, with ReleaseObjectCookie */ - void* GetObjectCookie(); + void* CreateObjectCookie(); /** * This static method can be used to dereference a cookie (i.e. retrieve * a pointer to the underlying object) that has been created with - * WebAssemblyViewport::GetObjectCookie() + * WebAssemblyViewport::CreateObjectCookie() * * If this method returns NULL, it basically means that the * WebAssemblyViewport has already been deleted and that you should NOT @@ -128,7 +126,7 @@ * go wrong. * * NEVER call this method on a void* that has not been generated by the - * GetObjectCookie method of this class + * CreateObjectCookie method of this class */ static WebAssemblyViewport* DereferenceObjectCookie(void* cookie); diff -r 0f8d6791b403 -r 74be0f498b08 Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Tue Nov 03 07:04:02 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Wed Nov 04 11:39:15 2020 +0100 @@ -1793,7 +1793,7 @@ virtual ~ViewerViewport() { // Unregister the callbacks to avoid any call with a "void*" that - // has been destroyed. "WebAssemblyViewport::GetObjectCookie()" + // has been destroyed. "WebAssemblyViewport::CreateObjectCookie()" // provides a more advanced alternative. emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, NULL); emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL);