mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
185
xpcom/build/NSPRInterposer.cpp
Normal file
185
xpcom/build/NSPRInterposer.cpp
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "IOInterposer.h"
|
||||
#include "NSPRInterposer.h"
|
||||
|
||||
#include "prio.h"
|
||||
#include "private/pprio.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nscore.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/* Original IO methods */
|
||||
PRCloseFN sCloseFn = nullptr;
|
||||
PRReadFN sReadFn = nullptr;
|
||||
PRWriteFN sWriteFn = nullptr;
|
||||
PRFsyncFN sFSyncFn = nullptr;
|
||||
PRFileInfoFN sFileInfoFn = nullptr;
|
||||
PRFileInfo64FN sFileInfo64Fn = nullptr;
|
||||
|
||||
/**
|
||||
* RAII class for timing the duration of an NSPR I/O call and reporting the
|
||||
* result to the IOInterposeObserver API.
|
||||
*/
|
||||
class NSPRIOAutoObservation : public IOInterposeObserver::Observation
|
||||
{
|
||||
public:
|
||||
explicit NSPRIOAutoObservation(IOInterposeObserver::Operation aOp)
|
||||
: IOInterposeObserver::Observation(aOp, "NSPRIOInterposer")
|
||||
{
|
||||
}
|
||||
|
||||
~NSPRIOAutoObservation()
|
||||
{
|
||||
Report();
|
||||
}
|
||||
};
|
||||
|
||||
PRStatus PR_CALLBACK
|
||||
interposedClose(PRFileDesc* aFd)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpClose);
|
||||
return sCloseFn(aFd);
|
||||
}
|
||||
|
||||
int32_t PR_CALLBACK
|
||||
interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpRead);
|
||||
return sReadFn(aFd, aBuf, aAmt);
|
||||
}
|
||||
|
||||
int32_t PR_CALLBACK
|
||||
interposedWrite(PRFileDesc* aFd, const void* aBuf, int32_t aAmt)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpWrite);
|
||||
return sWriteFn(aFd, aBuf, aAmt);
|
||||
}
|
||||
|
||||
PRStatus PR_CALLBACK
|
||||
interposedFSync(PRFileDesc* aFd)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpFSync);
|
||||
return sFSyncFn(aFd);
|
||||
}
|
||||
|
||||
PRStatus PR_CALLBACK
|
||||
interposedFileInfo(PRFileDesc* aFd, PRFileInfo* aInfo)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
|
||||
return sFileInfoFn(aFd, aInfo);
|
||||
}
|
||||
|
||||
PRStatus PR_CALLBACK
|
||||
interposedFileInfo64(PRFileDesc* aFd, PRFileInfo64* aInfo)
|
||||
{
|
||||
// If we don't have a valid original function pointer something is very wrong.
|
||||
NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL");
|
||||
|
||||
NSPRIOAutoObservation timer(IOInterposeObserver::OpStat);
|
||||
return sFileInfo64Fn(aFd, aInfo);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
InitNSPRIOInterposing()
|
||||
{
|
||||
// Check that we have not interposed any of the IO methods before
|
||||
MOZ_ASSERT(!sCloseFn && !sReadFn && !sWriteFn && !sFSyncFn && !sFileInfoFn &&
|
||||
!sFileInfo64Fn);
|
||||
|
||||
// We can't actually use this assertion because we initialize this code
|
||||
// before XPCOM is initialized, so NS_IsMainThread() always returns false.
|
||||
// MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Get IO methods from NSPR and const cast the structure so we can modify it.
|
||||
PRIOMethods* methods = const_cast<PRIOMethods*>(PR_GetFileMethods());
|
||||
|
||||
// Something is badly wrong if we don't get IO methods... However, we don't
|
||||
// want to crash over that in non-debug builds. This is unlikely to happen
|
||||
// so an assert is enough, no need to report it to the caller.
|
||||
MOZ_ASSERT(methods);
|
||||
if (!methods) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store original functions
|
||||
sCloseFn = methods->close;
|
||||
sReadFn = methods->read;
|
||||
sWriteFn = methods->write;
|
||||
sFSyncFn = methods->fsync;
|
||||
sFileInfoFn = methods->fileInfo;
|
||||
sFileInfo64Fn = methods->fileInfo64;
|
||||
|
||||
// Overwrite with our interposed functions
|
||||
methods->close = &interposedClose;
|
||||
methods->read = &interposedRead;
|
||||
methods->write = &interposedWrite;
|
||||
methods->fsync = &interposedFSync;
|
||||
methods->fileInfo = &interposedFileInfo;
|
||||
methods->fileInfo64 = &interposedFileInfo64;
|
||||
}
|
||||
|
||||
void
|
||||
ClearNSPRIOInterposing()
|
||||
{
|
||||
// If we have already cleared IO interposing, or not initialized it this is
|
||||
// actually bad.
|
||||
MOZ_ASSERT(sCloseFn && sReadFn && sWriteFn && sFSyncFn && sFileInfoFn &&
|
||||
sFileInfo64Fn);
|
||||
|
||||
// Get IO methods from NSPR and const cast the structure so we can modify it.
|
||||
PRIOMethods* methods = const_cast<PRIOMethods*>(PR_GetFileMethods());
|
||||
|
||||
// Something is badly wrong if we don't get IO methods... However, we don't
|
||||
// want to crash over that in non-debug builds. This is unlikely to happen
|
||||
// so an assert is enough, no need to report it to the caller.
|
||||
MOZ_ASSERT(methods);
|
||||
if (!methods) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore original functions
|
||||
methods->close = sCloseFn;
|
||||
methods->read = sReadFn;
|
||||
methods->write = sWriteFn;
|
||||
methods->fsync = sFSyncFn;
|
||||
methods->fileInfo = sFileInfoFn;
|
||||
methods->fileInfo64 = sFileInfo64Fn;
|
||||
|
||||
// Forget about original functions
|
||||
sCloseFn = nullptr;
|
||||
sReadFn = nullptr;
|
||||
sWriteFn = nullptr;
|
||||
sFSyncFn = nullptr;
|
||||
sFileInfoFn = nullptr;
|
||||
sFileInfo64Fn = nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue