]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
app_voicemail: Prevent deadlocks when out of ODBC database connections
authorSean Bright <sean.bright@gmail.com>
Thu, 24 Dec 2020 15:03:44 +0000 (10:03 -0500)
committerGeorge Joseph <gjoseph@digium.com>
Wed, 6 Jan 2021 16:50:48 +0000 (10:50 -0600)
ASTERISK-28992 #close

Change-Id: Ia7d608924036139ee2520b840d077762d02668d0

apps/app_voicemail.c

index 1bb736bf84390b099e9a761a991c1450066d5dfc..2929cf2cda2fb1da3efa4071c5a7a741813d4dde 100644 (file)
@@ -3834,6 +3834,7 @@ static int retrieve_file(char *dir, int msgnum)
        char fn[PATH_MAX];
        char full_fn[PATH_MAX];
        char msgnums[80];
+       char msg_id[MSG_ID_LEN] = "";
        char *argv[] = { dir, msgnums };
        struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
        struct odbc_obj *obj;
@@ -3938,10 +3939,10 @@ static int retrieve_file(char *dir, int msgnum)
                } else {
                        res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
                        if (res == SQL_NULL_DATA && !strcasecmp(coltitle, "msg_id")) {
-                               char msg_id[MSG_ID_LEN];
+                               /* Generate msg_id now, but don't store it until we're done with this
+                                  connection */
                                generate_msg_id(msg_id);
                                snprintf(rowdata, sizeof(rowdata), "%s", msg_id);
-                               odbc_update_msg_id(dir, msgnum, msg_id);
                        } else if (res == SQL_NULL_DATA && !strcasecmp(coltitle, "category")) {
                                /* Ignore null column value for category */
                                ast_debug(3, "Ignoring null category column in ODBC voicemail retrieve_file.\n");
@@ -3967,6 +3968,13 @@ bail:
 
        ast_odbc_release_obj(obj);
 
+       /* If res_odbc is configured to only allow a single database connection, we
+          will deadlock if we try to do this before releasing the connection we
+          were just using. */
+       if (!ast_strlen_zero(msg_id)) {
+               odbc_update_msg_id(dir, msgnum, msg_id);
+       }
+
        return x - 1;
 }