X-Spam-Check-By: sourceware.org Message-ID: <4640A009.4010408@scsiguy.com> Date: Tue, 08 May 2007 10:06:33 -0600 From: "Justin T. Gibbs" User-Agent: Thunderbird 2.0.0.0 (Windows/20070326) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Buffer size problem with FIFOs [TEST Program Included] Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com I have an application (Berkeley make) that manages parallelism using a FIFO. The FIFO acts as a pool for "work tokens". All processes, including the first that opens and "primes" the FIFO, must obtain a token from the FIFO before performing a job and return that token when the job is complete. Priming the FIFO entails writing N (number of concurrent jobs) 1 byte tokens into the FIFO. The only problem with this scheme is that it relies on the system having a PIPE_BUF value >= N, and FIFOs that honor this value. Otherwise the tokens aren't guaranteed to fit in the FIFO. In playing with this in cygwin, I quickly discovered that the named pipes used to implement FIFOs are created with a size of 1 byte. This is far less than cygwin's PIPE_BUF (4096) or the POSIX mandated minimum for PIPE_BUF (512). After reviewing the code, the setting seems deliberate (fhandler_pipe::create_selectable() has an explicit check to avoid bumping the size up to PIPE_BUF for FIFOs), but I couldn't find any code comments or changelog entries to explain the restriction. Can anyone explain the requirement for this limit? My limited testing (large parallel builds) after recompiling the cygwin DLL from CVS with the value bumped up to 512, has shown no ill effects. Here is a simple program that shows the problem. It runs correctly on the "unix" platforms I have access to (FreeBSD, Linux), but hangs with an unmodified Cygwin. Note that the behavior does not change if I use separate fds for reads and writes (O_RDWR is not guaranteed to work in POSIX - however cygwin does support it and it makes the sample program simpler). Thanks, Justin #include #include int main(int argc, const char **argv) { const char fifoName[] = "/tmp/test_fifo"; /** * Create a FIFO to store our tokens. */ if (mkfifo(fifoName, 0600) == 0) { int fd; if ((fd = open(fifoName, O_RDWR | O_BINARY, 0600)) >= 0) { /** Access the FIFO in nonblocking mode. */ fcntl(fd, F_SETFL, O_NONBLOCK); /* Fill FIFO with two tokens. This hangs on Cygwin. */ if (write(fd, "++", 2) == -1) warn("Unable to write tokens"); else { int count; char token; count = 0; while (1) { if (read(fd, &token, 1) == -1) break; count++; } printf("Read %d tokens\n", count); } } unlink(fifoName); } return (0); } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/