123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "Hal.h"
- #include "HalLog.h"
- #include <unistd.h>
- #include <sys/reboot.h>
- #include "nsIObserverService.h"
- #include "mozilla/Services.h"
- #include "MainThreadUtils.h"
- namespace mozilla {
- namespace hal_impl {
- void
- Reboot()
- {
- if (NS_IsMainThread()) {
- nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
- if (obsServ) {
- obsServ->NotifyObservers(nullptr, "system-reboot", nullptr);
- }
- }
- sync();
- reboot(RB_AUTOBOOT);
- }
- void
- PowerOff()
- {
- if (NS_IsMainThread()) {
- nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
- if (obsServ) {
- obsServ->NotifyObservers(nullptr, "system-power-off", nullptr);
- }
- }
- sync();
- reboot(RB_POWER_OFF);
- }
- // Structure to specify how watchdog pthread is going to work.
- typedef struct watchdogParam
- {
- hal::ShutdownMode mode; // Specify how to shutdown the system.
- int32_t timeoutSecs; // Specify the delayed seconds to shutdown the system.
- watchdogParam(hal::ShutdownMode aMode, int32_t aTimeoutSecs)
- : mode(aMode), timeoutSecs(aTimeoutSecs) {}
- } watchdogParam_t;
- // Function to complusively shut down the system with a given mode.
- static void
- QuitHard(hal::ShutdownMode aMode)
- {
- switch (aMode)
- {
- case hal::eHalShutdownMode_PowerOff:
- PowerOff();
- break;
- case hal::eHalShutdownMode_Reboot:
- Reboot();
- break;
- case hal::eHalShutdownMode_Restart:
- // Don't let signal handlers affect forced shutdown.
- kill(0, SIGKILL);
- // If we can't SIGKILL our process group, something is badly
- // wrong. Trying to deliver a catch-able signal to ourselves can
- // invoke signal handlers and might cause problems. So try
- // _exit() and hope we go away.
- _exit(1);
- break;
- default:
- MOZ_CRASH();
- }
- }
- // Function to complusively shut down the system with a given mode when timeout.
- static void*
- ForceQuitWatchdog(void* aParamPtr)
- {
- watchdogParam_t* paramPtr = reinterpret_cast<watchdogParam_t*>(aParamPtr);
- if (paramPtr->timeoutSecs > 0 && paramPtr->timeoutSecs <= 30) {
- // If we shut down normally before the timeout, this thread will
- // be harmlessly reaped by the OS.
- TimeStamp deadline =
- (TimeStamp::Now() + TimeDuration::FromSeconds(paramPtr->timeoutSecs));
- while (true) {
- TimeDuration remaining = (deadline - TimeStamp::Now());
- int sleepSeconds = int(remaining.ToSeconds());
- if (sleepSeconds <= 0) {
- break;
- }
- sleep(sleepSeconds);
- }
- }
- hal::ShutdownMode mode = paramPtr->mode;
- delete paramPtr;
- QuitHard(mode);
- return nullptr;
- }
- void
- StartForceQuitWatchdog(hal::ShutdownMode aMode, int32_t aTimeoutSecs)
- {
- // Force-quits are intepreted a little more ferociously on Gonk,
- // because while Gecko is in the process of shutting down, the user
- // can't call 911, for example. And if we hang on shutdown, bad
- // things happen. So, make sure that doesn't happen.
- if (aTimeoutSecs <= 0) {
- return;
- }
- // Use a raw pthread here to insulate ourselves from bugs in other
- // Gecko code that we're trying to protect!
- //
- // Note that we let the watchdog in charge of releasing |paramPtr|
- // if the pthread is successfully created.
- watchdogParam_t* paramPtr = new watchdogParam_t(aMode, aTimeoutSecs);
- pthread_t watchdog;
- if (pthread_create(&watchdog, nullptr,
- ForceQuitWatchdog,
- reinterpret_cast<void*>(paramPtr))) {
- // Better safe than sorry.
- delete paramPtr;
- QuitHard(aMode);
- }
- // The watchdog thread is off and running now.
- }
- } // hal_impl
- } // mozilla
|