76 lines
2.6 KiB
C++
76 lines
2.6 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef nsUpdateMutex_h__
|
|
#define nsUpdateMutex_h__
|
|
|
|
#include "nsIUpdateService.h"
|
|
#include "nsProfileLock.h"
|
|
#include "mozilla/StaticMutex.h"
|
|
|
|
/**
|
|
* A primitive object type suitable for acquiring the update mutex. It is
|
|
* composed of two parts:
|
|
* - a nsProfileLock taken on the update directory, to ensure that if two
|
|
* instances running from the same application path try to acquire the
|
|
* update mutex simultaneously, only one of them succeeds;
|
|
* - a StaticMutex, to ensure that even within the same instance of the
|
|
* application, it is never possible to successfully acquire two
|
|
* UpdateMutexImpl objects simultaneously.
|
|
*
|
|
* While the second part is not strictly required, it makes reasoning about
|
|
* these objects easier, and it helps us simulate an acquisition coming from
|
|
* another instance in tests.
|
|
*
|
|
* Contrary to a nsIUpdateMutex object, an UpdateMutexImpl object does not
|
|
* keep track of whether it is currently locked or unlocked. Therefore, it is
|
|
* the responsibility of the caller to guarantee the following:
|
|
* - a call to Unlock() must only occur after a matching successful call to
|
|
* TryLock();
|
|
* - no second call to TryLock() should ever occur after a successful first
|
|
* call to TryLock(), unless a call to Unlock() occured in the middle.
|
|
*/
|
|
class MOZ_CAPABILITY("mutex") UpdateMutexImpl {
|
|
public:
|
|
[[nodiscard]] bool TryLock() MOZ_TRY_ACQUIRE(true);
|
|
|
|
void Unlock() MOZ_CAPABILITY_RELEASE();
|
|
|
|
private:
|
|
static mozilla::StaticMutex sInProcessMutex;
|
|
|
|
nsProfileLock mCrossProcessLock;
|
|
};
|
|
|
|
/**
|
|
* An XPCOM wrapper for the UpdateMutexImpl primitive type, achieving the same
|
|
* goals but through a safe XPCOM-compatible nsIUpdateMutex interface.
|
|
*
|
|
* Contrary to UpdateMutexImpl objects, nsUpdateMutex objects track whether
|
|
* they are currently locked or unlocked. It is therefore always safe to call
|
|
* TryLock() or Unlock() on a nsUpdateMutex object.
|
|
*
|
|
* See nsIUpdateMutex in nsUpdateService.idl for more details.
|
|
*/
|
|
class nsUpdateMutex final : public nsIUpdateMutex {
|
|
public:
|
|
explicit nsUpdateMutex() = default;
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
NS_DECL_NSIUPDATEMUTEX
|
|
|
|
private:
|
|
UpdateMutexImpl mUpdateMutexImpl;
|
|
bool mIsLocked{};
|
|
|
|
virtual ~nsUpdateMutex() {
|
|
if (mIsLocked) {
|
|
Unlock();
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // nsUpdateMutex_h__
|