hal/linux/LinuxPower.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "Hal.h"
     8 #include <unistd.h>
     9 #include <sys/reboot.h>
    10 #include "nsIObserverService.h"
    11 #include "mozilla/Services.h"
    13 namespace mozilla {
    14 namespace hal_impl {
    16 void
    17 Reboot()
    18 {
    19   nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
    20   if (obsServ) {
    21     obsServ->NotifyObservers(nullptr, "system-reboot", nullptr);
    22   }
    23   sync();
    24   reboot(RB_AUTOBOOT);
    25 }
    27 void
    28 PowerOff()
    29 {
    30   nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
    31   if (obsServ) {
    32     obsServ->NotifyObservers(nullptr, "system-power-off", nullptr);
    33   }
    34   sync();
    35   reboot(RB_POWER_OFF);
    36 }
    38 // Structure to specify how watchdog pthread is going to work.
    39 typedef struct watchdogParam
    40 {
    41   hal::ShutdownMode mode; // Specify how to shutdown the system.
    42   int32_t timeoutSecs;    // Specify the delayed seconds to shutdown the system.
    44   watchdogParam(hal::ShutdownMode aMode, int32_t aTimeoutSecs)
    45     : mode(aMode), timeoutSecs(aTimeoutSecs) {}
    46 } watchdogParam_t;
    48 // Function to complusively shut down the system with a given mode.
    49 static void
    50 QuitHard(hal::ShutdownMode aMode)
    51 {
    52   switch (aMode)
    53   {
    54     case hal::eHalShutdownMode_PowerOff:
    55       PowerOff();
    56       break;
    57     case hal::eHalShutdownMode_Reboot:
    58       Reboot();
    59       break;
    60     case hal::eHalShutdownMode_Restart:
    61       // Don't let signal handlers affect forced shutdown.
    62       kill(0, SIGKILL);
    63       // If we can't SIGKILL our process group, something is badly
    64       // wrong.  Trying to deliver a catch-able signal to ourselves can
    65       // invoke signal handlers and might cause problems.  So try
    66       // _exit() and hope we go away.
    67       _exit(1);
    68       break;
    69     default:
    70       MOZ_CRASH();
    71   }
    72 }
    74 // Function to complusively shut down the system with a given mode when timeout.
    75 static void*
    76 ForceQuitWatchdog(void* aParamPtr)
    77 {
    78   watchdogParam_t* paramPtr = reinterpret_cast<watchdogParam_t*>(aParamPtr);
    79   if (paramPtr->timeoutSecs > 0 && paramPtr->timeoutSecs <= 30) {
    80     // If we shut down normally before the timeout, this thread will
    81     // be harmlessly reaped by the OS.
    82     TimeStamp deadline =
    83       (TimeStamp::Now() + TimeDuration::FromSeconds(paramPtr->timeoutSecs));
    84     while (true) {
    85       TimeDuration remaining = (deadline - TimeStamp::Now());
    86       int sleepSeconds = int(remaining.ToSeconds());
    87       if (sleepSeconds <= 0) {
    88         break;
    89       }
    90       sleep(sleepSeconds);
    91     }
    92   }
    93   hal::ShutdownMode mode = paramPtr->mode;
    94   delete paramPtr;
    95   QuitHard(mode);
    96   return nullptr;
    97 }
    99 void
   100 StartForceQuitWatchdog(hal::ShutdownMode aMode, int32_t aTimeoutSecs)
   101 {
   102   // Force-quits are intepreted a little more ferociously on Gonk,
   103   // because while Gecko is in the process of shutting down, the user
   104   // can't call 911, for example.  And if we hang on shutdown, bad
   105   // things happen.  So, make sure that doesn't happen.
   106   if (aTimeoutSecs <= 0) {
   107     return;
   108   }
   110   // Use a raw pthread here to insulate ourselves from bugs in other
   111   // Gecko code that we're trying to protect!
   112   // 
   113   // Note that we let the watchdog in charge of releasing |paramPtr|
   114   // if the pthread is successfully created.
   115   watchdogParam_t* paramPtr = new watchdogParam_t(aMode, aTimeoutSecs);
   116   pthread_t watchdog;
   117   if (pthread_create(&watchdog, nullptr,
   118                      ForceQuitWatchdog,
   119                      reinterpret_cast<void*>(paramPtr))) {
   120     // Better safe than sorry.
   121     delete paramPtr;
   122     QuitHard(aMode);
   123   }
   124   // The watchdog thread is off and running now.
   125 }
   127 } // hal_impl
   128 } // mozilla

mercurial