commit e5de9210c160bf941b5ac4a94c7be76da77bff47
parent 84b7cec46bc91343a1a8aa9b13799db5608ee4e8
Author: Olav Sørensen <olav.sorensen@live.no>
Date: Sun, 17 Mar 2024 12:22:46 +0100
Fix possible deadlock in loaders/savers
Diffstat:
2 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/src/ft2_inst_ed.c b/src/ft2_inst_ed.c
@@ -2912,25 +2912,26 @@ static int32_t SDLCALL saveInstrThread(void *ptr)
{
xiHdr_t ih;
sample_t *s;
+ FILE *f = NULL;
if (editor.tmpFilenameU == NULL)
{
okBoxThreadSafe(0, "System message", "General I/O error during saving! Is the file in use?", NULL);
- return false;
+ goto saveError;
}
const int32_t numSamples = getUsedSamples(saveInstrNum);
if (numSamples == 0 || instr[saveInstrNum] == NULL)
{
okBoxThreadSafe(0, "System message", "Instrument is empty!", NULL);
- return false;
+ goto saveError;
}
- FILE *f = UNICHAR_FOPEN(editor.tmpFilenameU, "wb");
+ f = UNICHAR_FOPEN(editor.tmpFilenameU, "wb");
if (f == NULL)
{
okBoxThreadSafe(0, "System message", "General I/O error during saving! Is the file in use?", NULL);
- return false;
+ goto saveError;
}
memset(&ih, 0, sizeof (ih)); // important, also clears reserved stuff
@@ -3025,9 +3026,8 @@ static int32_t SDLCALL saveInstrThread(void *ptr)
size_t result = fwrite(&ih, INSTR_XI_HEADER_SIZE + (ih.numSamples * sizeof (xmSmpHdr_t)), 1, f);
if (result != 1)
{
- fclose(f);
okBoxThreadSafe(0, "System message", "Error saving instrument: general I/O error!", NULL);
- return false;
+ goto saveError;
}
pauseAudio();
@@ -3047,9 +3047,8 @@ static int32_t SDLCALL saveInstrThread(void *ptr)
if (result != (size_t)SAMPLE_LENGTH_BYTES(s)) // write not OK
{
resumeAudio();
- fclose(f);
okBoxThreadSafe(0, "System message", "Error saving instrument: general I/O error!", NULL);
- return false;
+ goto saveError;
}
}
}
@@ -3062,6 +3061,15 @@ static int32_t SDLCALL saveInstrThread(void *ptr)
return true;
+saveError:
+ if (f != NULL)
+ fclose(f);
+
+ editor.diskOpReadDir = true; // force diskop re-read
+ setMouseBusy(false);
+
+ return false;
+
(void)ptr;
}
@@ -3102,21 +3110,22 @@ static int32_t SDLCALL loadInstrThread(void *ptr)
xmSmpHdr_t *src;
sample_t *s;
instr_t *ins;
-
+ FILE *f = NULL;
bool stereoWarning = false;
+
numLoadedSamples = 0;
if (editor.tmpInstrFilenameU == NULL)
{
okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?", NULL);
- return false;
+ goto loadDone;
}
- FILE *f = UNICHAR_FOPEN(editor.tmpInstrFilenameU, "rb");
+ f = UNICHAR_FOPEN(editor.tmpInstrFilenameU, "rb");
if (f == NULL)
{
okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?", NULL);
- return false;
+ goto loadDone;
}
memset(&xi_h, 0, sizeof (xi_h));
@@ -3435,32 +3444,36 @@ static int32_t SDLCALL loadInstrThread(void *ptr)
}
loadDone:
- fclose(f);
-
- numLoadedSamples = CLAMP(numLoadedSamples, 1, MAX_SMP_PER_INST);
+ if (f != NULL)
+ fclose(f);
- ins = instr[editor.curInstr];
- if (ins != NULL)
+ if (numLoadedSamples > 0)
{
- sanitizeInstrument(ins);
- for (i = 0; i < numLoadedSamples; i++)
+ numLoadedSamples = CLAMP(numLoadedSamples, 1, MAX_SMP_PER_INST);
+
+ ins = instr[editor.curInstr];
+ if (ins != NULL)
{
- s = &ins->smp[i];
- sanitizeSample(s);
+ sanitizeInstrument(ins);
+ for (i = 0; i < numLoadedSamples; i++)
+ {
+ s = &ins->smp[i];
+ sanitizeSample(s);
- if (s->dataPtr != NULL)
- fixSample(s);
- }
+ if (s->dataPtr != NULL)
+ fixSample(s);
+ }
- fixInstrAndSampleNames(editor.curInstr);
- }
- editor.updateCurInstr = true; // setMouseBusy(false) is called in the input/video thread when done
+ fixInstrAndSampleNames(editor.curInstr);
+ }
+ editor.updateCurInstr = true; // setMouseBusy(false) is called in the input/video thread when done
- if (numLoadedSamples > MAX_SMP_PER_INST)
- okBoxThreadSafe(0, "System message", "Warning: The instrument contained >16 samples. The extra samples were discarded!", NULL);
+ if (numLoadedSamples > MAX_SMP_PER_INST)
+ okBoxThreadSafe(0, "System message", "Warning: The instrument contained >16 samples. The extra samples were discarded!", NULL);
- if (stereoWarning)
- okBoxThreadSafe(0, "System message", "Warning: The instrument contained stereo sample(s). They were mixed to mono!", NULL);
+ if (stereoWarning)
+ okBoxThreadSafe(0, "System message", "Warning: The instrument contained stereo sample(s). They were mixed to mono!", NULL);
+ }
return true;
(void)ptr;
diff --git a/src/ft2_sample_loader.c b/src/ft2_sample_loader.c
@@ -86,14 +86,14 @@ static int32_t SDLCALL loadSampleThread(void *ptr)
if (editor.tmpFilenameU == NULL)
{
loaderMsgBox("General I/O error during loading!");
- return false;
+ goto loadError;
}
FILE *f = UNICHAR_FOPEN(editor.tmpFilenameU, "rb");
if (f == NULL)
{
loaderMsgBox("General I/O error during loading! Is the file in use?");
- return false;
+ goto loadError;
}
int8_t format = detectSample(f);
@@ -104,7 +104,7 @@ static int32_t SDLCALL loadSampleThread(void *ptr)
{
fclose(f);
loaderMsgBox("Error loading sample: The file is empty!");
- return false;
+ goto loadError;
}
bool sampleLoaded = false;