persistent_integer.cc revision 2fd51cc42dddba7568baec97f6b3701e2a77253b
12fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato// Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 22fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato// Use of this source code is governed by a BSD-style license that can be 32fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato// found in the LICENSE file. 42fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 52fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato#include "persistent_integer.h" 62fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 72fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato#include <fcntl.h> 82fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 92fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato#include <base/logging.h> 102fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato#include <base/posix/eintr_wrapper.h> 112fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 122fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato#include "metrics_library.h" 132fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 142fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatonamespace chromeos_metrics { 152fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 162fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato// The directory for the persistent storage. 172fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatoconst char* const kBackingFilesDirectory = "/var/log/metrics/"; 182fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 192fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato// Static class member instantiation. 202fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatobool PersistentInteger::testing_ = false; 212fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 222fd51cc42dddba7568baec97f6b3701e2a77253bLuigi SemenzatoPersistentInteger::PersistentInteger(const std::string& name) : 232fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato value_(0), 242fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato version_(kVersion), 252fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato name_(name), 262fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato synced_(false) { 272fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato if (testing_) { 282fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato backing_file_name_ = name_; 292fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato } else { 302fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato backing_file_name_ = kBackingFilesDirectory + name_; 312fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato } 322fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 332fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 342fd51cc42dddba7568baec97f6b3701e2a77253bLuigi SemenzatoPersistentInteger::~PersistentInteger() {} 352fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 362fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatovoid PersistentInteger::Set(int64 value) { 372fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato value_ = value; 382fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato Write(value); 392fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 402fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 412fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatoint64 PersistentInteger::Get() { 422fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato // If not synced, then read. If the read fails, it's a good idea to write. 432fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato if (!synced_ && !Read()) 442fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato Write(value_); 452fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato return value_; 462fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 472fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 482fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatoint64 PersistentInteger::GetAndClear() { 492fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato int64 v = Get(); 502fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato Set(0); 512fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato return v; 522fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 532fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 542fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatovoid PersistentInteger::Add(int64 x) { 552fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato Set(Get() + x); 562fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 572fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 582fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatovoid PersistentInteger::Write(int64 value) { 592fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato int fd = HANDLE_EINTR(open(backing_file_name_.c_str(), 602fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato O_WRONLY | O_CREAT | O_TRUNC, 612fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH)); 622fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato PCHECK(fd >= 0) << "cannot open " << backing_file_name_ << " for writing"; 632fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato PCHECK((HANDLE_EINTR(write(fd, &version_, sizeof(version_))) == 642fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato sizeof(version_)) && 652fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato (HANDLE_EINTR(write(fd, &value_, sizeof(value_))) == 662fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato sizeof(value_))) 672fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato << "cannot write to " << backing_file_name_; 682fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato close(fd); 692fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato synced_ = true; 702fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 712fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 722fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatobool PersistentInteger::Read() { 732fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato int fd = HANDLE_EINTR(open(backing_file_name_.c_str(), O_RDONLY)); 742fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato if (fd < 0) { 752fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato PLOG(WARNING) << "cannot open " << backing_file_name_ << " for reading"; 762fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato return false; 772fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato } 782fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato int32 version; 792fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato int64 value; 802fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato bool read_succeeded = false; 812fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato if (HANDLE_EINTR(read(fd, &version, sizeof(version))) == sizeof(version) && 822fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato version == version_ && 832fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato HANDLE_EINTR(read(fd, &value, sizeof(value))) == sizeof(value)) { 842fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato value_ = value; 852fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato read_succeeded = true; 862fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato synced_ = true; 872fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato } 882fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato close(fd); 892fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato return read_succeeded; 902fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 912fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 922fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzatovoid PersistentInteger::SetTestingMode(bool testing) { 932fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato testing_ = testing; 942fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} 952fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 962fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato 972fd51cc42dddba7568baec97f6b3701e2a77253bLuigi Semenzato} // namespace chromeos_metrics 98