Changeset: 13374cbb2603 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/13374cbb2603
Modified Files:
        gdk/gdk_bbp.c
        gdk/gdk_bbp.h
Branch: Jul2021
Log Message:

Fix race condition between subcommit and bat unload in decref.


diffs (100 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -2331,6 +2331,7 @@ decref(bat i, bool logical, bool release
            (BBP_lrefs(i) > 0 &&
             (b == NULL ||
              (BATdirty(b) && (BBP_status(i) & BBPHOT)) ||
+             (BBP_status(i) & BBPSYNCING) || /* no swap during (sub)commit */
              (BBP_status(i) & (BBPPERSISTENT | BBPHOT)) == BBPHOT ||
              GDKinmemory(b->theap->farmid)))) {
                /* bat cannot be swapped out */
@@ -3097,6 +3098,7 @@ BBPsync(int cnt, bat *restrict subcommit
        gdk_return ret = GDK_SUCCEED;
        int t0 = 0, t1 = 0;
        str bakdir, deldir;
+       const bool lock = locked_by == 0 || locked_by != MT_getpid();
 
        if(!(bakdir = GDKfilepath(0, NULL, subcommit ? SUBDIR : BAKDIR, NULL)))
                return GDK_FAIL;
@@ -3115,18 +3117,40 @@ BBPsync(int cnt, bat *restrict subcommit
 
                while (++idx < cnt) {
                        bat i = subcommit ? subcommit[idx] : idx;
+                       if (lock)
+                               MT_lock_set(&GDKswapLock(i));
+                       /* set flag that we're syncing, i.e. that we'll
+                        * be between moving heap to backup dir and
+                        * saving the new version */
+                       BBP_status_on(i, BBPSYNCING);
+                       /* wait until unloading is finished before
+                        * attempting to make a backup */
+                       while (BBP_status(i) & BBPUNLOADING) {
+                               if (lock)
+                                       MT_lock_unset(&GDKswapLock(i));
+                               BBPspin(i, __func__, BBPUNLOADING);
+                               if (lock)
+                                       MT_lock_set(&GDKswapLock(i));
+                       }
                        BAT *b = dirty_bat(&i, subcommit != NULL);
                        if (i <= 0)
                                break;
                        if (BBP_status(i) & BBPEXISTING) {
-                               if (b != NULL && BBPbackup(b, subcommit != 
NULL) != GDK_SUCCEED)
+                               if (b != NULL && BBPbackup(b, subcommit != 
NULL) != GDK_SUCCEED) {
+                                       BBP_status_off(i, BBPSYNCING);
+                                       if (lock)
+                                               MT_lock_unset(&GDKswapLock(i));
                                        break;
+                               }
                        } else if (subcommit && (b = BBP_desc(i)) && 
BBP_status(i) & BBPDELETED) {
                                char o[10];
                                char *f;
                                snprintf(o, sizeof(o), "%o", (unsigned) 
b->batCacheid);
                                f = GDKfilepath(b->theap->farmid, BAKDIR, o, 
gettailname(b));
                                if (f == NULL) {
+                                       BBP_status_off(i, BBPSYNCING);
+                                       if (lock)
+                                               MT_lock_unset(&GDKswapLock(i));
                                        ret = GDK_FAIL;
                                        goto bailout;
                                }
@@ -3135,6 +3159,9 @@ BBPsync(int cnt, bat *restrict subcommit
                                GDKfree(f);
                                f = GDKfilepath(b->theap->farmid, BAKDIR, o, 
"theap");
                                if (f == NULL) {
+                                       BBP_status_off(i, BBPSYNCING);
+                                       if (lock)
+                                               MT_lock_unset(&GDKswapLock(i));
                                        ret = GDK_FAIL;
                                        goto bailout;
                                }
@@ -3142,6 +3169,8 @@ BBPsync(int cnt, bat *restrict subcommit
                                        file_move(b->theap->farmid, BAKDIR, 
SUBDIR, o, "theap");
                                GDKfree(f);
                        }
+                       if (lock)
+                               MT_lock_unset(&GDKswapLock(i));
                }
                if (idx < cnt)
                        ret = GDK_FAIL;
@@ -3162,6 +3191,8 @@ BBPsync(int cnt, bat *restrict subcommit
                                if (b != NULL && BATsave(b) != GDK_SUCCEED)
                                        break;  /* write error */
                        }
+                       /* we once again have a saved heap */
+                       BBP_status_off(i, BBPSYNCING);
                }
                if (idx < cnt)
                        ret = GDK_FAIL;
diff --git a/gdk/gdk_bbp.h b/gdk/gdk_bbp.h
--- a/gdk/gdk_bbp.h
+++ b/gdk/gdk_bbp.h
@@ -52,6 +52,7 @@
 #define BBPWAITING      (BBPUNLOADING|BBPLOADING|BBPSAVING|BBPDELETING)
 
 #define BBPHOT         4096    /* bat is "hot", i.e. is still in active use */
+#define BBPSYNCING     8192
 
 #define BBPTRIM_ALL    (((size_t)1) << (sizeof(size_t)*8 - 2)) /* very large 
positive size_t */
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to