From db3edc40184b8235df92fe44df066944bbd130aa Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 15 Jul 2013 07:53:45 -0400 Subject: [PATCH] Use ::write instead of pwrite in AudioSource::compute_and_write_peaks for portability This destroys the atomicity of pwrite() and thus suggests that we should do something else to ensure that multithread access to peakfiles (if it does in fact exist) is safe. OTOH, there may be no such thing, since they are designed for the GUI, which is single threaded (for now) --- libs/ardour/audiosource.cc | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 776749fb57..ff92b8977d 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -725,12 +725,18 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData); -#ifndef WIN32 - if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { + off_t offset = lseek (_peakfile_fd, byte, SEEK_SET); + + if (offset != byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; return -1; } -#endif + _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); { @@ -840,14 +846,24 @@ AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, frame } } -#ifndef WIN32 - if (::pwrite (_peakfile_fd, peakbuf.get(), sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { + + off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET); + + if (offset != first_peak_byte) { + error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg; + return -1; + } + + ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed; + + ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write); + + if (bytes_written != bytes_to_write) { error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; return -1; } -#endif - _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); + _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write)); if (frames_done) { Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);