Merge inbound to mozilla-central. a=merge

This commit is contained in:
shindli 2019-01-09 23:42:10 +02:00
commit e196689816
43 changed files with 435 additions and 241 deletions

View File

@ -182,8 +182,8 @@
<key id="key_delete" keycode="VK_DELETE" command="cmd_delete"/>
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
<key keycode="VK_BACK" command="cmd_handleBackspace"/>
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift"/>
<key keycode="VK_BACK" command="cmd_handleBackspace" reserved="false"/>
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift" reserved="false"/>
#ifndef XP_MACOSX
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>

View File

@ -117,3 +117,43 @@ if (!navigator.platform.includes("Mac")) {
BrowserTestUtils.removeTab(tab1);
});
}
// There is a <key> element for Backspace with reserved="false", so make sure that it is not
// treated as a blocked shortcut key.
add_task(async function test_backspace() {
await new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve);
});
// The input field is autofocused. If this test fails, backspace can go back
// in history so cancel the beforeunload event and adjust the field to make the test fail.
const uri = "data:text/html,<body onbeforeunload='document.getElementById(\"field\").value = \"failed\";'>" +
"<input id='field' value='something'></body>";
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
await ContentTask.spawn(tab.linkedBrowser, { }, async function() {
content.document.getElementById("field").focus();
// Add a promise that resolves when the backspace key gets received
// so we can ensure the key gets received before checking the result.
content.keysPromise = new Promise(resolve => {
content.addEventListener("keyup", event => {
if (event.code == "Backspace") {
resolve(content.document.getElementById("field").value);
}
});
});
});
// Move the caret so backspace will delete the first character.
EventUtils.synthesizeKey("KEY_ArrowRight", {});
EventUtils.synthesizeKey("KEY_Backspace", {});
let fieldValue = await ContentTask.spawn(tab.linkedBrowser, { }, async function() {
return content.keysPromise;
});
is(fieldValue, "omething", "backspace not prevented");
BrowserTestUtils.removeTab(tab);
});

View File

@ -704,6 +704,7 @@ skip-if = (os == "win" && ccov) # Bug 1424154
[browser_dbg-expressions-error.js]
[browser_dbg-iframes.js]
[browser_dbg-inline-cache.js]
skip-if = ccov && os == 'win' # Bug 1443132
[browser_dbg-inspector-integration.js]
[browser_dbg-keyboard-navigation.js]
[browser_dbg-keyboard-shortcuts.js]

View File

