For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > January 2008 > How to wait until the other end of a FIFO is reopened.









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How to wait until the other end of a FIFO is reopened.
janesconference@gmail.com

2008-01-16, 8:11 am

Hi to everyone,

I've got two different processes, one writing and one reading on a
named pipe (FIFO).

Please note that i use 3d party library functions on each one of the
processes, so I can open() the fifo and do whatever I want on the file
descriptor of the writing end, but I cant' control how the libraries
handles its write() calls.

On the reading end, it's even worse: I can only pass the library the
file name of the FIFO and the library completely handles the file
operations (that is, I don't even have the file descriptor).

The problem is: I open() the FIFO on the writer process and pass the
file descriptor to the library. When I want, the library will start
writing the data on the FIFO.

On the reading end, the library opens the FIFO itself (and that's when
the writing-end open() unblocks), then close()s the FIFO, does its
calculations, and open()s it again. I know it sounds a bit crazy, but
I talked with the author and he said he won't change the behaviour,
and I have to live with it.

The core of the problem is that when I start to write on the writing
process, the FIFO may still be closed on the reading process. If it
is, I get a SIGPIPE on the writing end before the reading end opens
the FIFO again.

Schematically:

writer: open() -- blocks
reader: open()
writer: unblocks
reader: close()
writer: write() -- dies on a SIGPIPE
reader: open() -- but it's too late!

Now, I can't just ignore the SIGPIPE on the writer, because it returns
with EPIPE when the library writes, and I can't handle this within the
library.

I tried to poll() for POLLOUT the file descriptor on the writing side
before I start the library method that write()s, but it returns
immediately with a positive answer: Indeed, the write()s won't block,
but they will give me a SIGPIPE.

Do you know any way to block on a file descriptor until its reading
end is open? I tought i could write() on it some bogus data until
write() does not return EPIPE anymore (ignoring SIGPIPE), but I don't
like this method because:

1) it means busy waiting.
2) read end could read bogus data and screw everything up (the
processes exchange encoded video data, and if I send invalid data, it
could mean serious wreck on the video stream).

Ah, closing and opening again the file descriptor on the writing side
won't work too: when I initialize the library, it stores the file
descriptor in its private data. If I change it on the run, it will
mean chaos & destruction.

Thanks in advance,
Best Regards,

Cristiano.
William Pursell

2008-01-16, 7:12 pm

On Jan 16, 1:48 pm, janesconfere...@gmail.com wrote:

> I've got two different processes, one writing and one reading on a
> named pipe (FIFO).

