I have a real old code from a service that uses named named pipes in message mode (PIPE_TYPE_MESSAGE) with overlapped i/o (FILE_FLAG_OVERLAPPED).
The code does the following:
ReadFilefor 4 bytes with overlapped i/o (header + message length). The Client wrote this command with one call toWriteFile.- After the 4 bytes are read, a
ReadFilecall is made to read the rest of the message (with the known length) without specifying anOVERLAPPEDstructure. - After the command is executed the routine continues at stage 1. and awaits the next command.
When I read the documentation
Overlapped operations require a file, named pipe, or communications device that was created with the FILE_FLAG_OVERLAPPED flag. When a thread calls a function (such as the ReadFile function) to perform an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure. (If this pointer is NULL, the function return value may incorrectly indicate that the operation completed.)
I have to assume that this code will not work or is at least be called incorrect...
In fact this code is 15 years old and runs on hundreds of machines and it works without problems.
So do I have to tell my boss and colleagues that this code is buggy and it is just luck that it works and this code need to be corrected?
After reading more docs, I have to conclude that yes, the code can be said to be incorrect. Particularly these docs on
ReadFile:Bear in mind that the MS docs are updated over time, and the docs may have been less clear or incomplete at the time the code was written.
It probably happens to work because the pipe is in message mode. It's strange to have a length prefix header with message mode pipes in the first place, because the message mode handles message boundaries for you. In this specific scenario, the entire message would already be in the local OS so the incorrect synchronous read would always succeed.
Indeed, the protocol (with a separate header) sounds like it was designed to work with a byte stream abstraction such as a byte mode pipe or TCP/IP connection. It is possible that the protocol was originally designed for byte mode pipes and they switched to message mode pipes when it wasn't working (the synchronous
ReadFilemay behave unexpectedly on a byte mode pipe since the message may not be completely present yet).