git: 446e0f2e6c79 - 2021Q4 - games/gzdoom: fix wildmidi crash

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Thu, 16 Dec 2021 05:45:48 UTC
The branch 2021Q4 has been updated by kevans:

URL: https://cgit.FreeBSD.org/ports/commit/?id=446e0f2e6c79e2fbf012861c91e678a389c8852f

commit 446e0f2e6c79e2fbf012861c91e678a389c8852f
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2021-12-16 05:36:04 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2021-12-16 05:40:55 +0000

    games/gzdoom: fix wildmidi crash
    
    get_patch_data() may recurse on itself, which is not OK to do while
    using std::lock_guard<>.  Move the contents of get_patch_data() to a
    get_patch_data_locked() that may recurse on itself.
    
    This is a direct commit to quarterly, as this has since been fixed by
    the version present in main.  Specifically, a later refactoring ends up
    dropping the patch_lock entirely after get_patch_data() and friends are
    pushed into an Instruments class anyways.
    
    Based on triage work and an initial patch by wpaul@.
---
 .../patch-src_sound_wildmidi_wildmidi__lib.cpp     | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp b/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp
new file mode 100644
index 000000000000..eaa3681841db
--- /dev/null
+++ b/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp
@@ -0,0 +1,49 @@
+--- src/sound/wildmidi/wildmidi_lib.cpp.orig	2019-05-04 19:58:35 UTC
++++ src/sound/wildmidi/wildmidi_lib.cpp
+@@ -1318,11 +1318,9 @@ static int load_sample(struct _patch *sample_patch) {
+ }
+ 
+ static struct _patch *
+-get_patch_data(unsigned short patchid) {
++get_patch_data_locked(unsigned short patchid) {
+ 	struct _patch *search_patch;
+ 
+-	std::lock_guard<std::mutex> lock(patch_lock);
+-
+ 	search_patch = patch[patchid & 0x007F];
+ 
+ 	if (search_patch == NULL) {
+@@ -1335,12 +1333,32 @@ get_patch_data(unsigned short patchid) {
+ 		}
+ 		search_patch = search_patch->next;
+ 	}
+ 	if ((patchid >> 8) != 0) {
+-		return (get_patch_data(patchid & 0x00FF));
++		return (get_patch_data_locked(patchid & 0x00FF));
+ 	}
+ 	return NULL;
+ }
+ 
++static struct _patch *
++get_patch_data(unsigned short patchid) {
++	struct _patch *patch;
++
++	/*
++	 * Uh, hey, no, sorry pal, you can't use this
++	 * construction here. This function can call itself
++	 * recursively, which means you will recursively
++	 * try to acquire the patch_lock mutex, which is
++	 * not allowed with lock_guard.
++	 */
++
++/*	std::lock_guard<std::mutex> lock(patch_lock); */
++
++	patch_lock.lock();
++	patch = get_patch_data_locked(patchid);
++	patch_lock.unlock();
++	return (patch);
++}
++
+ static void load_patch(struct _mdi *mdi, unsigned short patchid) {
+ 	unsigned int i;
+ 	struct _patch *tmp_patch = NULL;