Merge b-i to m-c

This commit is contained in:
Phil Ringnalda 2014-01-25 19:58:13 -08:00
commit 6253dc2dfe
26 changed files with 179 additions and 72 deletions

View File

@ -865,9 +865,6 @@ pref("media.webspeech.synth.enabled", true);
pref("dom.mozDownloads.enabled", true);
pref("dom.downloads.max_retention_days", 7);
// Downloads API
pref("dom.mozDownloads.enabled", true);
// Inactivity time in milliseconds after which we shut down the OS.File worker.
pref("osfile.reset_worker_delay", 5000);

View File

@ -12,7 +12,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>

View File

@ -11,7 +11,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96d2d00165f4561fbde62d1062706eab74b3a01f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a887bfabaed83c4588b40c845535c0388c8da0f3"/>

View File

@ -12,7 +12,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>

View File

@ -1,4 +1,4 @@
{
"revision": "407993cc2cef77f8c8d0415f11996889ed18dc56",
"revision": "0284cd20f5348574b2bbd224ceacc9fb5e5d33da",
"repo_path": "/integration/gaia-central"
}

View File

@ -11,7 +11,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>

View File

@ -10,7 +10,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>

View File

@ -12,7 +12,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>

View File

@ -11,7 +11,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>

View File

@ -11,7 +11,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96d2d00165f4561fbde62d1062706eab74b3a01f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a887bfabaed83c4588b40c845535c0388c8da0f3"/>

View File

@ -11,7 +11,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f382061fe95750d584a9078175c421a36892afc9"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d342388c8c0a33ef72d0ea57707ec5ce89c10242"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>

View File

