blob: 2b2cdb400b74d1469659dc22297dd73afac097ce [file] [log] [blame]
// Copyright 2018 The Goma 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 DEVTOOLS_GOMA_CLIENT_COMPILER_INFO_STATE_H_
#define DEVTOOLS_GOMA_CLIENT_COMPILER_INFO_STATE_H_
#include <memory>
#include <string>
#include "compiler_flags.h"
#include "compiler_info.h"
using std::string;
namespace devtools_goma {
// CompilerInfoState contains CompilerInfo (created from local system) and
// disabled status (updated by response from remote).
// ref counted.
class CompilerInfoState {
public:
// Constructor creates with refcnt_==0.
// Before sharing it, caller should call Ref.
// Takes ownership of data.
explicit CompilerInfoState(std::unique_ptr<CompilerInfoData> data);
const CompilerInfo& info() const { return *compiler_info_; }
// refcnt returns the current reference count.
// potentially race. when you get the value, actual refcnt may be updated.
// use be careful.
int refcnt() const;
// Returns if it has been disabled (e.g. compiler not found in backend)
// Potential race (i.e. even if caller gets disabled()==false, it will
// become true while checking input files or calling rpc), but it might
// be acceptable.
bool disabled() const;
string GetDisabledReason() const;
void SetDisabled(bool disabled, const string& disabled_reason);
void Use(const string& local_compiler_path, const CompilerFlags& flags);
int used() const;
void UpdateLastUsedAt();
private:
friend class ScopedCompilerInfoState;
friend class CompilerInfoCache;
friend class CompilerInfoCacheTest;
~CompilerInfoState();
static std::unique_ptr<CompilerInfo> MakeCompilerInfo(
std::unique_ptr<CompilerInfoData> data);
void Ref();
void Deref();
std::unique_ptr<CompilerInfo> compiler_info_;
mutable Lock mu_;
int refcnt_ GUARDED_BY(mu_);
// When server side does not have the information about this compiler,
// it's disabled.
bool disabled_ GUARDED_BY(mu_);
string disabled_reason_ GUARDED_BY(mu_);
int used_;
DISALLOW_COPY_AND_ASSIGN(CompilerInfoState);
};
// ScopedCompilerInfoState manages lifecycle of CompilerInfoState.
// thread-unsafe.
//
// Initializes
// ScopedCompilerInfoState cis;
// cis.FillFromCompilerOutputs(...);
//
// share compiler_info_state with cis:
// ScopedCompilerInfoState state;
// state.reset(cis.get());
//
// ScopedCompilerInfoState state2(cis);
//
// transfer compiler_info_state from cis:
// ScopedCompilerInfoState state(std::move(cis));
class ScopedCompilerInfoState {
public:
ScopedCompilerInfoState() : state_(nullptr) {}
explicit ScopedCompilerInfoState(CompilerInfoState* state);
~ScopedCompilerInfoState();
ScopedCompilerInfoState(ScopedCompilerInfoState&& state) noexcept
: state_(std::move(state.state_)) {
state.state_ = nullptr;
}
ScopedCompilerInfoState& operator=(ScopedCompilerInfoState&& other) {
std::swap(state_, other.state_);
return *this;
}
CompilerInfoState* get() const { return state_; }
// reset derefs current state and refs given state.
void reset(CompilerInfoState* state);
// swap swaps state with other.
// useful to transfer state from other without modifying refcnt.
void swap(ScopedCompilerInfoState* other);
bool disabled() const;
string GetDisabledReason() const;
private:
CompilerInfoState* state_;
DISALLOW_COPY_AND_ASSIGN(ScopedCompilerInfoState);
};
} // namespace devtools_goma
#endif // DEVTOOLS_GOMA_CLIENT_COMPILER_INFO_STATE_H_