I would suggest creating your own class or structure or something else. To do this, you define a recording method that also contains expectations for the semaphore to start. If you are using Linux, sem_wait (from the semaphore family of functions, sem_* ) is what you want to see.
Then the write function will write the data to FIFO and wait until the semaphore is marked. However, how does a stream of letters write when all the data comes through the channel you want to send? If the stream should read in a locked way, problems can occur here.
Therefore, I suggest you use microformat inside the channel from the main stream to the processing stream, sending an integer size that determines how many bytes you are going to write. Then the processing stream will read the number of bytes, redirect it to the device and mark the semaphore as soon as all the data is marked. The write function will wait for the semaphore, so the lock is not busy until the processing flow is complete.
In this way, a custom channel structure and a dedicated recording function can be programmed:
#include <stdlib.h> #include <unistd.h> #include <semaphore.h> typedef struct { int write_to_pipe, read_from_pipe; sem_t *write_sem; } MyPipe; MyPipe *pipe_new() { int fds[2]; if (pipe(fds)) { // handle error here return NULL; } sem_t *sem = NULL; if (sem_init(sem, 0, 0)) { // handle error here close(fds[0]); close(fds[1]); return NULL; } MyPipe *result = malloc(sizeof(MyPipe)); result->write_to_pipe = fds[1]; result->read_from_pipe = fds[0]; result->write_sem = sem; return result; } void pipe_write(MyPipe *pipe, const unsigned char *buf, const int size) { write(pipe->write_to_pipe, &size, sizeof(int)); write(pipe->write_to_pipe, buf, size); sem_wait(pipe->write_sem); }
The processing thread will know the instance of MyPipe and read with read_from_pipe whenever it wishes. First, it reads the number of bytes that the main stream wrote in the pipe, and then all bytes are arbitrary pieces. After all the data has been sent to the device and was ACK'd by it, it can sem_post semaphore, so pipe_write will return.
Additionally, you can add another semaphore that pipe_write sends so that the processing thread only processes data when there is actually data.
Disclaimer: I did not check the code, I checked only its compilation. It is required to build with -pthread in order to have sem_* .