[Dosemu-devel] [PATCH] Retry opening MIDI output FIFO on writes.
Brought to you by:
bartoldeman
From: Ryan C. U. <nem...@ic...> - 2015-01-18 18:35:55
|
From: "Ryan C. Underwood" <ne...@ic...> Now the user can start consuming MIDI data after dosemu has started, instead of having to start over after realizing he forgot to start his MIDI-consuming app. Signed-off-by: Ryan C. Underwood <ne...@ic...> --- src/plugin/midimisc/mid_o_pipe.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/plugin/midimisc/mid_o_pipe.c b/src/plugin/midimisc/mid_o_pipe.c index eb45f64..633e3eb 100644 --- a/src/plugin/midimisc/mid_o_pipe.c +++ b/src/plugin/midimisc/mid_o_pipe.c @@ -41,10 +41,16 @@ static int midopipe_init(void) pipe_fd = RPT_SYSCALL(open(name, O_WRONLY | O_CREAT | O_NONBLOCK, 0666)); if (pipe_fd == -1) { - S_printf("%s: unable to open %s for writing: %s\n", - midopipe_name, name, strerror(errno)); - return 0; + int err = errno; + S_printf("%s: unable to open %s for writing (%s)%s\n", midopipe_name, name, + strerror(errno), errno == ENXIO ? ", will continue trying" : ""); + if (err == ENXIO) { /* no FIFO readers */ + return 1; + } else { /* some other problem */ + return 0; + } } + /* open ok */ return 1; } @@ -62,9 +68,28 @@ static void midopipe_reset(void) static void midopipe_write(unsigned char val) { - if (pipe_fd == -1) - return; - write(pipe_fd, &val, 1); + /* Try again to open FIFO on each write in case some readers showed up. */ + if (pipe_fd == -1) { + pipe_fd = RPT_SYSCALL(open(DOSEMU_MIDI_PATH, O_WRONLY | O_CREAT | O_NONBLOCK, 0666)); + if (pipe_fd == -1) { + return; + } + } + int retry = 0; + do { + if (write(pipe_fd, &val, 1) == -1) { + switch (errno) { + case EAGAIN: + case EINTR: + retry = 1; + default: /* all other errors incl. EPIPE */ + close(pipe_fd); + pipe_fd = -1; + retry = 0; + break; + } + } + } while (retry); } CONSTRUCTOR(static int midopipe_register(void)) -- 1.9.1 |