File 0544-erts-Fix-bugs-in-ets-rename.patch of Package erlang

From dbf48201728e9530090773cebc0733ed49ed9ee2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 22 Sep 2022 00:13:02 +0200
Subject: [PATCH 4/5] erts: Fix bugs in ets:rename

Handle racing rename correct by retry.

Avoid all name-tab locks when table is not named.
---
 erts/emulator/beam/erl_db.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index c71c951785..a32c9803e7 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -2178,13 +2178,13 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
         db_unlock(tb, LCK_READ);
         BIF_ERROR(BIF_P, BADARG);
     }
-
+retry:
     (void) meta_name_tab_bucket(BIF_ARG_2, &lck1);
 
     if (is_atom(BIF_ARG_1)) {
         old_name = BIF_ARG_1;
     named_tab:
-	(void) meta_name_tab_bucket(old_name, &lck2);
+        (void)meta_name_tab_bucket(old_name, &lck2);
 	if (lck1 == lck2)
 	    lck2 = NULL;
 	else if (lck1 > lck2) {
@@ -2198,15 +2198,17 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
         if (!tb)
             BIF_ERROR(BIF_P, BADARG | EXF_HAS_EXT_INFO);
         else {
+            old_name = tb->common.the_name;
             if (is_table_named(tb)) {
-                old_name = tb->common.the_name;
                 goto named_tab;
             }
+            lck1 = NULL;
             lck2 = NULL;
         }
     }
 
-    erts_rwmtx_rwlock(lck1);
+    if (lck1)
+        erts_rwmtx_rwlock(lck1);
     if (lck2)
 	erts_rwmtx_rwlock(lck2);
 
@@ -2215,6 +2217,16 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
 	goto fail;
 
     if (is_table_named(tb)) {
+        if (tb->common.the_name != old_name) {
+            /* Wow! Racing rename op. Unlock all and retry. */
+            ASSERT(is_not_atom(BIF_ARG_1));
+            if (lck1)
+                erts_rwmtx_rwunlock(lck1);
+            if (lck2)
+                erts_rwmtx_rwunlock(lck2);
+            db_unlock(tb, LCK_WRITE);
+            goto retry;
+        }
         if (!insert_named_tab(BIF_ARG_2, tb, 1))
             goto badarg;
 
@@ -2228,7 +2240,8 @@ BIF_RETTYPE ets_rename_2(BIF_ALIST_2)
     tb->common.the_name = BIF_ARG_2;
 
     db_unlock(tb, LCK_WRITE);
-    erts_rwmtx_rwunlock(lck1);
+    if (lck1)
+        erts_rwmtx_rwunlock(lck1);
     if (lck2)
 	erts_rwmtx_rwunlock(lck2);
     BIF_RET(ret);
@@ -2239,7 +2252,8 @@ badarg:
 fail:
     if (tb)
 	db_unlock(tb, LCK_WRITE);
-    erts_rwmtx_rwunlock(lck1);
+    if (lck1)
+        erts_rwmtx_rwunlock(lck1);
     if (lck2)
 	erts_rwmtx_rwunlock(lck2);
 
-- 
2.35.3

openSUSE Build Service is sponsored by