commit 4d106478c4f23f849aba46ec7ded831b5644c9d6
Author: Simon Howard <fraggle@soulsphere.org>
AuthorDate: Sun Jul 14 00:00:22 2019 -0400
Commit: Simon Howard <fraggle@soulsphere.org>
CommitDate: Sun Jul 14 00:00:22 2019 -0400
midiproc: Acknowledge all commands on completion.
Race conditions can occur if we do not know for sure whether a
midiproc command has completed yet or not. So expand on the ACK packet
type already sent for song registration and send acks for all commands
sent by the caller.
Second part of a fix for #963.
---
midiproc/main.c | 30 ++++++++++++------------------
midiproc/proto.h | 1 +
src/i_midipipe.c | 30 +++++++++++++++++++-----------
3 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/midiproc/main.c b/midiproc/main.c
index c21428d3..604d6ce4 100644
--- a/midiproc/main.c
+++ b/midiproc/main.c
@@ -164,30 +164,13 @@ static void StopSong()
static boolean MidiPipe_RegisterSong(buffer_reader_t *reader)
{
- CHAR buffer[2];
- DWORD bytes_written;
-
char *filename = Reader_ReadString(reader);
if (filename == NULL)
{
return false;
}
- if (!RegisterSong(filename))
- {
- return false;
- }
-
- if (!WriteInt16(buffer, sizeof(buffer),
- MIDIPIPE_PACKET_TYPE_REGISTER_SONG_ACK))
- {
- return false;
- }
-
- WriteFile(midi_process_out, buffer, sizeof(buffer),
- &bytes_written, NULL);
-
- return true;
+ return RegisterSong(filename);
}
static boolean MidiPipe_UnregisterSong(buffer_reader_t *reader)
@@ -270,6 +253,8 @@ boolean ParseCommand(buffer_reader_t *reader, uint16_t command)
//
boolean ParseMessage(buffer_t *buf)
{
+ CHAR buffer[2];
+ DWORD bytes_written;
int bytes_read;
uint16_t command;
buffer_reader_t *reader = NewReader(buf);
@@ -292,6 +277,15 @@ boolean ParseMessage(buffer_t *buf)
DeleteReader(reader);
Buffer_Shift(buf, bytes_read);
+ // Send acknowledgement back that the command has completed.
+ if (!WriteInt16(buffer, sizeof(buffer), MIDIPIPE_PACKET_TYPE_ACK))
+ {
+ goto fail;
+ }
+
+ WriteFile(midi_process_out, buffer, sizeof(buffer),
+ &bytes_written, NULL);
+
return true;
fail:
diff --git a/midiproc/proto.h b/midiproc/proto.h
index 35319fc8..790c9df5 100755
--- a/midiproc/proto.h
+++ b/midiproc/proto.h
@@ -26,6 +26,7 @@ typedef enum {
MIDIPIPE_PACKET_TYPE_STOP_SONG,
MIDIPIPE_PACKET_TYPE_SHUTDOWN,
MIDIPIPE_PACKET_TYPE_UNREGISTER_SONG,
+ MIDIPIPE_PACKET_TYPE_ACK,
} net_midipipe_packet_type_t;
#endif
diff --git a/src/i_midipipe.c b/src/i_midipipe.c
index 46b9b312..1df04429 100644
--- a/src/i_midipipe.c
+++ b/src/i_midipipe.c
@@ -215,6 +215,19 @@ void RemoveFileSpec(TCHAR *path, size_t size)
*(fp + 1) = '\0';
}
+static boolean BlockForAck(void)
+{
+ boolean ok;
+ net_packet_t *packet;
+
+ packet = NET_NewPacket(2);
+ NET_WriteInt16(packet, MIDIPIPE_PACKET_TYPE_REGISTER_SONG_ACK);
+ ok = ExpectPipe(packet);
+ NET_FreePacket(packet);
+
+ return ok;
+}
+
//=============================================================================
//
// Protocol Commands
@@ -239,23 +252,13 @@ boolean I_MidiPipe_RegisterSong(char *filename)
midi_server_registered = false;
+ ok = ok && BlockForAck();
if (!ok)
{
DEBUGOUT("I_MidiPipe_RegisterSong failed");
return false;
}
- packet = NET_NewPacket(2);
- NET_WriteInt16(packet, MIDIPIPE_PACKET_TYPE_REGISTER_SONG_ACK);
- ok = ExpectPipe(packet);
- NET_FreePacket(packet);
-
- if (!ok)
- {
- DEBUGOUT("I_MidiPipe_RegisterSong ack failed");
- return false;
- }
-
midi_server_registered = true;
DEBUGOUT("I_MidiPipe_RegisterSong succeeded");
@@ -277,6 +280,7 @@ void I_MidiPipe_UnregisterSong(void)
ok = WritePipe(packet);
NET_FreePacket(packet);
+ ok = ok && BlockForAck();
if (!ok)
{
DEBUGOUT("I_MidiPipe_UnregisterSong failed");
@@ -304,6 +308,7 @@ void I_MidiPipe_SetVolume(int vol)
ok = WritePipe(packet);
NET_FreePacket(packet);
+ ok = ok && BlockForAck();
if (!ok)
{
DEBUGOUT("I_MidiPipe_SetVolume failed");
@@ -329,6 +334,7 @@ void I_MidiPipe_PlaySong(int loops)
ok = WritePipe(packet);
NET_FreePacket(packet);
+ ok = ok && BlockForAck();
if (!ok)
{
DEBUGOUT("I_MidiPipe_PlaySong failed");
@@ -355,6 +361,7 @@ void I_MidiPipe_StopSong()
midi_server_registered = false;
+ ok = ok && BlockForAck();
if (!ok)
{
DEBUGOUT("I_MidiPipe_StopSong failed");
@@ -379,6 +386,7 @@ void I_MidiPipe_ShutdownServer()
ok = WritePipe(packet);
NET_FreePacket(packet);
+ ok = ok && BlockForAck();
FreePipes();
midi_server_initialized = false;