<snip>
> On the reading end, it's even worse: I can only pass the library the
> file name of the FIFO and the library completely handles the file
> operations (that is, I don't even have the file descriptor).

<snip>

But you know the name, so you can open() it and get an fd.

<snip>

>
> The core of the problem is that when I start to write on the writing
> process, the FIFO may still be closed on the reading process. If it
> is, I get a SIGPIPE on the writing end before the reading end opens
> the FIFO again.


Open the fifo yourself, and ignore the fd. The writer should then
block until the library call opens it, gets a new
fd, and reads.


janesconference@gmail.com

2008-01-17, 4:25 am

> > The core of the problem is that when I start to write on the writing
>
> Open the fifo yourself, and ignore the fd. The writer should then
> block until the library call opens it, gets a new
> fd, and reads.


You mean I should open the fifo in the reader before calling the
library? But if I do, the writer will not block when opening for
writing (because the read end is already open) and will start writing
on the FIFO immediately.
William Pursell

2008-01-17, 8:11 am

On Jan 17, 9:58 am, janesconfere...@gmail.com wrote:
>
>
> You mean I should open the fifo in the reader before calling the
> library? But if I do, the writer will not block when opening for
> writing (because the read end is already open) and will start writing
> on the FIFO immediately.


That should be okay, as long as you don't read that data. The
writer will be able to write some data, but it will just sit in
the fifo's buffer until the library call from the reader reads
it. If you're using the writer's block for synchronization, you'll
need to use a different mechanism.

So you get:

1: reader opens dummy fd1
2: writer opens and writes "abcd..."
3: reader opens fd2 in library call, which reads "abcd..."
4: reader's library call closes fd2
5: writer writes, doesn't get SIGPIPE because fd1 is still open
6: reader opens fd3 in library.
etc...

The library will see the data in the order written by the writer, even
if the writer writes before you make the open in the library call.
janesconference@gmail.com

2008-01-17, 8:11 am

On 17 Gen, 11:30, William Pursell <bill.purs...@gmail.com> wrote:
> That should be okay, as long as you don't read that data. The
> writer will be able to write some data, but it will just sit in
> the fifo's buffer until the library call from the reader reads
> it. If you're using the writer's block for synchronization, you'll
> need to use a different mechanism.
>
> So you get:
>
> 1: reader opens dummy fd1
> 2: writer opens and writes "abcd..."
> 3: reader opens fd2 in library call, which reads "abcd..."
> 4: reader's library call closes fd2
> 5: writer writes, doesn't get SIGPIPE because fd1 is still open
> 6: reader opens fd3 in library.
> etc...
>
> The library will see the data in the order written by the writer, even
> if the writer writes before you make the open in the library call.


Indeed, it works. The dummy fd worries me a bit (The reader library
enters in a continuous event loop that lasts potentially forever, so I
can never close() that fd when it's safe), but it's ten times better
than the sleep() solution that worked for me before :)

Too bad it does not exist a call which blocks until the other end is
ready, it really should. Hyronically there's a way to wait for the
complementary event, the closing of the opposite end of the pipe, that
is accomplished by poll()ing the file descriptor with the POLLHUP
flag.

Anyway,

Many Thanks!
Syren Baran

2008-01-17, 7:14 pm

janesconference@gmail.com schrieb:
> Hi to everyone,
> Do you know any way to block on a file descriptor until its reading
> end is open?

1.) Opening the the file for writing blocks until a process opens the
reading end. So maybe a second call to open the fifo for witing might
block since the reader closed the fifo.
2.) This works for linux, dont know about other unices. Dont open the
the fifo for writing, but open it rw instead. The open wont block in
this case and the writen data will be in the pipe until the actual
reader reads it.
> Thanks in advance,
> Best Regards,
>
> Cristiano.

Syren Baran

2008-01-17, 7:14 pm

Syren Baran schrieb:
> janesconference@gmail.com schrieb:
> 1.) Opening the the file for writing blocks until a process opens the
> reading end. So maybe a second call to open the fifo for witing might
> block since the reader closed the fifo.

s/might block since/should block if/
Dont know about the timing between "reader open","reader close" and
"reader open again".[color=darkred]
> 2.) This works for linux, dont know about other unices. Dont open the
> the fifo for writing, but open it rw instead. The open wont block in
> this case and the writen data will be in the pipe until the actual
> reader reads it.
Barry Margolin

2008-01-18, 10:13 pm

In article
<021d1f04-93d1-4722-8dfb-276679bb4008@l1g2000hsa.googlegroups.com>,
William Pursell <bill.pursell@gmail.com> wrote:

> On Jan 17, 9:58 am, janesconfere...@gmail.com wrote:
>
> That should be okay, as long as you don't read that data. The
> writer will be able to write some data, but it will just sit in
> the fifo's buffer until the library call from the reader reads
> it. If you're using the writer's block for synchronization, you'll
> need to use a different mechanism.
>
> So you get:
>
> 1: reader opens dummy fd1
> 2: writer opens and writes "abcd..."
> 3: reader opens fd2 in library call, which reads "abcd..."
> 4: reader's library call closes fd2
> 5: writer writes, doesn't get SIGPIPE because fd1 is still open
> 6: reader opens fd3 in library.
> etc...
>
> The library will see the data in the order written by the writer, even
> if the writer writes before you make the open in the library call.


One possible problem. If the library uses stdio to read from the FIFO,
stdio might buffer some extra data that the library never gets around to
reading. The library would close the stdio stream, the next call to the
library would open it again, and would have skipped over that unread
data.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com