mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-20 04:07:18 +02:00
75 lines
2.8 KiB
C++
75 lines
2.8 KiB
C++
// Copyright 2026 Mocktail Project Authors
|
|
//
|
|
// 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.
|
|
|
|
#ifndef MOCKTAIL_RUNTIME_SINGLE_INSTANCE_LOCK_H_
|
|
#define MOCKTAIL_RUNTIME_SINGLE_INSTANCE_LOCK_H_
|
|
|
|
#include <filesystem>
|
|
#include <string>
|
|
|
|
#include "runtime/environment.h"
|
|
#include "runtime/runtime_paths.h"
|
|
|
|
namespace mocktail {
|
|
namespace runtime {
|
|
|
|
// Stable lowercase-hex namespace derived from the executable installation
|
|
// path. Separate source trees cannot steal each other's browser launches,
|
|
// while every process started from one installed binary shares one owner.
|
|
std::string CurrentExecutableInstanceKey();
|
|
|
|
// Holds a non-blocking advisory lock for one Mocktail game process. The
|
|
// descriptor remains open for the lifetime of this object, so the kernel also
|
|
// releases the lock after a crash or forced process termination.
|
|
class SingleInstanceLock final {
|
|
public:
|
|
enum class Status { kAcquired, kAlreadyRunning, kError };
|
|
|
|
~SingleInstanceLock();
|
|
|
|
SingleInstanceLock(const SingleInstanceLock&) = delete;
|
|
SingleInstanceLock& operator=(const SingleInstanceLock&) = delete;
|
|
SingleInstanceLock(SingleInstanceLock&& other) noexcept;
|
|
SingleInstanceLock& operator=(SingleInstanceLock&& other) noexcept;
|
|
|
|
static SingleInstanceLock AcquireForCurrentUser();
|
|
// Updater canaries use fully isolated data/cache/state roots and an
|
|
// isolated lock so they can validate a candidate while the user's current
|
|
// payload remains open. Normal launches use one lock per user and Mocktail
|
|
// installation path.
|
|
static SingleInstanceLock AcquireForLaunch(const Environment& environment,
|
|
const RuntimePaths& paths);
|
|
static SingleInstanceLock Acquire(const std::filesystem::path& lock_file);
|
|
|
|
Status status() const { return status_; }
|
|
bool acquired() const { return status_ == Status::kAcquired; }
|
|
bool already_running() const { return status_ == Status::kAlreadyRunning; }
|
|
const std::filesystem::path& path() const { return path_; }
|
|
const std::string& error() const { return error_; }
|
|
|
|
private:
|
|
SingleInstanceLock(int descriptor, Status status, std::filesystem::path path,
|
|
std::string error);
|
|
|
|
int descriptor_ = -1;
|
|
Status status_ = Status::kError;
|
|
std::filesystem::path path_;
|
|
std::string error_;
|
|
};
|
|
|
|
} // namespace runtime
|
|
} // namespace mocktail
|
|
|
|
#endif // MOCKTAIL_RUNTIME_SINGLE_INSTANCE_LOCK_H_
|