summaryrefslogtreecommitdiffstats
path: root/chromecast/crash/linux/synchronized_minidump_manager.h
blob: c8277ba011c09620042e803e59755d2cc837a1ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_CRASH_LINUX_SYNCHRONIZED_MINIDUMP_MANAGER_H_
#define CHROMECAST_CRASH_LINUX_SYNCHRONIZED_MINIDUMP_MANAGER_H_

#include <string>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/scoped_vector.h"
#include "base/values.h"
#include "chromecast/crash/linux/dump_info.h"

namespace chromecast {

// Abstract base class for mutually-exclusive minidump handling. Ensures
// synchronized access among instances of this class to the minidumps directory
// using a file lock. The "lockfile" also holds serialized metadata about each
// of the minidumps in the directory. Derived classes should not access the
// lockfile directly. Instead, use protected methods to query and modify the
// metadata, but only within the implementation of DoWork().
//
// This class holds an in memory representation of the lockfile while it is
// held. Modifier methods work on this in memory representation. When the
// lockfile is released, the in memory representation is written to file.
class SynchronizedMinidumpManager {
 public:
  virtual ~SynchronizedMinidumpManager();

  // Returns whether this object's file locking method is nonblocking or not.
  bool non_blocking() { return non_blocking_; }

  // Sets the file locking mechansim to be nonblocking or not.
  void set_non_blocking(bool non_blocking) { non_blocking_ = non_blocking; }

 protected:
  SynchronizedMinidumpManager();

  // Acquires the lock, calls DoWork(), then releases the lock when DoWork()
  // returns. Derived classes should expose a method which calls this. Returns
  // the status of DoWork(), or -1 if the lock was not successfully acquired.
  int AcquireLockAndDoWork();

  // Derived classes must implement this method. It will be called from
  // DoWorkLocked after the lock has been successfully acquired. The lockfile
  // shall be accessed and mutated only through the methods below. All other
  // files shall be managed as needed by the derived class.
  virtual int DoWork() = 0;

  // Get the current dumps in the lockfile.
  ScopedVector<DumpInfo> GetDumps();

  // Set |dumps| as the dumps in |lockfile_|, replacing current list of dumps.
  int SetCurrentDumps(const ScopedVector<DumpInfo>& dumps);

  // Serialize |dump_info| and append it to the lockfile. Note that the child
  // class must only call this inside DoWork(). This should be the only method
  // used to write to the lockfile. Only call this if the minidump has been
  // generated in the minidumps directory successfully. Returns 0 on success,
  // -1 otherwise.
  int AddEntryToLockFile(const DumpInfo& dump_info);

  // Remove the lockfile entry at |index| in the current in memory
  // representation of the lockfile. If the index is invalid returns -1.
  // Otherwise returns 0.
  int RemoveEntryFromLockFile(int index);

  // Get the number of un-uploaded dumps in the dump_path directory.
  // If delete_all_dumps is true, also delete all these files, this is used to
  // clean lingering dump files.
  int GetNumDumps(bool delete_all_dumps);

  // If true, the flock on the lockfile will be nonblocking.
  bool non_blocking_;

  // Cached path for the minidumps directory.
  base::FilePath dump_path_;

 private:
  // Acquire the lock file. Blocks if another process holds it, or if called
  // a second time by the same process. Returns the fd of the lockfile if
  // successful, or -1 if failed.
  int AcquireLockFile();

  // Parse the lockfile, populating |lockfile_contents_| for modifier functions
  // to use. Return -1 if an error occurred. Otherwise, return 0. This must not
  // be called unless |this| has acquired the lock.
  int ParseLockFile();

  // Write deserialized lockfile to |lockfile_path_|.
  int WriteLockFile(const base::Value& contents);

  // Creates an empty lock file.
  int CreateEmptyLockFile();

  // Release the lock file with the associated *fd*.
  void ReleaseLockFile();

  std::string lockfile_path_;
  int lockfile_fd_;
  scoped_ptr<base::Value> lockfile_contents_;

  DISALLOW_COPY_AND_ASSIGN(SynchronizedMinidumpManager);
};

}  // namespace chromecast

#endif  // CHROMECAST_CRASH_LINUX_SYNCHRONIZED_MINIDUMP_MANAGER_H_