1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 "nsISupportsImpl.h"
9 #include "mozilla/Assertions.h"
10 #ifndef XPCOM_GLUE_AVOID_NSPR
11 # include "nsPrintfCString.h"
12 # include "nsThreadUtils.h"
15 using namespace mozilla
;
17 nsresult NS_FASTCALL
NS_TableDrivenQI(void* aThis
, REFNSIID aIID
,
19 const QITableEntry
* aEntries
) {
21 if (aIID
.Equals(*aEntries
->iid
)) {
22 nsISupports
* r
= reinterpret_cast<nsISupports
*>(
23 reinterpret_cast<char*>(aThis
) + aEntries
->offset
);
30 } while (aEntries
->iid
);
32 *aInstancePtr
= nullptr;
33 return NS_ERROR_NO_INTERFACE
;
36 #ifndef XPCOM_GLUE_AVOID_NSPR
37 # ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
38 nsAutoOwningThread::nsAutoOwningThread() : mThread(PR_GetCurrentThread()) {}
40 void nsAutoOwningThread::AssertCurrentThreadOwnsMe(const char* msg
) const {
41 if (MOZ_UNLIKELY(!IsCurrentThread())) {
42 // `msg` is a string literal by construction.
43 MOZ_CRASH_UNSAFE(msg
);
47 bool nsAutoOwningThread::IsCurrentThread() const {
48 return mThread
== PR_GetCurrentThread();
51 nsAutoOwningEventTarget::nsAutoOwningEventTarget()
52 : mTarget(GetCurrentSerialEventTarget()) {
56 nsAutoOwningEventTarget::nsAutoOwningEventTarget(
57 const nsAutoOwningEventTarget
& aOther
)
58 : mTarget(aOther
.mTarget
) {
62 nsAutoOwningEventTarget
& nsAutoOwningEventTarget::operator=(
63 const nsAutoOwningEventTarget
& aRhs
) {
64 nsISerialEventTarget
* previous
= std::exchange(mTarget
, aRhs
.mTarget
);
70 nsAutoOwningEventTarget::~nsAutoOwningEventTarget() { NS_RELEASE(mTarget
); }
72 void nsAutoOwningEventTarget ::AssertCurrentThreadOwnsMe(
73 const char* msg
) const {
74 if (MOZ_UNLIKELY(!IsCurrentThread())) {
75 // `msg` is a string literal by construction.
76 MOZ_CRASH_UNSAFE(msg
);
80 bool nsAutoOwningEventTarget::IsCurrentThread() const {
81 return mTarget
->IsOnCurrentThread();
86 namespace mozilla::detail
{
87 class ProxyDeleteVoidRunnable final
: public CancelableRunnable
{
89 ProxyDeleteVoidRunnable(const char* aName
, void* aPtr
,
90 DeleteVoidFunction
* aDeleteFunc
)
91 : CancelableRunnable(aName
), mPtr(aPtr
), mDeleteFunc(aDeleteFunc
) {}
93 NS_IMETHOD
Run() override
{
101 // Mimics the behaviour in `ProxyRelease`, freeing the resource when
103 nsresult
Cancel() override
{ return Run(); }
105 # ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
106 NS_IMETHOD
GetName(nsACString
& aName
) override
{
110 aName
.AssignLiteral("ProxyDeleteVoidRunnable");
117 ~ProxyDeleteVoidRunnable() {
119 # ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
122 "ProxyDeleteVoidRunnable for '%s' never run, leaking!", mName
)
125 NS_WARNING("ProxyDeleteVoidRunnable never run, leaking!");
131 DeleteVoidFunction
* mDeleteFunc
;
134 void ProxyDeleteVoid(const char* aName
, nsISerialEventTarget
* aTarget
,
135 void* aPtr
, DeleteVoidFunction
* aDeleteFunc
) {
138 MOZ_ASSERT(aDeleteFunc
);
140 NS_WARNING(nsPrintfCString("no target for '%s', leaking!", aName
).get());
144 if (aTarget
->IsOnCurrentThread()) {
148 nsresult rv
= aTarget
->Dispatch(
149 MakeAndAddRef
<ProxyDeleteVoidRunnable
>(aName
, aPtr
, aDeleteFunc
),
152 NS_WARNING(nsPrintfCString("failed to post '%s', leaking!", aName
).get());
155 } // namespace mozilla::detail