Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Named Pipes - WriteFile, ReadFile at the same time, same handle, different threads

1,031 views
Skip to first unread message

kierenj

unread,
Apr 24, 2008, 4:08:46 AM4/24/08
to
Hi -

I'm writing a multithreaded named pipes app.


BACKGROUND BLURB..

I have one thread which calls ReadFile() in a loop (not overlapped -
synchronous)
I have another thread which checks a 'message queue' of my design, and
calls WriteFile() when messages are to be sent

I've written both a server and a client for this - there are 4 threads
total. The basics:

Server: Creates named pipe
Server: Server-incoming thread starts, calls ReadFile() - blocks
Server: Server-outgoing thread starts, waiting for messages
Client: Connects to named pipe
Client: Client-incoming thread starts, calls ReadFile() - blocks
Client: Client-outgoing thread starts, waiting for messages

That seems fine so far... but when I try to send a message either way:

Client: Message put on queue to send
Client: Client-outgoing thread picks up message, calls WriteFile() -
blocks!

Same happens on the server side.


THE PROBLEM..

I'll boil it down to what I think is the problem: when there is a
blocking ReadFile() pending on one thread for a named pipe handle,
calling WriteFile(), even from another thread, on the same handle,
will block.

Is that right? The problem is I don't see why it should. Do I need
to use overlapped I/O? Because I think all I'd be doing is having the
thread sleep until the read/write operations complete anyway, which
seems to defeat the point of overlapped I/O, no?

Any help or tips, would be very much appreciated. MSDN tries to be
helpful but is worded poorly in this area (at least the information I
found).... PLEASE :)

Thanks
Kieren

kierenj

unread,
Apr 24, 2008, 4:10:29 AM4/24/08
to

For more information, I should have mentioned that if I disable two-
way comms, it works fine. For example, having the "Client" only write
messages and the "Server" only read them, or vice-versa.

Jeffrey Adler

unread,
Apr 24, 2008, 10:22:42 AM4/24/08
to

"kierenj" <kie...@gmail.com> wrote in message
news:1fa2511f-ca30-4951...@y38g2000hsy.googlegroups.com...

In order to do simultaneous reading and writing to a file (perhaps a comm
port?), you MUST use overlapped I/O.

http://msdn2.microsoft.com/en-us/library/ms810467.aspx

kierenj

unread,
Apr 25, 2008, 9:07:10 AM4/25/08
to
On 24 Apr, 15:22, "Jeffrey Adler" <jeff.nospam.ad...@bigfoot.com>
wrote:
> "kierenj" <kier...@gmail.com> wrote in message


Thanks very much for the reply. I've bitten the bullet and
implemented Overlapped I/O, and it works!

Well mostly... if I do this:

...client and server connected/communicating fine...
On server: ReadFile(), then GetOverlappedResult() // which blocks
until read is received
On client: CloseHandle() to the pipe

So basically I start an overlapped read op on the server, then
connection is closed using CloseHandle() on the client, but the server
doesn't ever return from GetOverlappedResult().

Why not? How do I detect that the client has disconnected? How do I
get GetOverlappedResult() to return when the disconnection happens?

Again any help would be greatly appreciated..

K

Jeffrey Adler

unread,
Apr 25, 2008, 5:54:49 PM4/25/08
to

"kierenj" <kie...@gmail.com> wrote in message
news:fecca347-c3e2-4008...@26g2000hsk.googlegroups.com...

You may need to set an event and use WaitForSingleObject (or
WaitForMultipleObjects) and use another Event Object to use when you want to
close the handle.


kierenj

unread,
Apr 27, 2008, 4:59:53 AM4/27/08
to
On 25 Apr, 22:54, "Jeffrey Adler" <jeff.nospam.ad...@bigfoot.com>

I'm use GetOverlappedResult(), and on the OVERLAPPED structure I set
an event (created with CreateEvent()) - so it's already waiting on
that event.. It's not that I want to close the pipe, it's that it
doesn't detect when the client disconnects.

To say it a different way, the server does a ReadFile() and
GetOverlappedResult() in a loop to receive messages - but when the
client disconnects, GetOverlappedResult() doesn' return so it's a
hang.... :(

Any ideas?

Tom

unread,
Apr 28, 2008, 11:31:35 PM4/28/08
to
In article <251933e6-14be-44ad...@s50g2000hsb.googlegroups.com>, kierenj <kie...@gmail.com> wrote:
>I'm use GetOverlappedResult(), and on the OVERLAPPED structure I set
>an event (created with CreateEvent()) - so it's already waiting on
>that event.. It's not that I want to close the pipe, it's that it
>doesn't detect when the client disconnects.
>
>To say it a different way, the server does a ReadFile() and
>GetOverlappedResult() in a loop to receive messages - but when the
>client disconnects, GetOverlappedResult() doesn' return so it's a
>hang.... :(
>
>Any ideas?

You can't use GetOverlappedResult() to detect when the client
disconnects, you have to use the event. Here's how I do it:

status=ReadFile()
if (!status && (GetLastError()==ERROR_IO_PENDING)) {
status=WaitForSingleObject()
if (status==WAIT_OBJECT_0) status=GetOverlappedResult()
}

The event that you're waiting for is the one in the OVERLAPPED structure that
gets passed to ReadFile.

Another important note: depending on how your client handles disconnections,
your server might need to call FlushFileBuffers() before it calls
DisconnectNamedPipe().

--Tom.

0 new messages