Changeset: bf17d5c6f4b7 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=bf17d5c6f4b7
Modified Files:
        gdk/gdk_align.c
        gdk/gdk_bat.c
        gdk/gdk_bbp.c
        gdk/gdk_private.h
        gdk/gdk_storage.c
Branch: default
Log Message:

Check for errors higher up in the code instead of producing a fatal error.
When we can't extend the BBP for some reason (too many IDs or no
memory), return an error.


diffs (222 lines):

diff --git a/gdk/gdk_align.c b/gdk/gdk_align.c
--- a/gdk/gdk_align.c
+++ b/gdk/gdk_align.c
@@ -183,7 +183,14 @@ VIEWcreate_(oid seq, BAT *b, int slice_v
        bn->timprints = NULL;
        /* Order OID index */
        bn->torderidx = NULL;
-       BBPcacheit(bn, 1);      /* enter in BBP */
+       if (BBPcacheit(bn, 1) != GDK_SUCCEED) { /* enter in BBP */
+               if (tp)
+                       BBPunshare(tp);
+               if (bn->tvheap)
+                       BBPunshare(bn->tvheap->parentid);
+               GDKfree(bn);
+               return NULL;
+       }
        return bn;
 }
 
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -101,7 +101,10 @@ BATcreatedesc(oid hseq, int tt, int heap
        /*
         * add to BBP
         */
-       BBPinsert(bn);
+       if (BBPinsert(bn) == 0) {
+               GDKfree(bn);
+               return NULL;
+       }
        /*
        * Default zero for order oid index
        */
@@ -204,7 +207,10 @@ BATnewstorage(oid hseq, int tt, BUN cap,
                goto bailout;
        }
        DELTAinit(bn);
-       BBPcacheit(bn, 1);
+       if (BBPcacheit(bn, 1) != GDK_SUCCEED) {
+               GDKfree(bn->tvheap);
+               goto bailout;
+       }
        return bn;
   bailout:
        HEAPfree(&bn->theap, 1);
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -333,19 +333,23 @@ BBPselectfarm(int role, int type, enum h
  * BBPextend must take the trimlock, as it is called when other BBP
  * locks are held and it will allocate memory.
  */
-static void
+static gdk_return
 BBPextend(int idx, int buildhash)
 {
-       if ((bat) ATOMIC_GET(BBPsize, BBPsizeLock) >= N_BBPINIT * BBPINIT)
-               GDKfatal("BBPextend: trying to extend BAT pool beyond the "
+       if ((bat) ATOMIC_GET(BBPsize, BBPsizeLock) >= N_BBPINIT * BBPINIT) {
+               GDKerror("BBPextend: trying to extend BAT pool beyond the "
                         "limit (%d)\n", N_BBPINIT * BBPINIT);
+               return GDK_FAIL;
+       }
 
        /* make sure the new size is at least BBPsize large */
        while (BBPlimit < (bat) ATOMIC_GET(BBPsize, BBPsizeLock)) {
                assert(BBP[BBPlimit >> BBPINITLOG] == NULL);
                BBP[BBPlimit >> BBPINITLOG] = GDKzalloc(BBPINIT * 
sizeof(BBPrec));
-               if (BBP[BBPlimit >> BBPINITLOG] == NULL)
-                       GDKfatal("BBPextend: failed to extend BAT pool\n");
+               if (BBP[BBPlimit >> BBPINITLOG] == NULL) {
+                       GDKerror("BBPextend: failed to extend BAT pool\n");
+                       return GDK_FAIL;
+               }
                BBPlimit += BBPINIT;
        }
 
@@ -358,6 +362,7 @@ BBPextend(int idx, int buildhash)
                        BBP_free(i) = 0;
                BBPinithash(idx);
        }
+       return GDK_SUCCEED;
 }
 
 static inline char *
@@ -1973,7 +1978,7 @@ BBPgetsubdir(str s, bat i)
  * increasing BBPsize (up to BBPlimit) or extending the BBP (which
  * increases BBPlimit).  Every time this function is called we start
  * searching in a following free list (variable "last"). */
-static void
+static gdk_return
 maybeextend(int idx)
 {
        int t, m;
@@ -2004,14 +2009,31 @@ maybeextend(int idx)
        } else {
                /* let the longest list alone, get a fresh entry */
                if ((bat) ATOMIC_ADD(BBPsize, 1, BBPsizeLock) >= BBPlimit) {
-                       BBPextend(idx, TRUE);
+                       if (BBPextend(idx, TRUE) != GDK_SUCCEED) {
+                               /* undo add */
+                               ATOMIC_SUB(BBPsize, 1, BBPsizeLock);
+                               /* couldn't extend; if there is any
+                                * free entry, take it from the
+                                * longest list after all */
+                               if (l > 0) {
+                                       i = BBP_free(m);
+                                       BBP_free(m) = BBP_next(i);
+                                       BBP_next(i) = 0;
+                                       BBP_free(idx) = i;
+                               } else {
+                                       /* nothing available */
+                                       return GDK_FAIL;
+                               }
+                       }
                } else {
                        BBP_free(idx) = (bat) ATOMIC_GET(BBPsize, BBPsizeLock) 
- 1;
                }
        }
        last = (last + 1) & BBP_THREADMASK;
+       return GDK_SUCCEED;
 }
 
+/* return new BAT id (> 0); return 0 on failure */
 bat
 BBPinsert(BAT *bn)
 {
@@ -2031,6 +2053,7 @@ BBPinsert(BAT *bn)
        /* find an empty slot */
        if (BBP_free(idx) <= 0) {
                /* we need to extend the BBP */
+               gdk_return r = GDK_SUCCEED;
                if (lock) {
                        /* we must take all locks in a consistent
                         * order so first unset the one we've already
@@ -2043,13 +2066,20 @@ BBPinsert(BAT *bn)
                /* check again in case some other thread extended
                 * while we were waiting */
                if (BBP_free(idx) <= 0) {
-                       maybeextend(idx);
+                       r = maybeextend(idx);
                }
                MT_lock_unset(&GDKnameLock);
                if (lock)
                        for (i = BBP_THREADMASK; i >= 0; i--)
                                if (i != idx)
                                        MT_lock_unset(&GDKcacheLock(i));
+               if (r != GDK_SUCCEED) {
+                       if (lock) {
+                               MT_lock_unset(&GDKcacheLock(idx));
+                               MT_lock_unset(&GDKtrimLock(idx));
+                       }
+                       return 0;
+               }
        }
        i = BBP_free(idx);
        assert(i > 0);
@@ -2101,7 +2131,7 @@ BBPinsert(BAT *bn)
        return i;
 }
 
-void
+gdk_return
 BBPcacheit(BAT *bn, int lock)
 {
        bat i = bn->batCacheid;
@@ -2114,6 +2144,8 @@ BBPcacheit(BAT *bn, int lock)
                assert(i > 0);
        } else {
                i = BBPinsert(bn);      /* bat was not previously entered */
+               if (i == 0)
+                       return GDK_FAIL;
                if (bn->tvheap)
                        bn->tvheap->parentid = i;
        }
@@ -2130,6 +2162,7 @@ BBPcacheit(BAT *bn, int lock)
 
        if (lock)
                MT_lock_unset(&GDKswapLock(i));
+       return GDK_SUCCEED;
 }
 
 /*
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -71,7 +71,8 @@ enum heaptype {
        __attribute__((__visibility__("hidden")));
 __hidden size_t BATvmsize(BAT *b, int dirty)
        __attribute__((__visibility__("hidden")));
-__hidden void BBPcacheit(BAT *bn, int lock)
+__hidden gdk_return BBPcacheit(BAT *bn, int lock)
+       __attribute__ ((__warn_unused_result__))
        __attribute__((__visibility__("hidden")));
 void BBPdump(void);            /* never called: for debugging only */
 __hidden void BBPexit(void)
@@ -81,6 +82,7 @@ void BBPdump(void);           /* never called: fo
 __hidden void BBPinit(void)
        __attribute__((__visibility__("hidden")));
 __hidden bat BBPinsert(BAT *bn)
+       __attribute__ ((__warn_unused_result__))
        __attribute__((__visibility__("hidden")));
 __hidden int BBPselectfarm(int role, int type, enum heaptype hptype)
        __attribute__((__visibility__("hidden")));
diff --git a/gdk/gdk_storage.c b/gdk/gdk_storage.c
--- a/gdk/gdk_storage.c
+++ b/gdk/gdk_storage.c
@@ -822,7 +822,12 @@ BATload_intern(bat bid, int lock)
        b->theap.parentid = 0;
 
        /* load succeeded; register it in BBP */
-       BBPcacheit(b, lock);
+       if (BBPcacheit(b, lock) != GDK_SUCCEED) {
+               HEAPfree(&b->theap, 0);
+               if (b->tvheap)
+                       HEAPfree(b->tvheap, 0);
+               return NULL;
+       }
 
        if ((b->batRestricted == BAT_WRITE && (GDKdebug & CHECKMASK)) ||
            (GDKdebug & PROPMASK)) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to