@ -64,7 +64,7 @@ ReverbConvolver::ReverbConvolver(const float* impulseResponseData,
m_accumulationBuffer(impulseResponseLength + WEBAUDIO_BLOCK_SIZE),
m_inputBuffer(InputBufferSize),
m_backgroundThread("ConvolverWorker"),
m_backgroundThreadCondition(&m_backgroundThreadLock),
m_backgroundThreadMonitor("ConvolverMonitor"),
m_useBackgroundThreads(useBackgroundThreads),
m_wantsToExit(false),
m_moreInputBuffered(false) {
@ -166,9 +166,9 @@ ReverbConvolver::~ReverbConvolver() {
// Wake up thread so it can return
{
AutoLock locker(m_backgroundThreadLock);
MonitorAutoLock locker(m_backgroundThreadMonitor);
m_moreInputBuffered = true;
m_backgroundThreadCondition.Signal();
m_backgroundThreadMonitor.Notify();
}
m_backgroundThread.Stop();
@ -199,8 +199,7 @@ size_t ReverbConvolver::sizeOfIncludingThis(
// Possible future measurements:
// - m_backgroundThread
// - m_backgroundThreadLock
// - m_backgroundThreadCondition
// - m_backgroundThreadMonitor
return amount;
}
@ -209,9 +208,9 @@ void ReverbConvolver::backgroundThreadEntry() {
// Wait for realtime thread to give us more input
m_moreInputBuffered = false;
{
AutoLock locker(m_backgroundThreadLock);
MonitorAutoLock locker(m_backgroundThreadMonitor);
while (!m_moreInputBuffered && !m_wantsToExit)
m_backgroundThreadCondition.Wait();
m_backgroundThreadMonitor.Wait();
}
// Process all of the stages until their read indices reach the input
@ -251,17 +250,17 @@ void ReverbConvolver::process(const float* sourceChannelData,
// Now that we've buffered more input, wake up our background thread.
// Not using a MutexLocker looks strange, but we use a tryLock() instead
// Not using a MonitorAutoLock looks strange, but we use a TryLock() instead
// because this is run on the real-time thread where it is a disaster for the
// lock to be contended (causes audio glitching). It's OK if we fail to
// signal from time to time, since we'll get to it the next time we're called.
// We're called repeatedly and frequently (around every 3ms). The background
// thread is processing well into the future and has a considerable amount of
// leeway here...
if (m_backgroundThreadLock.Try()) {
if (m_backgroundThreadMonitor.TryLock()) {
m_moreInputBuffered = true;
m_backgroundThreadCondition.Signal();
m_backgroundThreadLock.Release();
m_backgroundThreadMonitor.Notify();
m_backgroundThreadMonitor.Unlock();
}
}

View File

@ -33,11 +33,10 @@
#include "ReverbInputBuffer.h"
#include "nsAutoPtr.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Monitor.h"
#ifdef LOG
#undef LOG
#endif
#include "base/condition_variable.h"
#include "base/lock.h"
#include "base/thread.h"
namespace WebCore {
@ -80,8 +79,7 @@ class ReverbConvolver {
// Background thread and synchronization
base::Thread m_backgroundThread;
Lock m_backgroundThreadLock;
ConditionVariable m_backgroundThreadCondition;
mozilla::Monitor m_backgroundThreadMonitor;
bool m_useBackgroundThreads;
bool m_wantsToExit;
bool m_moreInputBuffered;

View File

@ -15,12 +15,15 @@ namespace base {
// thread-safe access, since it will only be modified in testing.
static AtExitManager* g_top_manager = NULL;
AtExitManager::AtExitManager() : next_manager_(NULL) {
AtExitManager::AtExitManager() : lock_("AtExitManager"),
next_manager_(NULL) {
DCHECK(!g_top_manager);
g_top_manager = this;
}
AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) {
AtExitManager::AtExitManager(bool shadow) : lock_("AtExitManager"),
next_manager_(g_top_manager)
{
DCHECK(shadow || !g_top_manager);
g_top_manager = this;
}
@ -45,7 +48,7 @@ void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) {
DCHECK(func);
AutoLock lock(g_top_manager->lock_);
mozilla::MutexAutoLock lock(g_top_manager->lock_);
g_top_manager->stack_.push(CallbackAndParam(func, param));
}
@ -56,7 +59,7 @@ void AtExitManager::ProcessCallbacksNow() {
return;
}
AutoLock lock(g_top_manager->lock_);
mozilla::MutexAutoLock lock(g_top_manager->lock_);
while (!g_top_manager->stack_.empty()) {
CallbackAndParam callback_and_param = g_top_manager->stack_.top();

View File

@ -10,7 +10,8 @@
#include <stack>
#include "base/basictypes.h"
#include "base/lock.h"
#include "mozilla/Mutex.h"
namespace base {
@ -63,7 +64,7 @@ class AtExitManager {
void* param_;
};
Lock lock_;
mozilla::Mutex lock_;
std::stack<CallbackAndParam> stack_;
AtExitManager* next_manager_; // Stack of managers to allow shadowing.

View File

@ -26,8 +26,6 @@ namespace base {
#define DVLOG(x) CHROMIUM_LOG(ERROR)
#define CHECK_GT DCHECK_GT
#define CHECK_LT DCHECK_LT
typedef ::Lock Lock;
typedef ::AutoLock AutoLock;
// Static table of checksums for all possible 8 bit bytes.
const uint32_t Histogram::kCrcTable[256] = {

View File

@ -50,7 +50,6 @@
#include <string>
#include "base/time.h"
#include "base/lock.h"
#include "nsTArray.h"

View File

@ -171,6 +171,7 @@ MessageLoop::MessageLoop(Type type, nsIEventTarget* aEventTarget)
id_(++message_loop_id_seq),
nestable_tasks_allowed_(true),
exception_restoration_(false),
incoming_queue_lock_("MessageLoop Incoming Queue Lock"),
state_(NULL),
run_depth_base_(1),
shutting_down_(false),
@ -400,7 +401,7 @@ void MessageLoop::PostTask_Helper(already_AddRefed<nsIRunnable> task,
RefPtr<base::MessagePump> pump;
{
AutoLock locked(incoming_queue_lock_);
mozilla::MutexAutoLock locked(incoming_queue_lock_);
incoming_queue_.push(std::move(pending_task));
pump = pump_;
}
@ -478,7 +479,7 @@ void MessageLoop::ReloadWorkQueue() {
// Acquire all we can from the inter-thread queue with one lock acquisition.
{
AutoLock lock(incoming_queue_lock_);
mozilla::MutexAutoLock lock(incoming_queue_lock_);
if (incoming_queue_.empty()) return;
std::swap(incoming_queue_, work_queue_);
DCHECK(incoming_queue_.empty());

View File

@ -13,10 +13,11 @@
#include <vector>
#include <map>
#include "base/lock.h"
#include "base/message_pump.h"
#include "base/observer_list.h"
#include "mozilla/Mutex.h"
#if defined(OS_WIN)
// We need this to declare base::MessagePumpWin::Dispatcher, which we should
// really just eliminate.
@ -423,7 +424,7 @@ class MessageLoop : public base::MessagePump::Delegate {
// will be handled by the TimerManager.
TaskQueue incoming_queue_;
// Protect access to incoming_queue_.
Lock incoming_queue_lock_;
mozilla::Mutex incoming_queue_lock_;
RunState* state_;
int run_depth_base_;

View File

@ -11,7 +11,6 @@
#include <list>
#include "base/lock.h"
#include "base/message_pump.h"
#include "base/observer_list.h"
#include "base/scoped_handle.h"

View File

@ -44,9 +44,9 @@
#include <mmsystem.h>
#include "base/basictypes.h"
#include "base/lock.h"
#include "base/logging.h"
#include "mozilla/Casting.h"
#include "mozilla/StaticMutex.h"
using base::Time;
using base::TimeDelta;
@ -216,10 +216,8 @@ DWORD (*tick_function)(void) = &timeGetTimeWrapper;
// 49 days.
class NowSingleton {
public:
NowSingleton() : rollover_(TimeDelta::FromMilliseconds(0)), last_seen_(0) {}
TimeDelta Now() {
AutoLock locked(lock_);
mozilla::StaticMutexAutoLock locked(lock_);
// We should hold the lock while calling tick_function to make sure that
// we keep our last_seen_ stay correctly in sync.
DWORD now = tick_function();
@ -231,12 +229,28 @@ class NowSingleton {
}
static NowSingleton& instance() {
static NowSingleton now;
// This setup is a little gross: the `now` instance lives until libxul is
// unloaded, but leak checking runs prior to that, and would see a Mutex
// instance contained in NowSingleton as still live. Said instance would
// be reported as a leak...but it's not, really. To avoid that, we need
// to use StaticMutex (which is not leak-checked), but StaticMutex can't
// be a member variable. So we have to have this separate variable and
// pass it into the NowSingleton constructor.
static mozilla::StaticMutex mutex;
static NowSingleton now(mutex);
return now;
}
private:
Lock lock_; // To protected last_seen_ and rollover_.
explicit NowSingleton(mozilla::StaticMutex& aMutex)
: lock_(aMutex)
, rollover_(TimeDelta::FromMilliseconds(0))
, last_seen_(0)
{
}
~NowSingleton() = default;
mozilla::StaticMutex& lock_; // To protected last_seen_ and rollover_.
TimeDelta rollover_; // Accumulation of time lost due to rollover.
DWORD last_seen_; // The last timeGetTime value we saw, to detect rollover.

View File

@ -25,7 +25,6 @@
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/lock.h"
#include "base/logging.h"
#include "base/process_util.h"
#include "base/string_util.h"
@ -33,6 +32,7 @@
#include "chrome/common/file_descriptor_set_posix.h"
#include "chrome/common/ipc_message_utils.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/UniquePtr.h"
#ifdef FUZZING
@ -108,7 +108,7 @@ class PipeMap {
public:
// Lookup a given channel id. Return -1 if not found.
int Lookup(const std::string& channel_id) {
AutoLock locked(lock_);
mozilla::StaticMutexAutoLock locked(lock_);
ChannelToFDMap::const_iterator i = map_.find(channel_id);
if (i == map_.end()) return -1;
@ -118,7 +118,7 @@ class PipeMap {
// Remove the mapping for the given channel id. No error is signaled if the
// channel_id doesn't exist
void Remove(const std::string& channel_id) {
AutoLock locked(lock_);
mozilla::StaticMutexAutoLock locked(lock_);
ChannelToFDMap::iterator i = map_.find(channel_id);
if (i != map_.end()) map_.erase(i);
@ -127,7 +127,7 @@ class PipeMap {
// Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
// mapping if one already exists for the given channel_id
void Insert(const std::string& channel_id, int fd) {
AutoLock locked(lock_);
mozilla::StaticMutexAutoLock locked(lock_);
DCHECK(fd != -1);
ChannelToFDMap::const_iterator i = map_.find(channel_id);
@ -137,15 +137,25 @@ class PipeMap {
}
static PipeMap& instance() {
static PipeMap map;
// This setup is a little gross: the `map` instance lives until libxul is
// unloaded, but leak checking runs prior to that, and would see a Mutex
// instance contained in PipeMap as still live. Said instance would be
// reported as a leak...but it's not, really. To avoid that, we need to
// use StaticMutex (which is not leak-checked), but StaticMutex can't be
// a member variable. So we have to have this separate variable and pass
// it into the PipeMap constructor.
static mozilla::StaticMutex mutex;
static PipeMap map(mutex);
return map;
}
private:
PipeMap() = default;
explicit PipeMap(mozilla::StaticMutex& aMutex)
: lock_(aMutex)
{}
~PipeMap() = default;
Lock lock_;
mozilla::StaticMutex& lock_;
typedef std::map<std::string, int> ChannelToFDMap;
ChannelToFDMap map_;
};

View File

@ -106,11 +106,9 @@ struct JSPropertySpec {
private:
void checkAccessorsAreNative() const {
MOZ_ASSERT(accessors.getter.native.op);
// We may not have a setter at all. So all we can assert here, for the
// native case is that if we have a jitinfo for the setter then we have
// a setter op too. This is good enough to make sure we don't have a
// SelfHostedWrapper for the setter.
// We may have a getter or a setter or both. And whichever ones we have
// should not have a SelfHostedWrapper for the accessor.
MOZ_ASSERT_IF(accessors.getter.native.info, accessors.getter.native.op);
MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
}

View File

@ -111,6 +111,10 @@ class FakeSocketTransportProvider : public nsISocketTransport {
MOZ_ASSERT(false);
return NS_OK;
}
NS_IMETHOD SetLinger(bool aPolarity, int16_t aTimeout) override {
MOZ_ASSERT(false);
return NS_OK;
}
NS_IMETHOD SetReuseAddrPort(bool reuseAddrPort) override {
MOZ_ASSERT(false);
return NS_OK;

View File

@ -11,6 +11,7 @@
#include <vector>
#include "CSFLog.h"
#include "base/histogram.h"
#include "timecard.h"
#include "jsapi.h"

View File

@ -42,7 +42,9 @@ DeviceInfoIos::DeviceInfoIos() {
this->Init();
}
DeviceInfoIos::~DeviceInfoIos() {}
DeviceInfoIos::~DeviceInfoIos() {
[_captureInfo registerOwner:nil];
}
int32_t DeviceInfoIos::Init() {
_captureInfo = [[DeviceInfoIosObjC alloc] init];

View File

@ -127,8 +127,9 @@ inline void mozilla::detail::MutexImpl::mutexLock() {
"mozilla::detail::MutexImpl::mutexLock: pthread_mutex_lock failed");
}
#ifdef XP_DARWIN
inline bool mozilla::detail::MutexImpl::mutexTryLock() {
bool mozilla::detail::MutexImpl::tryLock() { return mutexTryLock(); }
bool mozilla::detail::MutexImpl::mutexTryLock() {
int result = pthread_mutex_trylock(&platformData()->ptMutex);
if (result == 0) {
return true;
@ -142,7 +143,6 @@ inline bool mozilla::detail::MutexImpl::mutexTryLock() {
result,
"mozilla::detail::MutexImpl::mutexTryLock: pthread_mutex_trylock failed");
}
#endif
void mozilla::detail::MutexImpl::lock() {
#ifndef XP_DARWIN

View File

@ -22,6 +22,12 @@ void mozilla::detail::MutexImpl::lock() {
AcquireSRWLockExclusive(&platformData()->lock);
}
bool mozilla::detail::MutexImpl::tryLock() { return mutexTryLock(); }
bool mozilla::detail::MutexImpl::mutexTryLock() {
return !!TryAcquireSRWLockExclusive(&platformData()->lock);
}
void mozilla::detail::MutexImpl::unlock() {
ReleaseSRWLockExclusive(&platformData()->lock);
}

View File

@ -33,6 +33,9 @@ class MutexImpl {
protected:
MFBT_API void lock();
MFBT_API void unlock();
// We have a separate, forwarding API so internal uses don't have to go
// through the PLT.
MFBT_API bool tryLock();
private:
MutexImpl(const MutexImpl&) = delete;
@ -42,9 +45,7 @@ class MutexImpl {
bool operator==(const MutexImpl& rhs) = delete;
void mutexLock();
#ifdef XP_DARWIN
bool mutexTryLock();
#endif
PlatformData* platformData();

View File

@ -124,6 +124,13 @@ interface nsISocketTransport : nsITransport
unsigned long getTimeout(in unsigned long aType);
void setTimeout(in unsigned long aType, in unsigned long aValue);
/**
* Sets the SO_LINGER option with the specified values for the l_onoff and
* l_linger parameters. This applies PR_SockOpt_Linger before PR_Close and
* can be used with a timeout of zero to send an RST packet when closing.
*/
void setLinger(in boolean aPolarity, in short aTimeout);
/**
* True to set addr and port reuse socket options.
*/

View File

@ -717,6 +717,8 @@ nsSocketTransport::nsSocketTransport()
mSocketTransportService(gSocketTransportService),
mInput(this),
mOutput(this),
mLingerPolarity(false),
mLingerTimeout(0),
mQoSBits(0x00),
mKeepaliveEnabled(false),
mKeepaliveIdleTimeS(-1),
@ -1978,7 +1980,8 @@ class ThunkPRClose : public Runnable {
PRFileDesc *mFD;
};
void STS_PRCloseOnSocketTransport(PRFileDesc *fd) {
void STS_PRCloseOnSocketTransport(PRFileDesc *fd, bool lingerPolarity,
int16_t lingerTimeout) {
if (gSocketTransportService) {
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
gSocketTransportService->Dispatch(new ThunkPRClose(fd), NS_DISPATCH_NORMAL);
@ -1999,13 +2002,22 @@ void nsSocketTransport::ReleaseFD_Locked(PRFileDesc *fd) {
gSocketTransportService->MaxTimeForPrClosePref())) {
// If shutdown last to long, let the socket leak and do not close it.
SOCKET_LOG(("Intentional leak"));
} else if (OnSocketThread()) {
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
CloseSocket(
mFD, mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
} else {
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
STS_PRCloseOnSocketTransport(mFD);
if (mLingerPolarity || mLingerTimeout) {
PRSocketOptionData socket_linger;
socket_linger.option = PR_SockOpt_Linger;
socket_linger.value.linger.polarity = mLingerPolarity;
socket_linger.value.linger.linger = mLingerTimeout;
PR_SetSocketOption(mFD, &socket_linger);
}
if (OnSocketThread()) {
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
CloseSocket(
mFD, mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
} else {
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
STS_PRCloseOnSocketTransport(mFD, mLingerPolarity, mLingerTimeout);
}
}
mFD = nullptr;
}
@ -2756,6 +2768,16 @@ nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort) {
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::SetLinger(bool aPolarity, int16_t aTimeout) {
MutexAutoLock lock(mLock);
mLingerPolarity = aPolarity;
mLingerTimeout = aTimeout;
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::SetQoSBits(uint8_t aQoSBits) {
// Don't do any checking here of bits. Why? Because as of RFC-4594

View File

@ -398,6 +398,10 @@ class nsSocketTransport final : public nsASocketHandler,
// socket timeouts are not protected by any lock.
uint16_t mTimeouts[2];
// linger options to use when closing
bool mLingerPolarity;
int16_t mLingerTimeout;
// QoS setting for socket
uint8_t mQoSBits;

View File

@ -596,7 +596,6 @@ size_t CacheIOThread::SizeOfExcludingThis(
MonitorAutoLock lock(const_cast<CacheIOThread*>(this)->mMonitor);
size_t n = 0;
n += mallocSizeOf(mThread);
for (const auto& event : mEventQueue) {
n += event.ShallowSizeOfExcludingThis(mallocSizeOf);
// Events referenced by the queues are arbitrary objects we cannot be sure

View File

@ -1889,6 +1889,11 @@ SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort) {
return mWrapped->SetReuseAddrPort(aReuseAddrPort);
}
NS_IMETHODIMP
SocketTransportShim::SetLinger(bool aPolarity, int16_t aTimeout) {
return mWrapped->SetLinger(aPolarity, aTimeout);
}
NS_IMETHODIMP
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits) {
return mWrapped->GetQoSBits(aQoSBits);

View File

@ -398,7 +398,7 @@ nsHttpServer.prototype =
try {
var conn = new Connection(input, output, this, socket.port, trans.port,
connectionNumber);
connectionNumber, trans);
var reader = new RequestReader(conn);
// XXX add request timeout functionality here!
@ -1067,7 +1067,8 @@ ServerIdentity.prototype =
* @param number : uint
* a serial number used to uniquely identify this connection
*/
function Connection(input, output, server, port, outgoingPort, number) {
function Connection(input, output, server, port, outgoingPort, number,
transport) {
dumpn("*** opening new connection " + number + " on port " + outgoingPort);
/** Stream of incoming data. */
@ -1088,6 +1089,9 @@ function Connection(input, output, server, port, outgoingPort, number) {
/** The serial number of this connection. */
this.number = number;
/** Reference to the underlying transport. */
this.transport = transport;
/**
* The request for which a response is being generated, null if the
* incoming request has not been fully received or if it had errors.
@ -3559,10 +3563,19 @@ Response.prototype =
* @param e : Error
* the exception which precipitated this abort, or null if no such exception
* was generated
* @param truncateConnection : Boolean
* ensures that we truncate the connection using an RST packet, so the
* client testing code is aware that an error occurred, otherwise it may
* consider the response as valid.
*/
abort(e) {
abort(e, truncateConnection = false) {
dumpn("*** abort(<" + e + ">)");
if (truncateConnection) {
dumpn("*** truncate connection");
this._connection.transport.setLinger(true, 0);
}
// This response will be ended by the processor if one was created.
var copier = this._asyncCopier;
if (copier) {

View File

@ -2212,12 +2212,17 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
# Find a D3D compiler DLL in a Windows SDK.
MOZ_D3DCOMPILER_VISTA_DLL=
case "$MOZ_WINSDK_MAXVER" in
0x0603*|0x0A00*)
if test "$OS_ARCH" != "$HOST_OS_ARCH"; then
MOZ_D3DCOMPILER_VISTA_DLL=d3dcompiler_47.dll
AC_MSG_RESULT([Found D3D compiler in Windows SDK.])
;;
esac
AC_MSG_RESULT([Assuming D3D compiler will be in fxc2.])
else
case "$MOZ_WINSDK_MAXVER" in
0x0603*|0x0A00*)
MOZ_D3DCOMPILER_VISTA_DLL=d3dcompiler_47.dll
AC_MSG_RESULT([Found D3D compiler in Windows SDK.])
;;
esac
fi
if test -n "$MOZ_D3DCOMPILER_VISTA_DLL"; then
# We have a name, now track down the path.
@ -2235,13 +2240,20 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
MOZ_D3DCOMPILER_VISTA_DLL_PATH=
fi
else
AC_MSG_RESULT([Windows SDK not found.])
MOZ_D3DCOMPILER_VISTA_DLL_PATH="$(dirname $FXC)/$MOZ_D3DCOMPILER_VISTA_DLL"
if test -f "$MOZ_D3DCOMPILER_VISTA_DLL_PATH"; then
AC_MSG_RESULT([Found MOZ_D3DCOMPILER_VISTA_DLL_PATH: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
else
AC_MSG_RESULT([MOZ_D3DCOMPILER_VISTA_DLL_PATH doesn't exist: $MOZ_D3DCOMPILER_VISTA_DLL_PATH])
AC_MSG_ERROR([fxc2 or "$MOZ_D3DCOMPILER_VISTA_DLL" seem to be missing from the expected location.])
MOZ_D3DCOMPILER_VISTA_DLL_PATH=
fi
fi
else
if test "$OS_ARCH" = "$HOST_OS_ARCH"; then
AC_MSG_ERROR([Couldn't find Windows SDK 8.1 or higher needed for ANGLE.])
else
AC_MSG_RESULT([Windows SDK not needed for ANGLE in Linux MinGW build.])
AC_MSG_ERROR([We should need "$MOZ_D3DCOMPILER_VISTA_DLL" for ANGLE in Linux MinGW build, but we didn't look for it.])
fi
fi
@ -2263,10 +2275,8 @@ if test -n "$MOZ_ANGLE_RENDERER"; then
AC_MSG_RESULT([Found d3dcompiler DLL for Vista+: $MOZ_D3DCOMPILER_VISTA_DLL])
fi
if test -z "$CROSS_COMPILE"; then
if test -z "MOZ_FOUND_A_D3D_COMPILER"; then
AC_MSG_ERROR([Couldn't find an acceptable D3D compiler DLL.])
fi
if test -z "MOZ_FOUND_A_D3D_COMPILER"; then
AC_MSG_ERROR([Couldn't find an acceptable D3D compiler DLL.])
fi
fi # MOZ_ANGLE_RENDERER

View File

@ -72,14 +72,12 @@ capture.element = function(node, highlights = []) {
* The canvas element where the viewport has been painted on.
*/
capture.viewport = function(win, highlights = []) {
let rootNode = win.document.documentElement;
return capture.canvas(
win,
win.pageXOffset,
win.pageYOffset,
rootNode.clientWidth,
rootNode.clientHeight,
win.innerWidth,
win.innerHeight,
{highlights});
};

View File

@ -67,10 +67,7 @@ class ScreenCaptureTestCase(MarionetteTestCase):
@property
def viewport_dimensions(self):
return self.marionette.execute_script("""
return [arguments[0].clientWidth,
arguments[0].clientHeight];
""", script_args=[self.document_element])
return self.marionette.execute_script("return [window.innerWidth, window.innerHeight];")
def assert_png(self, screenshot):
"""Test that screenshot is a Base64 encoded PNG file."""

View File

@ -1,6 +1,2 @@
def document_dimensions(session):
return tuple(session.execute_script("""
let devicePixelRatio = window.devicePixelRatio;
let rect = document.documentElement.getBoundingClientRect();
return [Math.floor(rect.width * devicePixelRatio), Math.floor(rect.height * devicePixelRatio)];
"""))
return tuple(session.execute_script("return [window.innerWidth, window.innerHeight];"))

View File

@ -1451,6 +1451,51 @@ add_task(async function test_error_source_partial() {
Assert.equal(download.target.size, 0);
});
/**
* Ensures a download error is reported when an RST packet is received.
*/
add_task(async function test_error_source_netreset() {
if (AppConstants.platform == "win") {
return;
}
let download;
try {
if (!gUseLegacySaver) {
// When testing DownloadCopySaver, we want to check that the promise
// returned by the "start" method is rejected.
download = await promiseNewDownload(httpUrl("netreset.txt"));
Assert.ok(download.error === null);
await download.start();
} else {
// When testing DownloadLegacySaver, we cannot be sure whether we are
// testing the promise returned by the "start" method or we are testing
// the "error" property checked by promiseDownloadStopped. This happens
// because we don't have control over when the download is started.
download = await promiseStartLegacyDownload(httpUrl("netreset.txt"));
await promiseDownloadStopped(download);
}
do_throw("The download should have failed.");
} catch (ex) {
if (!(ex instanceof Downloads.Error) || !ex.becauseSourceFailed) {
throw ex;
}
// A specific error object is thrown when reading from the source fails.
}
// Check the properties now that the download stopped.
Assert.ok(download.stopped);
Assert.ok(!download.canceled);
Assert.ok(download.error !== null);
Assert.ok(download.error.becauseSourceFailed);
Assert.ok(!download.error.becauseTargetFailed);
Assert.equal(download.error.result, Cr.NS_ERROR_NET_RESET);
Assert.equal(false, await OS.File.exists(download.target.path));
});
/**
* Ensures download error details are reported on local writing failures.
*/

View File

@ -11,6 +11,7 @@
// Globals
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/Integration.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
@ -718,6 +719,20 @@ add_task(function test_common_initialize() {
"Blocked by Windows Parental Controls");
});
// This URL sends some data followed by an RST packet
gHttpServer.registerPathHandler("/netreset.txt",
function(aRequest, aResponse) {
info("Starting response that will be aborted.");
aResponse.processAsync();
aResponse.setHeader("Content-Type", "text/plain", false);
aResponse.write(TEST_DATA_SHORT);
promiseExecuteSoon().then(() => {
aResponse.abort(null, true);
aResponse.finish();
info("Aborting response with network reset.");
}).then(null, Cu.reportError);
});
// During unit tests, most of the functions that require profile access or
// operating system features will be disabled. Individual tests may override
// them again to check for specific behaviors.

View File

@ -5,8 +5,6 @@
* Tests for the "DownloadPaths.jsm" JavaScript module.
*/
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
function testSanitize(leafName, expectedLeafName) {
Assert.equal(DownloadPaths.sanitize(leafName), expectedLeafName);
}

View File

@ -23,6 +23,133 @@
<field name="scrollBox" readonly="true">
document.getAnonymousElementByAttribute(this, "class", "popup-internal-box");
</field>
<field name="AUTOSCROLL_INTERVAL">25</field>
<field name="NOT_DRAGGING">0</field>
<field name="DRAG_OVER_BUTTON">-1</field>
<field name="DRAG_OVER_POPUP">1</field>
<field name="_draggingState">this.NOT_DRAGGING</field>
<field name="_scrollTimer">0</field>
<method name="_enableDragScrolling">
<!-- when overItem is true, drag started over menuitem; when false, drag
started while the popup was opening.
-->
<parameter name="overItem"/>
<body>
<![CDATA[
if (!this._draggingState) {
this.setCaptureAlways();
this._draggingState = overItem ? this.DRAG_OVER_POPUP : this.DRAG_OVER_BUTTON;
}
]]>
</body>
</method>
<method name="_clearScrollTimer">
<body>
<![CDATA[
if (this._scrollTimer) {
this.ownerGlobal.clearInterval(this._scrollTimer);
this._scrollTimer = 0;
}
]]>
</body>
</method>
<constructor><![CDATA[
// Enable the drag-to-scroll events only in menulist popups.
if (!this.parentNode || this.parentNode.localName != "menulist") {
return;
}
// XBL bindings might be constructed more than once.
if (this.eventListenersAdded) {
return;
}
this.eventListenersAdded = true;
this.addEventListener("popupshown", () => {
// Enable drag scrolling even when the mouse wasn't used. The
// mousemove handler will remove it if the mouse isn't down.
this._enableDragScrolling(false);
});
this.addEventListener("popuphidden", () => {
this._draggingState = this.NOT_DRAGGING;
this._clearScrollTimer();
this.releaseCapture();
});
this.addEventListener("mousedown", event => {
if (event.button != 0) {
return;
}
if (this.state == "open" &&
(event.target.localName == "menuitem" ||
event.target.localName == "menu" ||
event.target.localName == "menucaption")) {
this._enableDragScrolling(true);
}
});
this.addEventListener("mouseup", event => {
if (event.button != 0) {
return;
}
this._draggingState = this.NOT_DRAGGING;
this._clearScrollTimer();
});
this.addEventListener("mousemove", event => {
if (!this._draggingState) {
return;
}
this._clearScrollTimer();
// If the user released the mouse before the popup opens, we will
// still be capturing, so check that the button is still pressed. If
// not, release the capture and do nothing else. This also handles if
// the dropdown was opened via the keyboard.
if (!(event.buttons & 1)) {
this._draggingState = this.NOT_DRAGGING;
this.releaseCapture();
return;
}
// If dragging outside the top or bottom edge of the popup, but within
// the popup area horizontally, scroll the list in that direction. The
// _draggingState flag is used to ensure that scrolling does not start
// until the mouse has moved over the popup first, preventing
// scrolling while over the dropdown button.
let popupRect = this.getOuterScreenRect();
if (event.screenX >= popupRect.left &&
event.screenX <= popupRect.right) {
if (this._draggingState == this.DRAG_OVER_BUTTON) {
if (event.screenY > popupRect.top &&
event.screenY < popupRect.bottom) {
this._draggingState = this.DRAG_OVER_POPUP;
}
}
if (this._draggingState == this.DRAG_OVER_POPUP &&
(event.screenY <= popupRect.top ||
event.screenY >= popupRect.bottom)) {
let scrollAmount = event.screenY <= popupRect.top ? -1 : 1;
this.scrollBox.scrollByIndex(scrollAmount, true);
let win = this.ownerGlobal;
this._scrollTimer = win.setInterval(() => {
this.scrollBox.scrollByIndex(scrollAmount, true);
}, this.AUTOSCROLL_INTERVAL);
}
}
});
]]></constructor>
</implementation>
<handlers>
@ -262,124 +389,4 @@
</handler>
</handlers>
</binding>
<binding id="popup-scrollbars" extends="chrome://global/content/bindings/popup.xml#popup">
<content>
<xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical"
smoothscroll="false">
<children/>
</xul:arrowscrollbox>
</content>
<implementation>
<field name="AUTOSCROLL_INTERVAL">25</field>
<field name="NOT_DRAGGING">0</field>
<field name="DRAG_OVER_BUTTON">-1</field>
<field name="DRAG_OVER_POPUP">1</field>
<field name="_draggingState">this.NOT_DRAGGING</field>
<field name="_scrollTimer">0</field>
<method name="enableDragScrolling">
<!-- when overItem is true, drag started over menuitem; when false, drag
started while the popup was opening.
-->
<parameter name="overItem"/>
<body>
<![CDATA[
if (!this._draggingState) {
this.setCaptureAlways();
this._draggingState = overItem ? this.DRAG_OVER_POPUP : this.DRAG_OVER_BUTTON;
}
]]>
</body>
</method>
<method name="_clearScrollTimer">
<body>
<![CDATA[
if (this._scrollTimer) {
this.ownerGlobal.clearInterval(this._scrollTimer);
this._scrollTimer = 0;
}
]]>
</body>
</method>
</implementation>
<handlers>
<handler event="popupshown">
// Enable drag scrolling even when the mouse wasn't used. The mousemove
// handler will remove it if the mouse isn't down.
this.enableDragScrolling(false);
</handler>
<handler event="popuphidden">
<![CDATA[
this._draggingState = this.NOT_DRAGGING;
this._clearScrollTimer();
this.releaseCapture();
]]>
</handler>
<handler event="mousedown" button="0">
<![CDATA[
if (this.state == "open" &&
(event.target.localName == "menuitem" ||
event.target.localName == "menu" ||
event.target.localName == "menucaption")) {
this.enableDragScrolling(true);
}
]]>
</handler>
<handler event="mouseup" button="0">
<![CDATA[
this._draggingState = this.NOT_DRAGGING;
this._clearScrollTimer();
]]>
</handler>
<handler event="mousemove">
<![CDATA[
if (!this._draggingState) {
return;
}
this._clearScrollTimer();
// If the user released the mouse before the popup opens, we will
// still be capturing, so check that the button is still pressed. If
// not, release the capture and do nothing else. This also handles if
// the dropdown was opened via the keyboard.
if (!(event.buttons & 1)) {
this._draggingState = this.NOT_DRAGGING;
this.releaseCapture();
return;
}
// If dragging outside the top or bottom edge of the popup, but within
// the popup area horizontally, scroll the list in that direction. The
// _draggingState flag is used to ensure that scrolling does not start
// until the mouse has moved over the popup first, preventing scrolling
// while over the dropdown button.
let popupRect = this.getOuterScreenRect();
if (event.screenX >= popupRect.left && event.screenX <= popupRect.right) {
if (this._draggingState == this.DRAG_OVER_BUTTON) {
if (event.screenY > popupRect.top && event.screenY < popupRect.bottom) {
this._draggingState = this.DRAG_OVER_POPUP;
}
}
if (this._draggingState == this.DRAG_OVER_POPUP &&
(event.screenY <= popupRect.top || event.screenY >= popupRect.bottom)) {
let scrollAmount = event.screenY <= popupRect.top ? -1 : 1;
this.scrollBox.scrollByIndex(scrollAmount, true);
let win = this.ownerGlobal;
this._scrollTimer = win.setInterval(() => {
this.scrollBox.scrollByIndex(scrollAmount, true);
}, this.AUTOSCROLL_INTERVAL);
}
}
]]>
</handler>
</handlers>
</binding>
</bindings>

View File

@ -1293,6 +1293,7 @@ set_config('MOZ_LAYOUT_DEBUGGER', depends_if('--enable-layout-debugger')(lambda
with only_when(compile_environment):
fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
(lambda t: t.kernel == 'WINNT'))
add_old_configure_assignment('FXC', fxc)
wine = check_prog('WINE', ['wine'], when=depends(target, host)
(lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))

View File

@ -28,12 +28,12 @@ interface nsIUpdatePatch : nsISupports
* "complete" A complete patch containing all of the replacement files
* to update to the new version
*/
attribute AString type;
readonly attribute AString type;
/**
* The URL this patch was being downloaded from
*/
attribute AString URL;
readonly attribute AString URL;
/**
* The final URL this patch was being downloaded from
@ -43,7 +43,7 @@ interface nsIUpdatePatch : nsISupports
/**
* The size of this file, in bytes.
*/
attribute unsigned long size;
readonly attribute unsigned long size;
/**
* The state of this patch
@ -92,28 +92,28 @@ interface nsIUpdate : nsISupports
* "major" A major new version of the Application
* "minor" A minor update to the Application (e.g. security update)
*/
attribute AString type;
readonly attribute AString type;
/**
* The name of the update, or "<Application Name> <Update Version>"
*/
attribute AString name;
readonly attribute AString name;
/**
* The string to display in the user interface for the version. If you want
* a real version number use appVersion.
*/
attribute AString displayVersion;
readonly attribute AString displayVersion;
/**
* The Application version of this update.
*/
attribute AString appVersion;
readonly attribute AString appVersion;
/**
* The Application version prior to the application being updated.
*/
attribute AString previousAppVersion;
readonly attribute AString previousAppVersion;
/**
* The Build ID of this update. Used to determine a particular build, down
@ -121,7 +121,7 @@ interface nsIUpdate : nsISupports
* to differentiate between several nightly builds with the same |version|
* for example.
*/
attribute AString buildID;
readonly attribute AString buildID;
/**
* The URL to a page which offers details about the content of this
@ -129,22 +129,22 @@ interface nsIUpdate : nsISupports
* that summarizes the differences between this update and the previous,
* which also links to the release notes.
*/
attribute AString detailsURL;
readonly attribute AString detailsURL;
/**
* The URL to the Update Service that supplied this update.
*/
attribute AString serviceURL;
readonly attribute AString serviceURL;
/**
* The channel used to retrieve this update from the Update Service.
*/
attribute AString channel;
readonly attribute AString channel;
/**
* Whether the update is no longer supported on this system.
*/
attribute boolean unsupported;
readonly attribute boolean unsupported;
/**
* Allows overriding the default amount of time in seconds before prompting the

View File

@ -17,10 +17,6 @@
/* ::::: XBL bindings ::::: */
menulist > menupopup {
-moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
}
@media (-moz-menubar-drag) {
toolbar[type="menubar"] {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");

View File

@ -11,12 +11,6 @@
%include ../../shared/global.inc.css
/* ::::: XBL bindings ::::: */
menulist > menupopup {
-moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
}
/* ::::: Variables ::::: */
:root {
--arrowpanel-padding: 16px;

View File

@ -15,12 +15,6 @@
%include ../../shared/global.inc.css
/* ::::: XBL bindings ::::: */
menulist > menupopup {
-moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
}
/* ::::: Variables ::::: */
:root {
--arrowpanel-padding: 10px;

View File

@ -349,6 +349,16 @@ void OffTheBooksMutex::Lock() {
Acquire();
}
bool OffTheBooksMutex::TryLock() {
CheckAcquire();
bool locked = this->tryLock();
if (locked) {
mOwningThread = PR_GetCurrentThread();
Acquire();
}
return locked;
}
void OffTheBooksMutex::Unlock() {
Release();
mOwningThread = nullptr;

View File

@ -30,6 +30,7 @@ class Monitor {
~Monitor() {}
void Lock() { mMutex.Lock(); }
bool TryLock() { return mMutex.TryLock(); }
void Unlock() { mMutex.Unlock(); }
void Wait() { mCondVar.Wait(); }

View File

@ -65,6 +65,11 @@ class OffTheBooksMutex : public detail::MutexImpl, BlockingResourceBase {
**/
void Lock() { this->lock(); }
/**
* Try to lock this mutex, returning true if we were successful.
**/
bool TryLock() { return this->tryLock(); }
/**
* Unlock this mutex.
**/
@ -89,6 +94,7 @@ class OffTheBooksMutex : public detail::MutexImpl, BlockingResourceBase {
#else
void Lock();
bool TryLock();
void Unlock();
void AssertCurrentThreadOwns() const;