[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pearsonca/rstudio/master/src/cpp/r/session/RInit.cpp [Back]  [Original]

/*
 * RInit.cpp
 *
 * Copyright (C) 2009-18 by RStudio, PBC
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include 

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "REmbedded.hpp"
#include "RInit.hpp"
#include "RSuspend.hpp"
#include "RStdCallbacks.hpp"
#include "RRestartContext.hpp"

#include "graphics/RGraphicsDevice.hpp"

// constants for graphics scratch subdirectory
#define kGraphicsPath "graphics"

using namespace rstudio::core;

namespace rstudio {
namespace r {
namespace session {

namespace {

// is this R 3.0 or greater
bool s_isR3 = false;

// is this R 3.3 or greater
bool s_isR3_3 = false;

// function for deferred deserialization actions. this encapsulates parts of 
// the initialization process that are potentially highly latent. this allows
// clients to bring their UI up and then receive an event indicating that the
// latent deserialization actions are taking place
boost::function s_deferredDeserializationAction;
   
void reportDeferredDeserializationError(const Error& error)
{
   // log error
   LOG_ERROR(error);

   // report to user
   std::string errMsg = r::endUserErrorMessage(error);
   REprintf((errMsg + "\n").c_str());
}

std::string createAliasedPath(const FilePath& filePath)
{
   return FilePath::createAliasedPath(filePath, utils::userHomePath());
}
   
Error restoreGlobalEnvFromFile(const std::string& path, std::string* pErrMessage)
{
   r::exec::RFunction fn(".rs.restoreGlobalEnvFromFile");
   fn.addParam(path);
   return fn.call(pErrMessage);
}

void completeDeferredSessionInit(bool newSession)
{
   // always cleanup any restart context here
   restartContext().removeSessionState();

   // call external hook
   if (rCallbacks().deferredInit)
      rCallbacks().deferredInit(newSession);
}


void deferredRestoreSuspendedSession(
                     const boost::function& deferredRestoreAction)
{
   // notify client of serialization status
   SerializationCallbackScope cb(kSerializationActionResumeSession);
   
   // suppress interrupts which occur during restore
   r::exec::IgnoreInterruptsScope ignoreInterrupts;
 
   // suppress output which occurs during restore (packages can sometimes
   // print messages to the console indicating they have conflicts -- the
   // has already seen these messages and doesn't expect them now so 
   // we suppress them
   utils::SuppressOutputInScope suppressOutput;
   
   // restore action
   Error error = deferredRestoreAction();
   if (error)
      reportDeferredDeserializationError(error);

   // complete deferred init
   completeDeferredSessionInit(false);
}

void deferredRestoreNewSession()
{
   // restore the default global environment if there is one
   FilePath globalEnvPath = utils::startupEnvironmentFilePath();
   if (utils::restoreWorkspace() && globalEnvPath.exists())
   {
      // notify client of serialization status
      SerializationCallbackScope cb(kSerializationActionLoadDefaultWorkspace,
                                    globalEnvPath);

      // ignore interrupts which occur during restoring of the global env
      // the restoration will run to completion in any case and then the
      // next thing the user does will be "interrupted" -- clearly not
      // what they intended
      r::exec::IgnoreInterruptsScope ignoreInterrupts;

      std::string path = string_utils::utf8ToSystem(globalEnvPath.getAbsolutePath());
      std::string aliasedPath = createAliasedPath(globalEnvPath);
      
      std::string errMessage;
      Error error = restoreGlobalEnvFromFile(path, &errMessage);
      if (error)
      {
         ::REprintf(
                  "WARNING: Failed to restore workspace from '%s' "
                  "(an internal error occurred)\n",
                  aliasedPath.c_str());
         LOG_ERROR(error);
      }
      else if (!errMessage.empty())
      {
         std::stringstream ss;
         ss 

Web Proxy Viewer  |  New URL  |  Original Page