@ -56,7 +56,7 @@ IndexedDBHelper.prototype = {
self._db.onversionchange = function(event) {
if (DEBUG) debug("WARNING: DB modified from a different window.");
}
aSuccessCb();
aSuccessCb && aSuccessCb();
};
req.onupgradeneeded = function (aEvent) {
@ -70,7 +70,7 @@ IndexedDBHelper.prototype = {
};
req.onerror = function (aEvent) {
if (DEBUG) debug("Failed to open database: " + self.dbName);
aFailureCb(aEvent.target.error.name);
aFailureCb && aFailureCb(aEvent.target.error.name);
};
req.onblocked = function (aEvent) {
if (DEBUG) debug("Opening database request is blocked.");
@ -88,7 +88,7 @@ IndexedDBHelper.prototype = {
ensureDB: function ensureDB(aSuccessCb, aFailureCb) {
if (this._db) {
if (DEBUG) debug("ensureDB: already have a database, returning early.");
aSuccessCb();
aSuccessCb && aSuccessCb();
return;
}
this.open(aSuccessCb, aFailureCb);

View File

@ -1916,6 +1916,27 @@ Navigator::HasDataStoreSupport(JSContext* cx, JSObject* aGlobal)
return status == nsIPrincipal::APP_STATUS_CERTIFIED;
}
/* static */
bool
Navigator::HasDownloadsSupport(JSContext* aCx, JSObject* aGlobal)
{
// We'll need a rooted object so that GC doesn't make it go away while
// we're calling CheckIsChrome.
JS::Rooted<JSObject*> global(aCx, aGlobal);
// Because of the way this API must be implemented, it will interact with
// objects attached to a chrome window. We always want to allow this.
if (ThreadsafeCheckIsChrome(aCx, global)) {
return true;
}
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(global);
return win &&
CheckPermission(win, "downloads") &&
Preferences::GetBool("dom.mozDownloads.enabled");
}
/* static */
already_AddRefed<nsPIDOMWindow>
Navigator::GetWindowFromGlobal(JSObject* aGlobal)

View File

@ -290,6 +290,8 @@ public:
static bool HasDataStoreSupport(JSContext* cx, JSObject* aGlobal);
static bool HasDownloadsSupport(JSContext* aCx, JSObject* aGlobal);
nsPIDOMWindow* GetParentObject() const
{
return GetWindow();

View File

@ -206,12 +206,12 @@ function DOMDownloadImpl() {
this.currentBytes = 0;
this.url = null;
this.path = null;
this.state = "stopped";
this.contentType = null;
/* fields that require getters/setters */
this._error = null;
this._startTime = new Date();
this._state = "stopped";
/* private fields */
this.id = null;
@ -270,6 +270,25 @@ DOMDownloadImpl.prototype = {
}
},
get state() {
return this._state;
},
// We require a setter here to simplify the internals of the Download Manager
// since we actually pass dummy JSON objects to the child process and update
// them. This is the case for all other setters for read-only attributes
// implemented in this object.
set state(aState) {
// We need to ensure that XPCOM consumers of this API respect the enum
// values as well.
if (["downloading",
"stopped",
"succeeded",
"finalized"].indexOf(aState) != -1) {
this._state = aState;
}
},
_init: function(aWindow, aDownload) {
this._window = aWindow;
this.id = aDownload.id;

View File

@ -9,9 +9,6 @@ function getQuery(request) {
return query;
}
// Timer used to handle the request response.
var timer = null;
function handleResponse() {
// Is this a rate limited response?
if (this.state.rate > 0) {
@ -26,7 +23,24 @@ function handleResponse() {
(bytesToWrite > this.state.rate) ? this.state.rate : bytesToWrite;
for (let i = 0; i < bytesToWrite; i++) {
this.response.write("0");
try {
this.response.bodyOutputStream.write("0", 1);
} catch (e) {
// Connection was closed by client.
if (e == Components.results.NS_ERROR_NOT_AVAILABLE) {
// There's no harm in calling this multiple times.
this.response.finish();
// It's possible that our timer wasn't cancelled in time
// and we'll be called again.
if (this.timer) {
this.timer.cancel();
this.timer = null;
}
return;
}
}
}
// Update the number of bytes we've sent to the client.
@ -47,12 +61,19 @@ function handleResponse() {
this.response.finish();
// All done sending, go ahead and cancel our repeating timer.
timer.cancel();
this.timer.cancel();
// Clear the timer.
this.timer = null;
}
function handleRequest(request, response) {
var query = getQuery(request);
// sending at a specific rate requires our response to be asynchronous so
// we handle all requests asynchronously. See handleResponse().
response.processAsync();
// Default status when responding.
var version = "1.1";
var statusCode = 200;
@ -120,20 +141,17 @@ function handleRequest(request, response) {
totalBytes: size,
sentBytes: 0,
rate: rate
}
},
timer: null
};
// The notify implementation for the timer.
context.notify = handleResponse.bind(context);
timer =
context.timer =
Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
// sending at a specific rate requires our response to be asynchronous so
// we handle all requests asynchronously. See handleResponse().
response.processAsync();
// generate the content.
response.setStatusLine(version, statusCode, description);
response.setHeader("Content-Type", contentType, false);
@ -143,8 +161,10 @@ function handleRequest(request, response) {
response.setHeader("Content-Length", size.toString(), false);
// initialize the timer and start writing out the response.
timer.initWithCallback(context,
1000,
Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
context.timer.initWithCallback(
context,
1000,
Components.interfaces.nsITimer.TYPE_REPEATING_SLACK
);
}

View File

@ -57,6 +57,18 @@ let NotificationDB = {
} catch (e) {
if (DEBUG) { debug("Unable to parse file data " + e); }
}
// populate the list of notifications by tag
if (this.notifications) {
for (var origin in this.notifications) {
this.byTag[origin] = {};
for (var id in this.notifications[origin]) {
var curNotification = this.notifications[origin][id];
if (curNotification.tag) {
this.byTag[origin][curNotification.tag] = curNotification;
}
}
}
}
this.loaded = true;
callback && callback();
}.bind(this),
@ -128,10 +140,20 @@ let NotificationDB = {
receiveMessage: function(message) {
if (DEBUG) { debug("Received message:" + message.name); }
// sendAsyncMessage can fail if the child process exits during a
// notification storage operation, so always wrap it in a try/catch.
function returnMessage(name, data) {
try {
message.target.sendAsyncMessage(name, data);
} catch (e) {
if (DEBUG) { debug("Return message failed, " + name); }
}
}
switch (message.name) {
case "Notification:GetAll":
this.queueTask("getall", message.data, function(notifications) {
message.target.sendAsyncMessage("Notification:GetAll:Return:OK", {
returnMessage("Notification:GetAll:Return:OK", {
requestID: message.data.requestID,
notifications: notifications
});
@ -140,7 +162,7 @@ let NotificationDB = {
case "Notification:Save":
this.queueTask("save", message.data, function() {
message.target.sendAsyncMessage("Notification:Save:Return:OK", {
returnMessage("Notification:Save:Return:OK", {
requestID: message.data.requestID
});
});
@ -148,7 +170,7 @@ let NotificationDB = {
case "Notification:Delete":
this.queueTask("delete", message.data, function() {
message.target.sendAsyncMessage("Notification:Delete:Return:OK", {
returnMessage("Notification:Delete:Return:OK", {
requestID: message.data.requestID
});
});

View File

@ -326,12 +326,6 @@ var interfaceNamesInGlobalScope =
"DOMTokenList",
// IMPORTANT: Do not change this list without review from a DOM peer!
"DOMTransactionEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "DOMDownload", b2g: true, pref: "dom.mozDownloads.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "DOMDownloadManager", b2g: true, pref: "dom.mozDownloads.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "DownloadEvent", b2g: true, pref: "dom.mozDownloads.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"DragEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -5,7 +5,7 @@
*/
[Constructor(DOMString type, optional DownloadEventInit eventInitDict),
Pref="dom.mozDownloads.enabled"]
Func="Navigator::HasDownloadsSupport"]
interface DownloadEvent : Event
{
readonly attribute DOMDownload? download;

View File

@ -4,7 +4,26 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[NavigatorProperty="mozDownloadManager",
// Represents the state of a download.
// "downloading": The resource is actively transfering.
// "stopped" : No network tranfer is happening.
// "succeeded" : The resource has been downloaded successfully.
// "finalized" : We won't try to download this resource, but the DOM
// object is still alive.
enum DownloadState {
"downloading",
"stopped",
"succeeded",
"finalized"
};
//
// XXXTODO: When we have a generic way to do feature detection in marketplace
// we will *STOP* using the pref and use the function like DOMDownload
// and DownloadEvent.
//
[NoInterfaceObject,
NavigatorProperty="mozDownloadManager",
JSImplementation="@mozilla.org/downloads/manager;1",
Pref="dom.mozDownloads.enabled"]
interface DOMDownloadManager : EventTarget {
@ -24,7 +43,7 @@ interface DOMDownloadManager : EventTarget {
};
[JSImplementation="@mozilla.org/downloads/download;1",
Pref="dom.mozDownloads.enabled"]
Func="Navigator::HasDownloadsSupport"]
interface DOMDownload : EventTarget {
// The full size of the resource.
readonly attribute long totalBytes;
@ -39,13 +58,8 @@ interface DOMDownload : EventTarget {
// is complete.
readonly attribute DOMString path;
// The state of the download. Can be any of:
// "downloading": The resource is actively transfering.
// "stopped" : No network tranfer is happening.
// "succeeded" : The resource has been downloaded successfully.
// "finalized" : We won't try to download this resource, but the DOM
// object is still alive.
readonly attribute DOMString state;
// The state of the download.
readonly attribute DownloadState state;
// The mime type for this resource.
readonly attribute DOMString contentType;

View File

@ -305,6 +305,7 @@
"dom/media/tests/mochitest/test_dataChannel_basicAudioVideo.html":"Bug 960442, video support for WebRTC is disabled on b2g",
"dom/media/tests/mochitest/test_dataChannel_basicAudioVideoCombined.html":"Bug 960442, video support for WebRTC is disabled on b2g",
"dom/media/tests/mochitest/test_dataChannel_basicVideo.html":"Bug 960442, video support for WebRTC is disabled on b2g",
"dom/media/tests/mochitest/test_peerConnection_basicAudio.html":"Bug 962984, test fail on b2g debug build",
"dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html":"Bug 960442, video support for WebRTC is disabled on b2g",
"dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html":"Bug 960442, video support for WebRTC is disabled on b2g",
"dom/media/tests/mochitest/test_peerConnection_basicVideo.html":"Bug 960442, video support for WebRTC is disabled on b2g",

View File

@ -110,7 +110,7 @@ class ProcessHandlerMixin(object):
else:
subprocess.Popen.__del__(self)
def kill(self):
def kill(self, sig=None):
self.returncode = 0
if isWin:
if not self._ignore_children and self._handle and self._job:
@ -126,20 +126,18 @@ class ProcessHandlerMixin(object):
self._cleanup()
if err is not None:
raise OSError(err)
else:
pass
else:
sig = sig or signal.SIGKILL
if not self._ignore_children:
try:
os.killpg(self.pid, signal.SIGKILL)
os.killpg(self.pid, sig)
except BaseException, e:
if getattr(e, "errno", None) != 3:
# Error 3 is "no such process", which is ok
print >> sys.stdout, "Could not kill process, could not find pid: %s, assuming it's already dead" % self.pid
else:
os.kill(self.pid, signal.SIGKILL)
if self.returncode is None:
self.returncode = subprocess.Popen._internal_poll(self)
os.kill(self.pid, sig)
self.returncode = -sig
self._cleanup()
return self.returncode
@ -417,7 +415,7 @@ falling back to not using job objects for managing child processes"""
threadalive = self._procmgrthread.is_alive()
else:
threadalive = self._procmgrthread.isAlive()
if self._job and threadalive:
if self._job and threadalive:
# Then we are managing with IO Completion Ports
# wait on a signal so we know when we have seen the last
# process come through.
@ -643,7 +641,7 @@ falling back to not using job objects for managing child processes"""
self.processOutput(timeout=timeout, outputTimeout=outputTimeout)
def kill(self):
def kill(self, sig=None):
"""
Kills the managed process.
@ -654,9 +652,12 @@ falling back to not using job objects for managing child processes"""
Note that this does not manage any state, save any output etc,
it immediately kills the process.
:param sig: Signal used to kill the process, defaults to SIGKILL
(has no effect on Windows)
"""
try:
return self.proc.kill()
return self.proc.kill(sig=sig)
except AttributeError:
# Try to print a relevant error message.
if not self.proc:

View File

@ -23,7 +23,8 @@ class ProcTestKill(proctest.ProcTest):
self.determine_status(detected,
output,
p.proc.returncode,
p.didTimeout)
p.didTimeout,
expectedfail=('returncode',))
def test_process_kill_deep(self):
"""Process is started, we kill it, we use a deep process tree"""
@ -37,7 +38,8 @@ class ProcTestKill(proctest.ProcTest):
self.determine_status(detected,
output,
p.proc.returncode,
p.didTimeout)
p.didTimeout,
expectedfail=('returncode',))
def test_process_kill_deep_wait(self):
"""Process is started, we use a deep process tree, we let it spawn
@ -54,7 +56,8 @@ class ProcTestKill(proctest.ProcTest):
self.determine_status(detected,
output,
p.proc.returncode,
p.didTimeout)
p.didTimeout,
expectedfail=('returncode',))
def test_process_kill_broad(self):
"""Process is started, we kill it, we use a broad process tree"""
@ -68,7 +71,8 @@ class ProcTestKill(proctest.ProcTest):
self.determine_status(detected,
output,
p.proc.returncode,
p.didTimeout)
p.didTimeout,
expectedfail=('returncode',))
if __name__ == '__main__':
unittest.main()

View File

@ -29,7 +29,8 @@ class ProcTestKill(proctest.ProcTest):
self.determine_status(detected,
output,
p.proc.returncode,
p.didTimeout)
p.didTimeout,
expectedfail=('returncode',))
if __name__ == '__main__':
unittest.main()

View File

@ -70,17 +70,25 @@ class Runner(object):
"""
Wait for the process to exit.
Returns the process return code if the process exited,
returns None otherwise.
returns -<signal> if the process was killed (Unix only)
returns None if the process is still running.
If timeout is not None, will return after timeout seconds.
Use is_running() to determine whether or not a timeout occured.
Timeout is ignored if interactive was set to True.
:param timeout: if not None, will return after timeout seconds.
Use is_running() to determine whether or not a
timeout occured. Timeout is ignored if
interactive was set to True.
"""
if self.process_handler is not None:
if isinstance(self.process_handler, subprocess.Popen):
self.returncode = self.process_handler.wait()
else:
self.process_handler.wait(timeout)
if not self.process_handler:
# the process was killed by another thread
return self.returncode
# the process terminated, retrieve the return code
self.returncode = self.process_handler.proc.poll()
if self.returncode is not None:
self.process_handler = None
@ -96,13 +104,16 @@ class Runner(object):
return self.process_handler is not None
def stop(self):
def stop(self, sig=None):
"""
Kill the process
:param sig: Signal used to kill the process, defaults to SIGKILL
(has no effect on Windows).
"""
if self.process_handler is None:
return
self.process_handler.kill()
self.returncode = self.process_handler.kill(sig=sig)
self.process_handler = None
def reset(self):

View File

@ -531,7 +531,7 @@ nsWindow::GetDefaultScaleInternal()
return 1.5; // hdpi devices.
}
// xhdpi devices and beyond.
return floor(dpi / 150.0);
return floor(dpi / 150.0 + 0.5);
}
LayerManager *