Free shared state when sandbox is destroyed in libretro builds

This commit is contained in:
刘皓 2025-05-31 16:06:07 -04:00
parent 6f6efb4ef0
commit ef07a974ec
No known key found for this signature in database
GPG key ID: 7901753DB465B711
3 changed files with 58 additions and 42 deletions

View file

@ -53,8 +53,6 @@ struct SharedMidiState
fluid_settings_t *flSettings;
#ifdef MKXPZ_RETRO
fluid_sfloader_t *flLoader;
SharedMidiState()
: inited(false)
{}
@ -100,43 +98,6 @@ struct SharedMidiState
fluid.settings_setint(flSettings, "synth.chorus.active", mkxp_retro::midi_chorus_override == 1 || (mkxp_retro::midi_chorus_override != 0 && conf.midi.chorus));
fluid.settings_setint(flSettings, "synth.reverb.active", mkxp_retro::midi_reverb_override == 1 || (mkxp_retro::midi_reverb_override != 0 && conf.midi.reverb));
extern const uint8_t mkxp_gmgsx_sf2[];
extern const size_t mkxp_gmgsx_sf2_len;
flLoader = new_fluid_defsfloader(flSettings);
fluid_sfloader_set_callbacks(
flLoader,
[](const char *filename) {
return std::strcmp(filename, "/GMGSx.sf2") ? NULL : std::calloc(1, sizeof(fluid_long_long_t));
},
[](void *buf, fluid_long_long_t count, void *handle) {
assert((size_t)(*(fluid_long_long_t *)handle + count) < mkxp_gmgsx_sf2_len);
std::memcpy(buf, mkxp_gmgsx_sf2 + *(fluid_long_long_t *)handle, count);
*(fluid_long_long_t *)handle += count;
return (int)FLUID_OK;
},
[](void *handle, fluid_long_long_t offset, int origin) {
switch (origin) {
case SEEK_CUR:
*(fluid_long_long_t *)handle += offset;
break;
case SEEK_END:
*(fluid_long_long_t *)handle = mkxp_gmgsx_sf2_len + offset;
break;
default:
*(fluid_long_long_t *)handle = offset;
break;
}
return (int)FLUID_OK;
},
[](void *handle) {
return *(fluid_long_long_t *)handle;
},
[](void *handle) {
std::free(handle);
return (int)FLUID_OK;
}
);
for (size_t i = 0; i < SYNTH_INIT_COUNT; ++i)
addSynth(false);
}
@ -208,7 +169,45 @@ private:
fluid_synth_t *syn = fluid.new_synth(flSettings);
#ifdef MKXPZ_RETRO
fluid_synth_add_sfloader(syn, flLoader);
extern const uint8_t mkxp_gmgsx_sf2[];
extern const size_t mkxp_gmgsx_sf2_len;
fluid_sfloader_t *loader = new_fluid_defsfloader(flSettings);
fluid_sfloader_set_callbacks(
loader,
[](const char *filename) {
return std::strcmp(filename, "/GMGSx.sf2") ? NULL : std::calloc(1, sizeof(fluid_long_long_t));
},
[](void *buf, fluid_long_long_t count, void *handle) {
assert((size_t)(*(fluid_long_long_t *)handle + count) < mkxp_gmgsx_sf2_len);
std::memcpy(buf, mkxp_gmgsx_sf2 + *(fluid_long_long_t *)handle, count);
*(fluid_long_long_t *)handle += count;
return (int)FLUID_OK;
},
[](void *handle, fluid_long_long_t offset, int origin) {
switch (origin) {
case SEEK_CUR:
*(fluid_long_long_t *)handle += offset;
break;
case SEEK_END:
*(fluid_long_long_t *)handle = mkxp_gmgsx_sf2_len + offset;
break;
default:
*(fluid_long_long_t *)handle = offset;
break;
}
return (int)FLUID_OK;
},
[](void *handle) {
return *(fluid_long_long_t *)handle;
},
[](void *handle) {
std::free(handle);
return (int)FLUID_OK;
}
);
fluid_synth_add_sfloader(syn, loader);
fluid.synth_sfload(syn, "/GMGSx.sf2", 1);
#else
if (!soundFont.empty())

View file

@ -744,16 +744,21 @@ struct main : boost::asio::coroutine {
};
static void deinit_sandbox() {
bool shared_state_was_initialized = shared_state_initialized.load_relaxed();
shared_state_initialized = false;
struct lock_guard guard(threaded_audio_mutex);
struct lock_guard guard(threaded_audio_mutex); // Wait for the audio thread to stop rendering audio
if (sound_buf != nullptr) {
mkxp_aligned_free(sound_buf);
sound_buf = nullptr;
}
mkxp_retro::sandbox.reset();
thread_data.reset();
input.reset();
audio.reset();
if (al_context != nullptr) {
alcDestroyContext(al_context);
@ -763,7 +768,13 @@ static void deinit_sandbox() {
alcCloseDevice(al_device);
al_device = nullptr;
}
if (shared_state_was_initialized) {
SharedState::finiInstance();
}
conf.reset();
fs.reset();
}

View file

@ -228,14 +228,15 @@ void SharedState::initInstance(Exception &exception, RGSSThreadData *threadData)
_globalIBO = new GlobalIBO();
_globalIBO->ensureSize(1);
SharedState::instance = 0;
Font *defaultFont = 0;
SharedState::instance = new SharedState(exception, threadData);
if (exception.is_error())
{
delete SharedState::instance;
SharedState::instance = 0;
delete _globalIBO;
_globalIBO = 0;
return;
}
@ -247,7 +248,9 @@ void SharedState::initInstance(Exception &exception, RGSSThreadData *threadData)
MKXPZ_CATCH (const Exception &)
{
delete _globalIBO;
_globalIBO = 0;
delete SharedState::instance;
SharedState::instance = 0;
delete defaultFont;
MKXPZ_RETHROW;
@ -259,10 +262,13 @@ void SharedState::initInstance(Exception &exception, RGSSThreadData *threadData)
void SharedState::finiInstance()
{
delete SharedState::instance->p->defaultFont;
SharedState::instance->p->defaultFont = 0;
delete SharedState::instance;
SharedState::instance = 0;
delete _globalIBO;
_globalIBO = 0;
}
void SharedState::setScreen(Scene &screen)