Skip site navigation (1)Skip section navigation (2)
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>