Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / toolkit / mozapps / defaultagent / WindowsMutex.cpp
blob804c3e6d75b5139aacc37240f16621405dae5fc6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Logging.h"
9 #include "WindowsMutex.h"
11 namespace mozilla::default_agent {
13 using mozilla::LogLevel;
15 static LazyLogModule gWindowsMutexLog("WindowsMutex");
17 NS_IMPL_ISUPPORTS(WindowsMutexFactory, nsIWindowsMutexFactory)
19 NS_IMETHODIMP
20 WindowsMutexFactory::CreateMutex(const nsAString& aName,
21 nsIWindowsMutex** aWindowsMutex) {
22 nsAutoHandle mutex;
23 auto name = PromiseFlatString(aName);
25 mutex.own(CreateMutexW(nullptr, FALSE, name.get()));
26 if (mutex.get() == nullptr) {
27 MOZ_LOG(gWindowsMutexLog, LogLevel::Error,
28 ("Couldn't open mutex \"%s\": %#lX",
29 NS_ConvertUTF16toUTF8(name).get(), GetLastError()));
30 return NS_ERROR_NOT_AVAILABLE;
33 RefPtr<WindowsMutex> nsMutex = new WindowsMutex(name, mutex);
34 nsMutex.forget(aWindowsMutex);
35 return NS_OK;
38 WindowsMutex::WindowsMutex(const nsString& aName, nsAutoHandle& aMutex)
39 : mName(NS_ConvertUTF16toUTF8(aName)), mLocked(false) {
40 mMutex.steal(aMutex);
43 WindowsMutex::~WindowsMutex() {
44 Unlock();
45 // nsAutoHandle will take care of closing the mutex's handle.
48 NS_IMPL_ISUPPORTS(WindowsMutex, nsIWindowsMutex)
50 NS_IMETHODIMP
51 WindowsMutex::TryLock() {
52 // This object may be used on the main thread, so don't wait if it's
53 // not signaled.
54 DWORD mutexStatus = WaitForSingleObject(mMutex.get(), 0);
55 if (mutexStatus == WAIT_OBJECT_0) {
56 mLocked = true;
57 } else if (mutexStatus == WAIT_TIMEOUT) {
58 MOZ_LOG(gWindowsMutexLog, LogLevel::Warning,
59 ("Timed out waiting for mutex \"%s\"", mName.get()));
60 } else if (mutexStatus == WAIT_ABANDONED) {
61 // This status code means that we are supposed to check our data for
62 // consistency as the last locking process didn't signal intentional
63 // unlocking which might indicate it crashed mid-operation. Current uses of
64 // this `WindowsMutex` don't need to worry about corruption of the locked
65 // object, if needed the `nsIWindowsMutex` interface should be extended.
66 MOZ_LOG(gWindowsMutexLog, LogLevel::Warning,
67 ("Found abandoned mutex \"%s\". Continuing...", mName.get()));
68 mLocked = true;
69 } else {
70 // The only other documented status code is WAIT_FAILED. In the case that
71 // we somehow get some other code, that is also an error.
72 MOZ_LOG(gWindowsMutexLog, LogLevel::Error,
73 ("Failed to wait on mutex: mName: %s, error %#lX", mName.get(),
74 GetLastError()));
76 return mLocked ? NS_OK : NS_ERROR_NOT_AVAILABLE;
79 NS_IMETHODIMP
80 WindowsMutex::IsLocked(bool* aLocked) {
81 *aLocked = mLocked;
82 return NS_OK;
85 NS_IMETHODIMP
86 WindowsMutex::Unlock() {
87 nsresult rv = NS_OK;
89 if (mLocked) {
90 BOOL success = ReleaseMutex(mMutex.get());
91 if (!success) {
92 MOZ_LOG(gWindowsMutexLog, LogLevel::Error,
93 ("Failed to release mutex \"%s\"", mName.get()));
94 rv = NS_ERROR_UNEXPECTED;
97 mLocked = false;
100 return rv;
103 } // namespace mozilla::default_agent