public static function shutdown()
 {
     if (!empty(self::$instance) && self::$instance instanceof waLongActionController) {
         self::$instance->uncleanShutdown();
         self::$instance = null;
     }
 }
 public function execute()
 {
     $this->initEnv();
     // Get processId from GET/POST parameters
     foreach (array('processId', 'processid') as $field) {
         if ($this->_processId = waRequest::request($field)) {
             break;
         }
     }
     if (!$this->_processId) {
         if (!$this->preInit()) {
             return;
         }
         $this->_initDataStructures();
         // it calls init() too
         $this->getStorage()->close();
     } else {
         $this->_newProcess = false;
         $status = $this->_obtainLock();
         if ($this->_data['ready']) {
             $this->_runner = false;
             if ($this->finish($this->_files['old']['file'])) {
                 $this->_cleanup();
             }
             // check info output
             return;
         }
         switch ($status) {
             case self::TYPE_RUNNER:
                 ignore_user_abort(true);
                 if (self::$instance !== false) {
                     register_shutdown_function(array(__CLASS__, 'shutdown'));
                 }
                 self::$instance =& $this;
                 $this->_transaction = true;
                 $this->restore();
                 $this->_transaction = false;
                 $this->getStorage()->close();
                 break;
             case self::TYPE_MESSENGER:
                 $this->info();
                 return;
             case self::TYPE_NONE:
                 // must be a lost messenger
                 echo json_encode(array('ready' => true, 'processId' => $this->_processId));
                 return;
         }
     }
     // For new processes do not call step() in the first iteration
     // to be able to return processId to browser instantly.
     $continue = !$this->_newProcess;
     $this->_heartbeat = microtime(true);
     $this->_data['complete'] = !$continue;
     $this->_save(true);
     $this->_transaction = true;
     while ($continue && !$this->isDone()) {
         $continue = $this->step();
         $this->_data['complete'] = !$continue;
         $this->_save();
     }
     if ($continue) {
         // We're done!
         $this->_data['ready'] = true;
     }
     $this->_save(true);
     $this->_runner = false;
     $this->_transaction = false;
     if ($continue) {
         if ($this->finish($this->_files['old']['file'])) {
             $this->_cleanup();
         }
         // check info output
     } else {
         $this->info();
     }
     self::$instance = false;
 }