Fix T39446: Blender Crashes when Camera Tracking
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 1 Apr 2014 07:14:37 +0000 (13:14 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 1 Apr 2014 07:14:37 +0000 (13:14 +0600)
Issue is likely caused by thread-unsafe nature of IMB_freeImBuf
which might lead to race condition in some circumstances.

Now made it thread-safe and from Sebastian's tests seems crash is
gone now, so hopefully the root of the issue is finally nailed down.

source/blender/imbuf/intern/IMB_allocimbuf.h
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/module.c

index 02b738cc2cd7f13f6f7fb5511f95c3e274e35dd2..f4d6d869f1b7ae37261ebcde149852dba6cd9c25 100644 (file)
@@ -35,6 +35,9 @@
 
 struct ImBuf;
 
+void imb_refcounter_lock_init(void);
+void imb_refcounter_lock_exit(void);
+
 bool imb_addencodedbufferImBuf(struct ImBuf *ibuf);
 bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf);
 
index d7ca381bae6aa314bb24464133834876c951cd2a..d0e81f2f383a17c34bd391cad307ef060ef5c200 100644 (file)
 #include "MEM_CacheLimiterC-Api.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_threads.h"
+
+static SpinLock refcounter_spin;
+
+void imb_refcounter_lock_init(void)
+{
+       BLI_spin_init(&refcounter_spin);
+}
+
+void imb_refcounter_lock_exit(void)
+{
+       BLI_spin_end(&refcounter_spin);
+}
 
 void imb_freemipmapImBuf(ImBuf *ibuf)
 {
@@ -154,10 +167,18 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf)
 void IMB_freeImBuf(ImBuf *ibuf)
 {
        if (ibuf) {
+               bool needs_free = false;
+
+               BLI_spin_lock(&refcounter_spin);
                if (ibuf->refcounter > 0) {
                        ibuf->refcounter--;
                }
                else {
+                       needs_free = true;
+               }
+               BLI_spin_unlock(&refcounter_spin);
+
+               if (needs_free) {
                        imb_freerectImBuf(ibuf);
                        imb_freerectfloatImBuf(ibuf);
                        imb_freetilesImBuf(ibuf);
@@ -177,7 +198,9 @@ void IMB_freeImBuf(ImBuf *ibuf)
 
 void IMB_refImBuf(ImBuf *ibuf)
 {
+       BLI_spin_lock(&refcounter_spin);
        ibuf->refcounter++;
+       BLI_spin_unlock(&refcounter_spin);
 }
 
 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
index 9141dad6f9c33971b02bce3b19174f7497d61b9a..4097deb00edeaa3426acfb88e760f67bced26be5 100644 (file)
 
 
 #include <stddef.h>
+
+#include "BLI_utildefines.h"
+
+#include "IMB_allocimbuf.h"
 #include "IMB_imbuf.h"
 #include "IMB_filetype.h"
 #include "IMB_colormanagement_intern.h"
 
 void IMB_init(void)
 {
+       imb_refcounter_lock_init();
        imb_filetypes_init();
        imb_tile_cache_init();
        colormanagement_init();
@@ -42,5 +47,6 @@ void IMB_exit(void)
        imb_tile_cache_exit();
        imb_filetypes_exit();
        colormanagement_exit();
+       imb_refcounter_lock_exit();
 }