summaryrefslogtreecommitdiff
path: root/src/serialize/protobuf_io.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialize/protobuf_io.cc')
-rw-r--r--src/serialize/protobuf_io.cc173
1 files changed, 0 insertions, 173 deletions
diff --git a/src/serialize/protobuf_io.cc b/src/serialize/protobuf_io.cc
deleted file mode 100644
index 1b6420f..0000000
--- a/src/serialize/protobuf_io.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "protobuf_io.h"
-
-#include "common/trace.h"
-#include "serialize/arena_ptr.h"
-
-#include <android-base/chrono_utils.h>
-#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utils/Trace.h>
-
-#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
-#include "system/iorap/src/serialize/TraceFile.pb.h"
-
-namespace iorap {
-namespace serialize {
-
-ArenaPtr<proto::TraceFile> ProtobufIO::Open(std::string file_path) {
- // TODO: file a bug about this.
- // Note: can't use {} here, clang think it's narrowing from long->int.
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(::open(file_path.c_str(), O_RDONLY)));
- if (fd.get() < 0) {
- PLOG(DEBUG) << "ProtobufIO: open failed: " << file_path;
- return nullptr;
- }
-
- return Open(fd.get(), file_path.c_str());
-}
-
-ArenaPtr<proto::TraceFile> ProtobufIO::Open(int fd, const char* file_path) {
-
- ScopedFormatTrace atrace_protobuf_io_open(ATRACE_TAG_ACTIVITY_MANAGER,
- "ProtobufIO::Open %s",
- file_path);
- android::base::Timer timer{};
-
- struct stat buf;
- if (fstat(fd, /*out*/&buf) < 0) {
- PLOG(ERROR) << "ProtobufIO: open error, fstat failed: " << file_path;
- return nullptr;
- }
- // XX: off64_t for stat::st_size ?
-
- // Using the mmap appears to be the only way to do zero-copy with protobuf lite.
- void* data = mmap(/*addr*/nullptr,
- buf.st_size,
- PROT_READ, MAP_SHARED | MAP_POPULATE,
- fd,
- /*offset*/0);
- if (data == nullptr) {
- PLOG(ERROR) << "ProtobufIO: open error, mmap failed: " << file_path;
- return nullptr;
- }
-
- ArenaPtr<proto::TraceFile> protobuf_trace_file = ArenaPtr<proto::TraceFile>::Make();
- if (protobuf_trace_file == nullptr) {
- LOG(ERROR) << "ProtobufIO: open error, failed to create arena: " << file_path;
- return nullptr;
- }
-
- google::protobuf::io::ArrayInputStream protobuf_input_stream{data, static_cast<int>(buf.st_size)};
- if (!protobuf_trace_file->ParseFromZeroCopyStream(/*in*/&protobuf_input_stream)) {
- // XX: Does protobuf on android already have the right LogHandler ?
- LOG(ERROR) << "ProtobufIO: open error, protobuf parsing failed: " << file_path;
- return nullptr;
- }
-
- if (munmap(data, buf.st_size) < 0) {
- PLOG(WARNING) << "ProtobufIO: open problem, munmap failed, possibly memory leak? "
- << file_path;
- }
-
- LOG(VERBOSE) << "ProtobufIO: open succeeded: " << file_path << ", duration: " << timer;
- return protobuf_trace_file;
-}
-
-iorap::expected<size_t /*bytes written*/, int /*errno*/> ProtobufIO::WriteFully(
- const ::google::protobuf::MessageLite& message,
- std::string_view file_path) {
-
- std::string str{file_path};
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(
- ::open(str.c_str(),
- O_CREAT | O_TRUNC | O_RDWR,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))); // ugo: rw-rw----
- if (fd.get() < 0) {
- int err = errno;
- PLOG(ERROR) << "ProtobufIO: open failed: " << file_path;
- return unexpected{err};
- }
-
- return WriteFully(message, fd.get(), file_path);
-}
-
-iorap::expected<size_t /*bytes written*/, int /*errno*/> ProtobufIO::WriteFully(
- const ::google::protobuf::MessageLite& message,
- int fd,
- std::string_view file_path) {
-
- int byte_size = message.ByteSize();
- if (byte_size < 0) {
- DCHECK(false) << "Invalid protobuf size: " << byte_size;
- LOG(ERROR) << "ProtobufIO: Invalid protobuf size: " << byte_size;
- return unexpected{EDOM};
- }
- size_t serialized_size = static_cast<size_t>(byte_size);
-
- // Change the file to be exactly the length of the protobuf.
- if (ftruncate(fd, static_cast<off_t>(serialized_size)) < 0) {
- int err = errno;
- PLOG(ERROR) << "ProtobufIO: ftruncate (size=" << serialized_size << ") failed";
- return unexpected{err};
- }
-
- // Using the mmap appears to be the only way to do zero-copy with protobuf lite.
- void* data = mmap(/*addr*/nullptr,
- serialized_size,
- PROT_WRITE,
- MAP_SHARED,
- fd,
- /*offset*/0);
- if (data == nullptr) {
- int err = errno;
- PLOG(ERROR) << "ProtobufIO: mmap failed: " << file_path;
- return unexpected{err};
- }
-
- // Zero-copy write from protobuf to file via memory-map.
- ::google::protobuf::io::ArrayOutputStream output_stream{data, byte_size};
- if (!message.SerializeToZeroCopyStream(/*inout*/&output_stream)) {
- // This should never happen since we pre-allocated the file and memory map to be large
- // enough to store the full protobuf.
- DCHECK(false) << "ProtobufIO:: SerializeToZeroCopyStream failed despite precalculating size";
- LOG(ERROR) << "ProtobufIO: SerializeToZeroCopyStream failed";
- return unexpected{EXFULL};
- }
-
- // Guarantee that changes are written back prior to munmap.
- if (msync(data, static_cast<size_t>(serialized_size), MS_SYNC) < 0) {
- int err = errno;
- PLOG(ERROR) << "ProtobufIO: msync failed";
- return unexpected{err};
- }
-
- if (munmap(data, serialized_size) < 0) {
- PLOG(WARNING) << "ProtobufIO: munmap failed, possibly memory leak? "
- << file_path;
- }
-
- return serialized_size;
-}
-
-} // namespace serialize
-} // namespace iorap
-