Date: Tue, 15 Jun 2021 19:29:59 -0400 From: Kurt Hackenberg <kh@panix.com> To: freebsd-questions@freebsd.org Subject: Re: Is a successful call to write(2) atomic? Message-ID: <b6349909-7073-52d5-504e-acc88cbd3a21@panix.com> In-Reply-To: <25718.1623792483@segfault.tristatelogic.com> References: <25718.1623792483@segfault.tristatelogic.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2021/06/15 17:28, Ronald F. Guilmette wrote: >> There are two common solutions. Paul suggested one of them: serialize >> access through a single process. > > I stated in response that I was 100% sure that that would solve the problem. > Upon further reflection however, I wish to withdraw that assertion. > > In fact, it now appear to me that the notion of using a pipe to pass > (indivisible?) lines of data up to a parent/controller process from a > number of child processes, and then allowing that parent to "sequentialize" > those data lines onto disk actually just moves the problem around, without > actually addressing it. > > Consider this: If single ("successful") call to write() (which returns a > value indicating that all bytes were written) fails to guarantee that > the entire written buffer will be treated as an indivisible unit, then > it likely fails to provide that fundamental guarantee *regardless* of > whether the specific file descriptor being written to is associated > with either (a) a file on the local hard disk or (b) a pipe being used > to communicate with a another process. You're right. Sorry, I didn't give enough attention to the details of that solution. But it works by just changing the messaging mechanism a little: Have many pipes, one for each sender, all sending to the single write process, which uses the system call select() to wait for activity on any of them. The write process still has to make sure it reads all of a message from a pipe before going on to another pipe, but that's straightforward, if it knows how much data to expect. Did you mentions lines -- each sender sends one line to be written, and each line must be atomic, but it's OK to write the many lines in any order? If so, the writer process just keeps reading a pipe until it gets a complete line. If it's not lines, then do something similar -- have an end-of-message marker, or precede each message with its length in bytes, or hard-code a fixed length for all messages -- any way for the writer process to know it has a complete message.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b6349909-7073-52d5-504e-acc88cbd3a21>