<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(OS_MACOSX)
#include <signal.h>
#include <unistd.h>
#endif  // OS_MACOSX

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/metrics/field_trial.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
#include "base/string_util.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "chrome/renderer/render_process_impl.h"
#include "chrome/renderer/render_thread.h"
#include "content/common/main_function_params.h"
#include "content/common/hi_res_timer_manager.h"
#include "grit/generated_resources.h"
#include "net/base/net_module.h"
#include "ui/base/system_monitor/system_monitor.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/gfx_module.h"

#if defined(OS_MACOSX)
#include "base/eintr_wrapper.h"
#include "chrome/app/breakpad_mac.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#endif  // OS_MACOSX

#if defined(OS_MACOSX)
namespace {

// TODO(viettrungluu): crbug.com/28547: The following signal handling is needed,
// as a stopgap, to avoid leaking due to not releasing Breakpad properly.
// Without this problem, this could all be eliminated. Remove when Breakpad is
// fixed?
// TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing).
// The code should be properly shared (or this code should be eliminated).
int g_shutdown_pipe_write_fd = -1;

void SIGTERMHandler(int signal) {
  RAW_CHECK(signal == SIGTERM);
  RAW_LOG(INFO, "Handling SIGTERM in renderer.");

  // Reinstall the default handler.  We had one shot at graceful shutdown.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_DFL;
  CHECK(sigaction(signal, &action, NULL) == 0);

  RAW_CHECK(g_shutdown_pipe_write_fd != -1);
  size_t bytes_written = 0;
  do {
    int rv = HANDLE_EINTR(
        write(g_shutdown_pipe_write_fd,
              reinterpret_cast<const char*>(&signal) + bytes_written,
              sizeof(signal) - bytes_written));
    RAW_CHECK(rv >= 0);
    bytes_written += rv;
  } while (bytes_written < sizeof(signal));

  RAW_LOG(INFO, "Wrote signal to shutdown pipe.");
}

class ShutdownDetector : public base::PlatformThread::Delegate {
 public:
  explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) {
    CHECK(shutdown_fd_ != -1);
  }

  virtual void ThreadMain() {
    int signal;
    size_t bytes_read = 0;
    ssize_t ret;
    do {
      ret = HANDLE_EINTR(
          read(shutdown_fd_,
               reinterpret_cast<char*>(&signal) + bytes_read,
               sizeof(signal) - bytes_read));
      if (ret < 0) {
        NOTREACHED() << "Unexpected error: " << strerror(errno);
        break;
      } else if (ret == 0) {
        NOTREACHED() << "Unexpected closure of shutdown pipe.";
        break;
      }
      bytes_read += ret;
    } while (bytes_read < sizeof(signal));

    if (bytes_read == sizeof(signal))
      VLOG(1) << "Handling shutdown for signal " << signal << ".";
    else
      VLOG(1) << "Handling shutdown for unknown signal.";

    // Clean up Breakpad if necessary.
    if (IsCrashReporterEnabled()) {
      VLOG(1) << "Cleaning up Breakpad.";
      DestructCrashReporter();
    } else {
      VLOG(1) << "Breakpad not enabled; no clean-up needed.";
    }

    // Something went seriously wrong, so get out.
    if (bytes_read != sizeof(signal)) {
      LOG(WARNING) << "Failed to get signal. Quitting ungracefully.";
      _exit(1);
    }

    // Re-raise the signal.
    kill(getpid(), signal);

    // The signal may be handled on another thread. Give that a chance to
    // happen.
    sleep(3);

    // We really should be dead by now.  For whatever reason, we're not. Exit
    // immediately, with the exit status set to the signal number with bit 8
    // set.  On the systems that we care about, this exit status is what is
    // normally used to indicate an exit by this signal's default handler.
    // This mechanism isn't a de jure standard, but even in the worst case, it
    // should at least result in an immediate exit.
    LOG(WARNING) << "Still here, exiting really ungracefully.";
    _exit(signal | (1 << 7));
  }

 private:
  const int shutdown_fd_;

  DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
};

}  // namespace
#endif  // OS_MACOSX

// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleRendererErrorTestParameters(const CommandLine& command_line) {
  // This parameter causes an assertion.
  if (command_line.HasSwitch(switches::kRendererAssertTest)) {
    DCHECK(false);
  }

#if !defined(OFFICIAL_BUILD)
  // This parameter causes an assertion too.
  if (command_line.HasSwitch(switches::kRendererCheckFalseTest)) {
    CHECK(false);
  }
#endif  // !defined(OFFICIAL_BUILD)

  // This parameter causes a null pointer crash (crash reporter trigger).
  if (command_line.HasSwitch(switches::kRendererCrashTest)) {
    int* bad_pointer = NULL;
    *bad_pointer = 0;
  }

  if (command_line.HasSwitch(switches::kRendererStartupDialog)) {
    ChildProcess::WaitForDebugger("Renderer");
  }
}

// This is a simplified version of the browser Jankometer, which measures
// the processing time of tasks on the render thread.
class RendererMessageLoopObserver : public MessageLoop::TaskObserver {
 public:
  RendererMessageLoopObserver()
      : process_times_(base::Histogram::FactoryGet(
            "Chrome.ProcMsgL RenderThread",
            1, 3600000, 50, base::Histogram::kUmaTargetedHistogramFlag)) {}
  virtual ~RendererMessageLoopObserver() {}

  virtual void WillProcessTask(const Task* task) {
    begin_process_message_ = base::TimeTicks::Now();
  }

  virtual void DidProcessTask(const Task* task) {
    if (begin_process_message_ != base::TimeTicks())
      process_times_->AddTime(base::TimeTicks::Now() - begin_process_message_);
  }

 private:
  base::TimeTicks begin_process_message_;
  scoped_refptr<base::Histogram> process_times_;
  DISALLOW_COPY_AND_ASSIGN(RendererMessageLoopObserver);
};

// mainline routine for running as the Renderer process
int RendererMain(const MainFunctionParams& parameters) {
  TRACE_EVENT_BEGIN("RendererMain", 0, "");

  const CommandLine& parsed_command_line = parameters.command_line_;
  base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_;

#if defined(OS_MACOSX)
  // TODO(viettrungluu): Code taken from browser_main.cc.
  int pipefd[2];
  int ret = pipe(pipefd);
  if (ret < 0) {
    PLOG(DFATAL) << "Failed to create pipe";
  } else {
    int shutdown_pipe_read_fd = pipefd[0];
    g_shutdown_pipe_write_fd = pipefd[1];
    const size_t kShutdownDetectorThreadStackSize = 4096;
    if (!base::PlatformThread::CreateNonJoinable(
            kShutdownDetectorThreadStackSize,
            new ShutdownDetector(shutdown_pipe_read_fd))) {
      LOG(DFATAL) << "Failed to create shutdown detector task.";
    }
  }

  // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking
  // Mach ports.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIGTERMHandler;
  CHECK(sigaction(SIGTERM, &action, NULL) == 0);
#endif  // OS_MACOSX

#if defined(OS_CHROMEOS)
  // As Zygote process starts up earlier than browser process gets its own
  // locale (at login time for Chrome OS), we have to set the ICU default
  // locale for renderer process here.
  // ICU locale will be used for fallback font selection etc.
  if (parsed_command_line.HasSwitch(switches::kLang)) {
    const std::string locale =
        parsed_command_line.GetSwitchValueASCII(switches::kLang);
    base::i18n::SetICUDefaultLocale(locale);
  }
#endif

  // Configure modules that need access to resources.
  net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
  gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);

  // This function allows pausing execution using the --renderer-startup-dialog
  // flag allowing us to attach a debugger.
  // Do not move this function down since that would mean we can't easily debug
  // whatever occurs before it.
  HandleRendererErrorTestParameters(parsed_command_line);

  RendererMainPlatformDelegate platform(parameters);

  base::StatsScope<base::StatsCounterTimer>
      startup_timer(chrome::Counters::renderer_main());

  RendererMessageLoopObserver task_observer;
#if defined(OS_MACOSX)
  // As long as we use Cocoa in the renderer (for the forseeable future as of
  // now; see http://crbug.com/13890 for info) we need to have a UI loop.
  MessageLoop main_message_loop(MessageLoop::TYPE_UI);
#else
  // The main message loop of the renderer services doesn't have IO or UI tasks,
  // unless in-process-plugins is used.
  MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ?
              MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT);
#endif
  main_message_loop.AddTaskObserver(&task_observer);

  base::PlatformThread::SetName("CrRendererMain");

  ui::SystemMonitor system_monitor;
  HighResolutionTimerManager hi_res_timer_manager;

  platform.PlatformInitialize();

  bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
  platform.InitSandboxTests(no_sandbox);

  // Initialize histogram statistics gathering system.
  // Don't create StatisticsRecorder in the single process mode.
  scoped_ptr<base::StatisticsRecorder> statistics;
  if (!base::StatisticsRecorder::IsActive()) {
    statistics.reset(new base::StatisticsRecorder());
  }

  // Initialize statistical testing infrastructure.
  base::FieldTrialList field_trial;
  // Ensure any field trials in browser are reflected into renderer.
  if (parsed_command_line.HasSwitch(switches::kForceFieldTestNameAndValue)) {
    std::string persistent = parsed_command_line.GetSwitchValueASCII(
        switches::kForceFieldTestNameAndValue);
    bool ret = field_trial.CreateTrialsInChildProcess(persistent);
    DCHECK(ret);
  }

  // Load pepper plugins before engaging the sandbox.
  PepperPluginRegistry::GetInstance();

  {
#if !defined(OS_LINUX)
    // TODO(markus): Check if it is OK to unconditionally move this
    // instruction down.
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif
    bool run_loop = true;
    if (!no_sandbox) {
      run_loop = platform.EnableSandbox();
    } else {
      LOG(ERROR) << "Running without renderer sandbox";
    }
#if defined(OS_LINUX)
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif

    platform.RunSandboxTests();

    startup_timer.Stop();  // End of Startup Time Measurement.

    if (run_loop) {
      if (pool)
        pool->Recycle();
      TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0);
      MessageLoop::current()->Run();
      TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0);
    }
  }
  platform.PlatformUninitialize();
  TRACE_EVENT_END("RendererMain", 0, "");
  return 0;
}
<commit_msg>Revert 78517 - Add a histogram to measure task execution time for the render thread.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(OS_MACOSX)
#include <signal.h>
#include <unistd.h>
#endif  // OS_MACOSX

#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/metrics/field_trial.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string_util.h"
#include "base/threading/platform_thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/pepper_plugin_registry.h"
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "chrome/renderer/render_process_impl.h"
#include "chrome/renderer/render_thread.h"
#include "content/common/main_function_params.h"
#include "content/common/hi_res_timer_manager.h"
#include "grit/generated_resources.h"
#include "net/base/net_module.h"
#include "ui/base/system_monitor/system_monitor.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/gfx_module.h"

#if defined(OS_MACOSX)
#include "base/eintr_wrapper.h"
#include "chrome/app/breakpad_mac.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#endif  // OS_MACOSX

#if defined(OS_MACOSX)
namespace {

// TODO(viettrungluu): crbug.com/28547: The following signal handling is needed,
// as a stopgap, to avoid leaking due to not releasing Breakpad properly.
// Without this problem, this could all be eliminated. Remove when Breakpad is
// fixed?
// TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing).
// The code should be properly shared (or this code should be eliminated).
int g_shutdown_pipe_write_fd = -1;

void SIGTERMHandler(int signal) {
  RAW_CHECK(signal == SIGTERM);
  RAW_LOG(INFO, "Handling SIGTERM in renderer.");

  // Reinstall the default handler.  We had one shot at graceful shutdown.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_DFL;
  CHECK(sigaction(signal, &action, NULL) == 0);

  RAW_CHECK(g_shutdown_pipe_write_fd != -1);
  size_t bytes_written = 0;
  do {
    int rv = HANDLE_EINTR(
        write(g_shutdown_pipe_write_fd,
              reinterpret_cast<const char*>(&signal) + bytes_written,
              sizeof(signal) - bytes_written));
    RAW_CHECK(rv >= 0);
    bytes_written += rv;
  } while (bytes_written < sizeof(signal));

  RAW_LOG(INFO, "Wrote signal to shutdown pipe.");
}

class ShutdownDetector : public base::PlatformThread::Delegate {
 public:
  explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) {
    CHECK(shutdown_fd_ != -1);
  }

  virtual void ThreadMain() {
    int signal;
    size_t bytes_read = 0;
    ssize_t ret;
    do {
      ret = HANDLE_EINTR(
          read(shutdown_fd_,
               reinterpret_cast<char*>(&signal) + bytes_read,
               sizeof(signal) - bytes_read));
      if (ret < 0) {
        NOTREACHED() << "Unexpected error: " << strerror(errno);
        break;
      } else if (ret == 0) {
        NOTREACHED() << "Unexpected closure of shutdown pipe.";
        break;
      }
      bytes_read += ret;
    } while (bytes_read < sizeof(signal));

    if (bytes_read == sizeof(signal))
      VLOG(1) << "Handling shutdown for signal " << signal << ".";
    else
      VLOG(1) << "Handling shutdown for unknown signal.";

    // Clean up Breakpad if necessary.
    if (IsCrashReporterEnabled()) {
      VLOG(1) << "Cleaning up Breakpad.";
      DestructCrashReporter();
    } else {
      VLOG(1) << "Breakpad not enabled; no clean-up needed.";
    }

    // Something went seriously wrong, so get out.
    if (bytes_read != sizeof(signal)) {
      LOG(WARNING) << "Failed to get signal. Quitting ungracefully.";
      _exit(1);
    }

    // Re-raise the signal.
    kill(getpid(), signal);

    // The signal may be handled on another thread. Give that a chance to
    // happen.
    sleep(3);

    // We really should be dead by now.  For whatever reason, we're not. Exit
    // immediately, with the exit status set to the signal number with bit 8
    // set.  On the systems that we care about, this exit status is what is
    // normally used to indicate an exit by this signal's default handler.
    // This mechanism isn't a de jure standard, but even in the worst case, it
    // should at least result in an immediate exit.
    LOG(WARNING) << "Still here, exiting really ungracefully.";
    _exit(signal | (1 << 7));
  }

 private:
  const int shutdown_fd_;

  DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
};

}  // namespace
#endif  // OS_MACOSX

// This function provides some ways to test crash and assertion handling
// behavior of the renderer.
static void HandleRendererErrorTestParameters(const CommandLine& command_line) {
  // This parameter causes an assertion.
  if (command_line.HasSwitch(switches::kRendererAssertTest)) {
    DCHECK(false);
  }

#if !defined(OFFICIAL_BUILD)
  // This parameter causes an assertion too.
  if (command_line.HasSwitch(switches::kRendererCheckFalseTest)) {
    CHECK(false);
  }
#endif  // !defined(OFFICIAL_BUILD)

  // This parameter causes a null pointer crash (crash reporter trigger).
  if (command_line.HasSwitch(switches::kRendererCrashTest)) {
    int* bad_pointer = NULL;
    *bad_pointer = 0;
  }

  if (command_line.HasSwitch(switches::kRendererStartupDialog)) {
    ChildProcess::WaitForDebugger("Renderer");
  }
}

// mainline routine for running as the Renderer process
int RendererMain(const MainFunctionParams& parameters) {
  TRACE_EVENT_BEGIN("RendererMain", 0, "");

  const CommandLine& parsed_command_line = parameters.command_line_;
  base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_;

#if defined(OS_MACOSX)
  // TODO(viettrungluu): Code taken from browser_main.cc.
  int pipefd[2];
  int ret = pipe(pipefd);
  if (ret < 0) {
    PLOG(DFATAL) << "Failed to create pipe";
  } else {
    int shutdown_pipe_read_fd = pipefd[0];
    g_shutdown_pipe_write_fd = pipefd[1];
    const size_t kShutdownDetectorThreadStackSize = 4096;
    if (!base::PlatformThread::CreateNonJoinable(
            kShutdownDetectorThreadStackSize,
            new ShutdownDetector(shutdown_pipe_read_fd))) {
      LOG(DFATAL) << "Failed to create shutdown detector task.";
    }
  }

  // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking
  // Mach ports.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIGTERMHandler;
  CHECK(sigaction(SIGTERM, &action, NULL) == 0);
#endif  // OS_MACOSX

#if defined(OS_CHROMEOS)
  // As Zygote process starts up earlier than browser process gets its own
  // locale (at login time for Chrome OS), we have to set the ICU default
  // locale for renderer process here.
  // ICU locale will be used for fallback font selection etc.
  if (parsed_command_line.HasSwitch(switches::kLang)) {
    const std::string locale =
        parsed_command_line.GetSwitchValueASCII(switches::kLang);
    base::i18n::SetICUDefaultLocale(locale);
  }
#endif

  // Configure modules that need access to resources.
  net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
  gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);

  // This function allows pausing execution using the --renderer-startup-dialog
  // flag allowing us to attach a debugger.
  // Do not move this function down since that would mean we can't easily debug
  // whatever occurs before it.
  HandleRendererErrorTestParameters(parsed_command_line);

  RendererMainPlatformDelegate platform(parameters);

  base::StatsScope<base::StatsCounterTimer>
      startup_timer(chrome::Counters::renderer_main());

#if defined(OS_MACOSX)
  // As long as we use Cocoa in the renderer (for the forseeable future as of
  // now; see http://crbug.com/13890 for info) we need to have a UI loop.
  MessageLoop main_message_loop(MessageLoop::TYPE_UI);
#else
  // The main message loop of the renderer services doesn't have IO or UI tasks,
  // unless in-process-plugins is used.
  MessageLoop main_message_loop(RenderProcessImpl::InProcessPlugins() ?
              MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT);
#endif

  base::PlatformThread::SetName("CrRendererMain");

  ui::SystemMonitor system_monitor;
  HighResolutionTimerManager hi_res_timer_manager;

  platform.PlatformInitialize();

  bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
  platform.InitSandboxTests(no_sandbox);

  // Initialize histogram statistics gathering system.
  // Don't create StatisticsRecorder in the single process mode.
  scoped_ptr<base::StatisticsRecorder> statistics;
  if (!base::StatisticsRecorder::IsActive()) {
    statistics.reset(new base::StatisticsRecorder());
  }

  // Initialize statistical testing infrastructure.
  base::FieldTrialList field_trial;
  // Ensure any field trials in browser are reflected into renderer.
  if (parsed_command_line.HasSwitch(switches::kForceFieldTestNameAndValue)) {
    std::string persistent = parsed_command_line.GetSwitchValueASCII(
        switches::kForceFieldTestNameAndValue);
    bool ret = field_trial.CreateTrialsInChildProcess(persistent);
    DCHECK(ret);
  }

  // Load pepper plugins before engaging the sandbox.
  PepperPluginRegistry::GetInstance();

  {
#if !defined(OS_LINUX)
    // TODO(markus): Check if it is OK to unconditionally move this
    // instruction down.
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif
    bool run_loop = true;
    if (!no_sandbox) {
      run_loop = platform.EnableSandbox();
    } else {
      LOG(ERROR) << "Running without renderer sandbox";
    }
#if defined(OS_LINUX)
    RenderProcessImpl render_process;
    render_process.set_main_thread(new RenderThread());
#endif

    platform.RunSandboxTests();

    startup_timer.Stop();  // End of Startup Time Measurement.

    if (run_loop) {
      if (pool)
        pool->Recycle();
      TRACE_EVENT_BEGIN("RendererMain.START_MSG_LOOP", 0, 0);
      MessageLoop::current()->Run();
      TRACE_EVENT_END("RendererMain.START_MSG_LOOP", 0, 0);
    }
  }
  platform.PlatformUninitialize();
  TRACE_EVENT_END("RendererMain", 0, "");
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "echo_client_handler.hpp"

#include <websocketpp/websocketpp.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include <iostream>

using boost::asio::ip::tcp;
using namespace websocketecho;

int main(int argc, char* argv[]) {
	std::string uri;

	/*if (argc != 2) {
		std::cout << "Usage: `echo_client test_url`" << std::endl;
	} else {
		uri = argv[1];
	}*/

	echo_client_handler_ptr c(new echo_client_handler());

	try {
		boost::asio::io_service io_service;

		websocketpp::client_ptr client(new websocketpp::client(io_service,c));

		client->init();
		client->set_header("User Agent","WebSocket++/2011-10-27");

		client->connect("ws://localhost:9001/getCaseCount");
		io_service.run();

		std::cout << "case count: " << c->m_case_count << std::endl;

		for (int i = 1; i <= c->m_case_count; i++) {
			io_service.reset();
			//boost::asio::io_service ios;

			//client.reset();
			//client = websocketpp::client_ptr(new websocketpp::client(io_service,c));

			std::cout << "foo: " << i << std::endl;
			//websocketpp::client_ptr client2(new websocketpp::client(io_service,c));

			client->set_alog_level(websocketpp::ALOG_OFF);
			client->set_elog_level(websocketpp::LOG_OFF);

			client->init();
			client->set_header("User Agent","WebSocket++/2011-10-27");

			std::stringstream foo;

			foo << "ws://localhost:9001/runCase?case=" << i << "&agent=\"WebSocket++Snapshot/2011-10-27\"";

			client->connect(foo.str());
			io_service.run();
		}

		std::cout << "done" << std::endl;

	} catch (std::exception& e) {
		std::cerr << "Exception: " << e.what() << std::endl;
	}

	return 0;
}
<commit_msg>fix for relative include paths<commit_after>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "echo_client_handler.hpp"

#include "../../src/websocketpp.hpp"
#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include <iostream>

using boost::asio::ip::tcp;
using namespace websocketecho;

int main(int argc, char* argv[]) {
	std::string uri;

	/*if (argc != 2) {
		std::cout << "Usage: `echo_client test_url`" << std::endl;
	} else {
		uri = argv[1];
	}*/

	echo_client_handler_ptr c(new echo_client_handler());

	try {
		boost::asio::io_service io_service;

		websocketpp::client_ptr client(new websocketpp::client(io_service,c));

		client->init();
		client->set_header("User Agent","WebSocket++/2011-10-27");

		client->connect("ws://localhost:9001/getCaseCount");
		io_service.run();

		std::cout << "case count: " << c->m_case_count << std::endl;

		for (int i = 1; i <= c->m_case_count; i++) {
			io_service.reset();
			//boost::asio::io_service ios;

			//client.reset();
			//client = websocketpp::client_ptr(new websocketpp::client(io_service,c));

			std::cout << "foo: " << i << std::endl;
			//websocketpp::client_ptr client2(new websocketpp::client(io_service,c));

			client->set_alog_level(websocketpp::ALOG_OFF);
			client->set_elog_level(websocketpp::LOG_OFF);

			client->init();
			client->set_header("User Agent","WebSocket++/2011-10-27");

			std::stringstream foo;

			foo << "ws://localhost:9001/runCase?case=" << i << "&agent=\"WebSocket++Snapshot/2011-10-27\"";

			client->connect(foo.str());
			io_service.run();
		}

		std::cout << "done" << std::endl;

	} catch (std::exception& e) {
		std::cerr << "Exception: " << e.what() << std::endl;
	}

	return 0;
}
<|endoftext|>


<commit_before>//===-- sanitizer_coverage_mapping.cc -------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Mmap-based implementation of sanitizer coverage.
//
// This is part of the implementation of code coverage that does not require
// __sanitizer_cov_dump() call. Data is stored in 2 files per process.
//
// $pid.sancov.map describes process memory layout in the following text-based
// format:
// <pointer size in bits>  // 1 line, 32 or 64
// <mapping start> <mapping end> <base address> <dso name> // repeated
// ...
// Mapping lines are NOT sorted. This file is updated every time memory layout
// is changed (i.e. in dlopen() and dlclose() interceptors).
//
// $pid.sancov.raw is a binary dump of PC values, sizeof(uptr) each. Again, not
// sorted. This file is extended by 64Kb at a time and mapped into memory. It
// contains one or more 0 words at the end, up to the next 64Kb aligned offset.
//
// To convert these 2 files to the usual .sancov format, run sancov.py rawunpack
// $pid.sancov.raw.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_allocator_internal.h"
#include "sanitizer_libc.h"
#include "sanitizer_procmaps.h"

namespace __sanitizer {

static const uptr kMaxNumberOfModules = 1 << 14;
static const uptr kMaxTextSize = 64 * 1024;

struct CachedMapping {
 public:
  bool NeedsUpdate(uptr pc) {
    int new_pid = internal_getpid();
    if (last_pid == new_pid && pc && pc >= last_range_start &&
        pc < last_range_end)
      return false;
    last_pid = new_pid;
    return true;
  }

  void SetModuleRange(uptr start, uptr end) {
    last_range_start = start;
    last_range_end = end;
  }

 private:
  uptr last_range_start, last_range_end;
  int last_pid;
};

static CachedMapping cached_mapping;
static StaticSpinMutex mapping_mu;

void CovUpdateMapping(uptr caller_pc) {
  if (!common_flags()->coverage || !common_flags()->coverage_direct) return;

  SpinMutexLock l(&mapping_mu);

  if (!cached_mapping.NeedsUpdate(caller_pc))
    return;

  InternalScopedString text(kMaxTextSize);
  InternalScopedBuffer<LoadedModule> modules(kMaxNumberOfModules);
  CHECK(modules.data());
  int n_modules = GetListOfModules(modules.data(), kMaxNumberOfModules,
                                   /* filter */ 0);

  text.append("%d\n", sizeof(uptr) * 8);
  for (int i = 0; i < n_modules; ++i) {
    const char *module_name = StripModuleName(modules[i].full_name());
    for (unsigned j = 0; j < modules[i].n_ranges(); ++j) {
      if (modules[i].address_range_executable(j)) {
        uptr start = modules[i].address_range_start(j);
        uptr end = modules[i].address_range_end(j);
        uptr base = modules[i].base_address();
        text.append("%zx %zx %zx %s\n", start, end, base, module_name);
        if (caller_pc && caller_pc >= start && caller_pc < end)
          cached_mapping.SetModuleRange(start, end);
      }
    }
  }

  int err;
  InternalScopedString tmp_path(64 +
                                internal_strlen(common_flags()->coverage_dir));
  uptr res = internal_snprintf((char *)tmp_path.data(), tmp_path.size(),
                    "%s/%zd.sancov.map.tmp", common_flags()->coverage_dir,
                    internal_getpid());
  CHECK_LE(res, tmp_path.size());
  uptr map_fd = OpenFile(tmp_path.data(), true);
  if (internal_iserror(map_fd)) {
    Report(" Coverage: failed to open %s for writing\n", tmp_path.data());
    Die();
  }

  res = internal_write(map_fd, text.data(), text.length());
  if (internal_iserror(res, &err)) {
    Printf("sancov.map write failed: %d\n", err);
    Die();
  }
  internal_close(map_fd);

  InternalScopedString path(64 + internal_strlen(common_flags()->coverage_dir));
  res = internal_snprintf((char *)path.data(), path.size(), "%s/%zd.sancov.map",
                    common_flags()->coverage_dir, internal_getpid());
  CHECK_LE(res, path.size());
  res = internal_rename(tmp_path.data(), path.data());
  if (internal_iserror(res, &err)) {
    Printf("sancov.map rename failed: %d\n", err);
    Die();
  }
}

}  // namespace __sanitizer
<commit_msg>[asan] Better error message in coverage.<commit_after>//===-- sanitizer_coverage_mapping.cc -------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Mmap-based implementation of sanitizer coverage.
//
// This is part of the implementation of code coverage that does not require
// __sanitizer_cov_dump() call. Data is stored in 2 files per process.
//
// $pid.sancov.map describes process memory layout in the following text-based
// format:
// <pointer size in bits>  // 1 line, 32 or 64
// <mapping start> <mapping end> <base address> <dso name> // repeated
// ...
// Mapping lines are NOT sorted. This file is updated every time memory layout
// is changed (i.e. in dlopen() and dlclose() interceptors).
//
// $pid.sancov.raw is a binary dump of PC values, sizeof(uptr) each. Again, not
// sorted. This file is extended by 64Kb at a time and mapped into memory. It
// contains one or more 0 words at the end, up to the next 64Kb aligned offset.
//
// To convert these 2 files to the usual .sancov format, run sancov.py rawunpack
// $pid.sancov.raw.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_allocator_internal.h"
#include "sanitizer_libc.h"
#include "sanitizer_procmaps.h"

namespace __sanitizer {

static const uptr kMaxNumberOfModules = 1 << 14;
static const uptr kMaxTextSize = 64 * 1024;

struct CachedMapping {
 public:
  bool NeedsUpdate(uptr pc) {
    int new_pid = internal_getpid();
    if (last_pid == new_pid && pc && pc >= last_range_start &&
        pc < last_range_end)
      return false;
    last_pid = new_pid;
    return true;
  }

  void SetModuleRange(uptr start, uptr end) {
    last_range_start = start;
    last_range_end = end;
  }

 private:
  uptr last_range_start, last_range_end;
  int last_pid;
};

static CachedMapping cached_mapping;
static StaticSpinMutex mapping_mu;

void CovUpdateMapping(uptr caller_pc) {
  if (!common_flags()->coverage || !common_flags()->coverage_direct) return;

  SpinMutexLock l(&mapping_mu);

  if (!cached_mapping.NeedsUpdate(caller_pc))
    return;

  InternalScopedString text(kMaxTextSize);
  InternalScopedBuffer<LoadedModule> modules(kMaxNumberOfModules);
  CHECK(modules.data());
  int n_modules = GetListOfModules(modules.data(), kMaxNumberOfModules,
                                   /* filter */ 0);

  text.append("%d\n", sizeof(uptr) * 8);
  for (int i = 0; i < n_modules; ++i) {
    const char *module_name = StripModuleName(modules[i].full_name());
    for (unsigned j = 0; j < modules[i].n_ranges(); ++j) {
      if (modules[i].address_range_executable(j)) {
        uptr start = modules[i].address_range_start(j);
        uptr end = modules[i].address_range_end(j);
        uptr base = modules[i].base_address();
        text.append("%zx %zx %zx %s\n", start, end, base, module_name);
        if (caller_pc && caller_pc >= start && caller_pc < end)
          cached_mapping.SetModuleRange(start, end);
      }
    }
  }

  int err;
  InternalScopedString tmp_path(64 +
                                internal_strlen(common_flags()->coverage_dir));
  uptr res = internal_snprintf((char *)tmp_path.data(), tmp_path.size(),
                    "%s/%zd.sancov.map.tmp", common_flags()->coverage_dir,
                    internal_getpid());
  CHECK_LE(res, tmp_path.size());
  uptr map_fd = OpenFile(tmp_path.data(), true);
  if (internal_iserror(map_fd, &err)) {
    Report(" Coverage: failed to open %s for writing: %d\n", tmp_path.data(), err);
    Die();
  }

  res = internal_write(map_fd, text.data(), text.length());
  if (internal_iserror(res, &err)) {
    Printf("sancov.map write failed: %d\n", err);
    Die();
  }
  internal_close(map_fd);

  InternalScopedString path(64 + internal_strlen(common_flags()->coverage_dir));
  res = internal_snprintf((char *)path.data(), path.size(), "%s/%zd.sancov.map",
                    common_flags()->coverage_dir, internal_getpid());
  CHECK_LE(res, path.size());
  res = internal_rename(tmp_path.data(), path.data());
  if (internal_iserror(res, &err)) {
    Printf("sancov.map rename failed: %d\n", err);
    Die();
  }
}

}  // namespace __sanitizer
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#pragma once
#include <fc/exception/exception.hpp>
#include <fc/io/varint.hpp>
#include <memory>
#define GRAPHENE_DB_MAX_INSTANCE_ID  (uint64_t(-1)>>16)

namespace graphene { namespace db {
   using  std::shared_ptr;
   using  std::unique_ptr;
   using  std::vector;
   using  fc::flat_map;
   using  fc::variant;
   using  fc::unsigned_int;

   struct object_id_type
   {
      object_id_type( uint8_t s, uint8_t t, uint64_t i )
      {
         FC_ASSERT( i >> 48 == 0, "instance overflow", ("instance",i) );
         number = (uint64_t(s)<<56) | (uint64_t(t)<<48) | i;
      }
      object_id_type(){ number = 0; }

      uint8_t  space()const       { return number >> 56;              }
      uint8_t  type()const        { return number >> 48 & 0x00ff;     }
      uint16_t space_type()const { return number >> 48;              }
      uint64_t instance()const { return number & GRAPHENE_DB_MAX_INSTANCE_ID; }
      bool     is_null()const { return number == 0; }
      explicit operator uint64_t()const { return number; }

      friend bool  operator == ( const object_id_type& a, const object_id_type& b ) { return a.number == b.number; }
      friend bool  operator != ( const object_id_type& a, const object_id_type& b ) { return a.number != b.number; }
      friend bool  operator < ( const object_id_type& a, const object_id_type& b ) { return a.number < b.number; }
      friend bool  operator > ( const object_id_type& a, const object_id_type& b ) { return a.number > b.number; }

      object_id_type& operator++(int) { ++number; return *this; }
      object_id_type& operator++()    { ++number; return *this; }

      friend object_id_type operator+(const object_id_type& a, int delta ) {
         return object_id_type( a.space(), a.type(), a.instance() + delta );
      }
      friend object_id_type operator+(const object_id_type& a, int64_t delta ) {
         return object_id_type( a.space(), a.type(), a.instance() + delta );
      }
      friend size_t hash_value( object_id_type v ) { return std::hash<uint64_t>()(v.number); }

      template< typename T >
      bool is() const
      {
         return (number >> 48) == ((T::space_id << 8) | (T::type_id));
      }

      template< typename T >
      T as() const
      {
         FC_ASSERT( is<T>() );
         return T( *this );
      }

      explicit operator std::string() const
      {
          return fc::to_string(space()) + "." + fc::to_string(type()) + "." + fc::to_string(instance());
      }

      uint64_t                   number;
   };

   class object;
   class object_database;

   /// This template is used to downcast a generic object type to a specific xyz_object type.
   template<typename ObjectID>
   struct object_downcast { using type = object; };
   // This macro specializes the above template for a specific xyz_object type
#define MAP_OBJECT_ID_TO_TYPE(OBJECT) \
   namespace graphene { namespace db { \
   template<> \
   struct object_downcast<graphene::db::object_id<OBJECT::space_id, OBJECT::type_id>> { using type = OBJECT; }; \
   } }
   template<typename ObjectID>
   using object_downcast_t = typename object_downcast<ObjectID>::type;

   template<uint8_t SpaceID, uint8_t TypeID>
   struct object_id
   {
      static const uint8_t space_id = SpaceID;
      static const uint8_t type_id = TypeID;

      object_id() = default;
      object_id( unsigned_int i ):instance(i){}
      explicit object_id( uint64_t i ):instance(i)
      {
         FC_ASSERT( (i >> 48) == 0 );
      }
      object_id( object_id_type id ):instance(id.instance())
      {
      }

      friend object_id operator+(const object_id a, int64_t delta ) { return object_id( uint64_t(a.instance.value+delta) ); }
      friend object_id operator+(const object_id a, int delta ) { return object_id( uint64_t(a.instance.value+delta) ); }

      operator object_id_type()const { return object_id_type( SpaceID, TypeID, instance.value ); }
      explicit operator uint64_t()const { return object_id_type( *this ).number; }

      template<typename DB>
      auto operator()(const DB& db)const -> const decltype(db.get(*this))& { return db.get(*this); }

      friend bool  operator == ( const object_id& a, const object_id& b ) { return a.instance == b.instance; }
      friend bool  operator != ( const object_id& a, const object_id& b ) { return a.instance != b.instance; }
      friend bool  operator == ( const object_id_type& a, const object_id& b ) { return a == object_id_type(b); }
      friend bool  operator != ( const object_id_type& a, const object_id& b ) { return a != object_id_type(b); }
      friend bool  operator == ( const object_id& a, const object_id_type& b ) { return object_id_type(a) == b; }
      friend bool  operator != ( const object_id& a, const object_id_type& b ) { return object_id_type(a) != b; }
      friend bool  operator == ( const object_id& a, const fc::unsigned_int& b ) { return a.instance == b; }
      friend bool  operator != ( const object_id& a, const fc::unsigned_int& b ) { return a.instance != b; }
      friend bool  operator == ( const fc::unsigned_int& a, const object_id& b ) { return a == b.instance; }
      friend bool  operator != ( const fc::unsigned_int& a, const object_id& b ) { return a != b.instance; }

      friend bool  operator < ( const object_id& a, const object_id& b ) { return a.instance.value < b.instance.value; }
      friend bool  operator > ( const object_id& a, const object_id& b ) { return a.instance.value > b.instance.value; }

      friend size_t hash_value( object_id v ) { return std::hash<uint64_t>()(v.instance.value); }

      unsigned_int instance;
   };

} } // graphene::db

FC_REFLECT( graphene::db::object_id_type, (number) )

// REFLECT object_id manually because it has 2 template params
namespace fc {
template<uint8_t SpaceID, uint8_t TypeID>
struct get_typename<graphene::db::object_id<SpaceID,TypeID>>
{
   static const char* name() {
      return typeid(get_typename).name();
      static std::string _str = string("graphene::db::object_id<")+fc::to_string(SpaceID) + ":" + fc::to_string(TypeID)+">";
      return _str.c_str();
   }
};

template<uint8_t SpaceID, uint8_t TypeID>
struct reflector<graphene::db::object_id<SpaceID,TypeID> >
{
    typedef graphene::db::object_id<SpaceID,TypeID> type;
    typedef fc::true_type  is_defined;
    typedef fc::false_type is_enum;
    enum  member_count_enum {
      local_member_count = 1,
      total_member_count = 1
    };
    template<typename Visitor>
    static inline void visit( const Visitor& visitor )
    {
       typedef decltype(((type*)nullptr)->instance) member_type;
       visitor.TEMPLATE operator()<member_type,type,&type::instance>( "instance" );
    }
};

 inline void to_variant( const graphene::db::object_id_type& var,  fc::variant& vo, uint32_t max_depth = 1 )
 {
    vo = std::string( var );
 }

 inline void from_variant( const fc::variant& var,  graphene::db::object_id_type& vo, uint32_t max_depth = 1 )
 { try {
    vo.number = 0;
    const auto& s = var.get_string();
    auto first_dot = s.find('.');
    auto second_dot = s.find('.',first_dot+1);
    FC_ASSERT( first_dot != second_dot );
    FC_ASSERT( first_dot != 0 && first_dot != std::string::npos );
    vo.number = fc::to_uint64(s.substr( second_dot+1 ));
    FC_ASSERT( vo.number <= GRAPHENE_DB_MAX_INSTANCE_ID );
    auto space_id = fc::to_uint64( s.substr( 0, first_dot ) );
    FC_ASSERT( space_id <= 0xff );
    auto type_id =  fc::to_uint64( s.substr( first_dot+1, second_dot-first_dot-1 ) );
    FC_ASSERT( type_id <= 0xff );
    vo.number |= (space_id << 56) | (type_id << 48);
 } FC_CAPTURE_AND_RETHROW( (var) ) }
 template<uint8_t SpaceID, uint8_t TypeID>
 void to_variant( const graphene::db::object_id<SpaceID,TypeID>& var,  fc::variant& vo, uint32_t max_depth = 1 )
 {
    vo = fc::to_string(SpaceID) + "." + fc::to_string(TypeID) + "." + fc::to_string(var.instance.value);
 }
 template<uint8_t SpaceID, uint8_t TypeID>
 void from_variant( const fc::variant& var,  graphene::db::object_id<SpaceID,TypeID>& vo, uint32_t max_depth = 1 )
 { try {
    const auto& s = var.get_string();
    auto first_dot = s.find('.');
    auto second_dot = s.find('.',first_dot+1);
    FC_ASSERT( first_dot != second_dot );
    FC_ASSERT( first_dot != 0 && first_dot != std::string::npos );
    FC_ASSERT( fc::to_uint64( s.substr( 0, first_dot ) ) == SpaceID &&
               fc::to_uint64( s.substr( first_dot+1, second_dot-first_dot-1 ) ) == TypeID,
               "Space.Type.0 (${SpaceID}.${TypeID}.0) doesn't match expected value ${var}", ("TypeID",TypeID)("SpaceID",SpaceID)("var",var) );
    vo.instance = fc::to_uint64(s.substr( second_dot+1 ));
 } FC_CAPTURE_AND_RETHROW( (var) ) }

} // namespace fc

namespace std {
     template <> struct hash<graphene::db::object_id_type>
     {
          size_t operator()(const graphene::db::object_id_type& x) const
          {
              return std::hash<uint64_t>()(x.number);
          }
     };
}
<commit_msg>Wrap overlength line<commit_after>/*
 * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#pragma once
#include <fc/exception/exception.hpp>
#include <fc/io/varint.hpp>
#include <memory>
#define GRAPHENE_DB_MAX_INSTANCE_ID  (uint64_t(-1)>>16)

namespace graphene { namespace db {
   using  std::shared_ptr;
   using  std::unique_ptr;
   using  std::vector;
   using  fc::flat_map;
   using  fc::variant;
   using  fc::unsigned_int;

   struct object_id_type
   {
      object_id_type( uint8_t s, uint8_t t, uint64_t i )
      {
         FC_ASSERT( i >> 48 == 0, "instance overflow", ("instance",i) );
         number = (uint64_t(s)<<56) | (uint64_t(t)<<48) | i;
      }
      object_id_type(){ number = 0; }

      uint8_t  space()const       { return number >> 56;              }
      uint8_t  type()const        { return number >> 48 & 0x00ff;     }
      uint16_t space_type()const { return number >> 48;              }
      uint64_t instance()const { return number & GRAPHENE_DB_MAX_INSTANCE_ID; }
      bool     is_null()const { return number == 0; }
      explicit operator uint64_t()const { return number; }

      friend bool  operator == ( const object_id_type& a, const object_id_type& b ) { return a.number == b.number; }
      friend bool  operator != ( const object_id_type& a, const object_id_type& b ) { return a.number != b.number; }
      friend bool  operator < ( const object_id_type& a, const object_id_type& b ) { return a.number < b.number; }
      friend bool  operator > ( const object_id_type& a, const object_id_type& b ) { return a.number > b.number; }

      object_id_type& operator++(int) { ++number; return *this; }
      object_id_type& operator++()    { ++number; return *this; }

      friend object_id_type operator+(const object_id_type& a, int delta ) {
         return object_id_type( a.space(), a.type(), a.instance() + delta );
      }
      friend object_id_type operator+(const object_id_type& a, int64_t delta ) {
         return object_id_type( a.space(), a.type(), a.instance() + delta );
      }
      friend size_t hash_value( object_id_type v ) { return std::hash<uint64_t>()(v.number); }

      template< typename T >
      bool is() const
      {
         return (number >> 48) == ((T::space_id << 8) | (T::type_id));
      }

      template< typename T >
      T as() const
      {
         FC_ASSERT( is<T>() );
         return T( *this );
      }

      explicit operator std::string() const
      {
          return fc::to_string(space()) + "." + fc::to_string(type()) + "." + fc::to_string(instance());
      }

      uint64_t                   number;
   };

   class object;
   class object_database;

   /// This template is used to downcast a generic object type to a specific xyz_object type.
   template<typename ObjectID>
   struct object_downcast { using type = object; };
   // This macro specializes the above template for a specific xyz_object type
#define MAP_OBJECT_ID_TO_TYPE(OBJECT) \
   namespace graphene { namespace db { \
   template<> \
   struct object_downcast<graphene::db::object_id<OBJECT::space_id, \
                                                  OBJECT::type_id>> { using type = OBJECT; }; \
   } }
   template<typename ObjectID>
   using object_downcast_t = typename object_downcast<ObjectID>::type;

   template<uint8_t SpaceID, uint8_t TypeID>
   struct object_id
   {
      static const uint8_t space_id = SpaceID;
      static const uint8_t type_id = TypeID;

      object_id() = default;
      object_id( unsigned_int i ):instance(i){}
      explicit object_id( uint64_t i ):instance(i)
      {
         FC_ASSERT( (i >> 48) == 0 );
      }
      object_id( object_id_type id ):instance(id.instance())
      {
      }

      friend object_id operator+(const object_id a, int64_t delta ) { return object_id( uint64_t(a.instance.value+delta) ); }
      friend object_id operator+(const object_id a, int delta ) { return object_id( uint64_t(a.instance.value+delta) ); }

      operator object_id_type()const { return object_id_type( SpaceID, TypeID, instance.value ); }
      explicit operator uint64_t()const { return object_id_type( *this ).number; }

      template<typename DB>
      auto operator()(const DB& db)const -> const decltype(db.get(*this))& { return db.get(*this); }

      friend bool  operator == ( const object_id& a, const object_id& b ) { return a.instance == b.instance; }
      friend bool  operator != ( const object_id& a, const object_id& b ) { return a.instance != b.instance; }
      friend bool  operator == ( const object_id_type& a, const object_id& b ) { return a == object_id_type(b); }
      friend bool  operator != ( const object_id_type& a, const object_id& b ) { return a != object_id_type(b); }
      friend bool  operator == ( const object_id& a, const object_id_type& b ) { return object_id_type(a) == b; }
      friend bool  operator != ( const object_id& a, const object_id_type& b ) { return object_id_type(a) != b; }
      friend bool  operator == ( const object_id& a, const fc::unsigned_int& b ) { return a.instance == b; }
      friend bool  operator != ( const object_id& a, const fc::unsigned_int& b ) { return a.instance != b; }
      friend bool  operator == ( const fc::unsigned_int& a, const object_id& b ) { return a == b.instance; }
      friend bool  operator != ( const fc::unsigned_int& a, const object_id& b ) { return a != b.instance; }

      friend bool  operator < ( const object_id& a, const object_id& b ) { return a.instance.value < b.instance.value; }
      friend bool  operator > ( const object_id& a, const object_id& b ) { return a.instance.value > b.instance.value; }

      friend size_t hash_value( object_id v ) { return std::hash<uint64_t>()(v.instance.value); }

      unsigned_int instance;
   };

} } // graphene::db

FC_REFLECT( graphene::db::object_id_type, (number) )

// REFLECT object_id manually because it has 2 template params
namespace fc {
template<uint8_t SpaceID, uint8_t TypeID>
struct get_typename<graphene::db::object_id<SpaceID,TypeID>>
{
   static const char* name() {
      return typeid(get_typename).name();
      static std::string _str = string("graphene::db::object_id<")+fc::to_string(SpaceID) + ":" + fc::to_string(TypeID)+">";
      return _str.c_str();
   }
};

template<uint8_t SpaceID, uint8_t TypeID>
struct reflector<graphene::db::object_id<SpaceID,TypeID> >
{
    typedef graphene::db::object_id<SpaceID,TypeID> type;
    typedef fc::true_type  is_defined;
    typedef fc::false_type is_enum;
    enum  member_count_enum {
      local_member_count = 1,
      total_member_count = 1
    };
    template<typename Visitor>
    static inline void visit( const Visitor& visitor )
    {
       typedef decltype(((type*)nullptr)->instance) member_type;
       visitor.TEMPLATE operator()<member_type,type,&type::instance>( "instance" );
    }
};

 inline void to_variant( const graphene::db::object_id_type& var,  fc::variant& vo, uint32_t max_depth = 1 )
 {
    vo = std::string( var );
 }

 inline void from_variant( const fc::variant& var,  graphene::db::object_id_type& vo, uint32_t max_depth = 1 )
 { try {
    vo.number = 0;
    const auto& s = var.get_string();
    auto first_dot = s.find('.');
    auto second_dot = s.find('.',first_dot+1);
    FC_ASSERT( first_dot != second_dot );
    FC_ASSERT( first_dot != 0 && first_dot != std::string::npos );
    vo.number = fc::to_uint64(s.substr( second_dot+1 ));
    FC_ASSERT( vo.number <= GRAPHENE_DB_MAX_INSTANCE_ID );
    auto space_id = fc::to_uint64( s.substr( 0, first_dot ) );
    FC_ASSERT( space_id <= 0xff );
    auto type_id =  fc::to_uint64( s.substr( first_dot+1, second_dot-first_dot-1 ) );
    FC_ASSERT( type_id <= 0xff );
    vo.number |= (space_id << 56) | (type_id << 48);
 } FC_CAPTURE_AND_RETHROW( (var) ) }
 template<uint8_t SpaceID, uint8_t TypeID>
 void to_variant( const graphene::db::object_id<SpaceID,TypeID>& var,  fc::variant& vo, uint32_t max_depth = 1 )
 {
    vo = fc::to_string(SpaceID) + "." + fc::to_string(TypeID) + "." + fc::to_string(var.instance.value);
 }
 template<uint8_t SpaceID, uint8_t TypeID>
 void from_variant( const fc::variant& var,  graphene::db::object_id<SpaceID,TypeID>& vo, uint32_t max_depth = 1 )
 { try {
    const auto& s = var.get_string();
    auto first_dot = s.find('.');
    auto second_dot = s.find('.',first_dot+1);
    FC_ASSERT( first_dot != second_dot );
    FC_ASSERT( first_dot != 0 && first_dot != std::string::npos );
    FC_ASSERT( fc::to_uint64( s.substr( 0, first_dot ) ) == SpaceID &&
               fc::to_uint64( s.substr( first_dot+1, second_dot-first_dot-1 ) ) == TypeID,
               "Space.Type.0 (${SpaceID}.${TypeID}.0) doesn't match expected value ${var}", ("TypeID",TypeID)("SpaceID",SpaceID)("var",var) );
    vo.instance = fc::to_uint64(s.substr( second_dot+1 ));
 } FC_CAPTURE_AND_RETHROW( (var) ) }

} // namespace fc

namespace std {
     template <> struct hash<graphene::db::object_id_type>
     {
          size_t operator()(const graphene::db::object_id_type& x) const
          {
              return std::hash<uint64_t>()(x.number);
          }
     };
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMFormatterWalker.hpp"

// Xerces header files...
#include <xercesc/dom/DOMElement.hpp>

#include <PlatformSupport/AttributeListImpl.hpp>
#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/FormatterListener.hpp>

#include <XercesParserLiaison/XercesNamedNodeMapAttributeList.hpp>

XALAN_CPP_NAMESPACE_BEGIN

XercesDOMFormatterWalker::XercesDOMFormatterWalker(FormatterListener& 	formatterListener) :
	XercesDOMWalker(),
	m_formatterListener(formatterListener)
{
}

XercesDOMFormatterWalker::~XercesDOMFormatterWalker()
{
}

void
XercesDOMFormatterWalker::startNode(const DOMNodeType*	node)
{
	assert(node != 0);

	switch(node->getNodeType())
	{
	case DOMNodeType::COMMENT_NODE:
		{
			m_formatterListener.comment(node->getNodeValue());
		}
		break;

	case DOMNodeType::DOCUMENT_FRAGMENT_NODE:
		// ??
		break;

	case DOMNodeType::DOCUMENT_NODE:
		m_formatterListener.startDocument();
		break;

	case DOMNodeType::ELEMENT_NODE:
		{
			const DOMElementType* const		theElementNode =
#if defined(XALAN_OLD_STYLE_CASTS)
				(const DOMElementType*)node;
#else
				static_cast<const DOMElementType*>(node);
#endif

			const DOMNamedNodeMapType* const	atts = theElementNode->getAttributes();
			assert(atts != 0);

			XercesNamedNodeMapAttributeList		theAttributeList(atts);

			m_formatterListener.startElement(
					theElementNode->getNodeName(),
					theAttributeList);
		}
		break;

	case DOMNodeType::PROCESSING_INSTRUCTION_NODE:
		{
			m_formatterListener.processingInstruction(
					node->getNodeName(),
					node->getNodeValue());
		}
		break;

	case DOMNodeType::CDATA_SECTION_NODE:
		{
			const XMLCh* const	data = node->getNodeValue();

			assert(length(data) == FormatterListener::size_type(length(data)));

			m_formatterListener.cdata(data, FormatterListener::size_type(length(data)));
		}
		break;

	case DOMNodeType::TEXT_NODE:
		{
			const XMLCh* const	data = node->getNodeValue();

			assert(length(data) == FormatterListener::size_type(length(data)));

			m_formatterListener.characters(data, FormatterListener::size_type(length(data)));
		}
		break;

	case DOMNodeType::ENTITY_REFERENCE_NODE:
		m_formatterListener.entityReference(node->getNodeName());
		break;

	default:
		// Do nothing...
		break;
	}
}

void
XercesDOMFormatterWalker::endNode(const DOMNodeType*	node)
{
	assert(node != 0);

	switch(node->getNodeType())
	{
	case DOMNodeType::DOCUMENT_NODE:
		m_formatterListener.endDocument();
		break;

	case DOMNodeType::ELEMENT_NODE:
		m_formatterListener.endElement(node->getNodeName());
		break;

	default:
		// Do nothing
		break;
	}
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Fixed include glitch.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMFormatterWalker.hpp"

// Xerces header files...
#include <xercesc/dom/DOMElement.hpp>

#include <PlatformSupport/AttributeListImpl.hpp>
#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/FormatterListener.hpp>

#include "XercesNamedNodeMapAttributeList.hpp"

XALAN_CPP_NAMESPACE_BEGIN

XercesDOMFormatterWalker::XercesDOMFormatterWalker(FormatterListener& 	formatterListener) :
	XercesDOMWalker(),
	m_formatterListener(formatterListener)
{
}

XercesDOMFormatterWalker::~XercesDOMFormatterWalker()
{
}

void
XercesDOMFormatterWalker::startNode(const DOMNodeType*	node)
{
	assert(node != 0);

	switch(node->getNodeType())
	{
	case DOMNodeType::COMMENT_NODE:
		{
			m_formatterListener.comment(node->getNodeValue());
		}
		break;

	case DOMNodeType::DOCUMENT_FRAGMENT_NODE:
		// ??
		break;

	case DOMNodeType::DOCUMENT_NODE:
		m_formatterListener.startDocument();
		break;

	case DOMNodeType::ELEMENT_NODE:
		{
			const DOMElementType* const		theElementNode =
#if defined(XALAN_OLD_STYLE_CASTS)
				(const DOMElementType*)node;
#else
				static_cast<const DOMElementType*>(node);
#endif

			const DOMNamedNodeMapType* const	atts = theElementNode->getAttributes();
			assert(atts != 0);

			XercesNamedNodeMapAttributeList		theAttributeList(atts);

			m_formatterListener.startElement(
					theElementNode->getNodeName(),
					theAttributeList);
		}
		break;

	case DOMNodeType::PROCESSING_INSTRUCTION_NODE:
		{
			m_formatterListener.processingInstruction(
					node->getNodeName(),
					node->getNodeValue());
		}
		break;

	case DOMNodeType::CDATA_SECTION_NODE:
		{
			const XMLCh* const	data = node->getNodeValue();

			assert(length(data) == FormatterListener::size_type(length(data)));

			m_formatterListener.cdata(data, FormatterListener::size_type(length(data)));
		}
		break;

	case DOMNodeType::TEXT_NODE:
		{
			const XMLCh* const	data = node->getNodeValue();

			assert(length(data) == FormatterListener::size_type(length(data)));

			m_formatterListener.characters(data, FormatterListener::size_type(length(data)));
		}
		break;

	case DOMNodeType::ENTITY_REFERENCE_NODE:
		m_formatterListener.entityReference(node->getNodeName());
		break;

	default:
		// Do nothing...
		break;
	}
}

void
XercesDOMFormatterWalker::endNode(const DOMNodeType*	node)
{
	assert(node != 0);

	switch(node->getNodeType())
	{
	case DOMNodeType::DOCUMENT_NODE:
		m_formatterListener.endDocument();
		break;

	case DOMNodeType::ELEMENT_NODE:
		m_formatterListener.endElement(node->getNodeName());
		break;

	default:
		// Do nothing
		break;
	}
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "Frame.h"
#include "PageGroupLoadDeferrer.h"
#include "v8_proxy.h"
#include <wtf/HashSet.h>
#undef LOG

#include "base/string_util.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
#include "webkit/glue/webview_impl.h"

#if USE(V8)
#include "v8/include/v8-debug.h"
#endif

WebDevToolsAgent::MessageLoopDispatchHandler
    DebuggerAgentManager::message_loop_dispatch_handler_ = NULL;

// static
bool DebuggerAgentManager::in_host_dispatch_handler_ = false;

// static
DebuggerAgentManager::DeferrersMap DebuggerAgentManager::page_deferrers_;

namespace {

class CallerIdWrapper : public v8::Debug::ClientData {
 public:
  CallerIdWrapper() : caller_is_mananager_(true), caller_id_(0) {}
  explicit CallerIdWrapper(int caller_id)
    : caller_is_mananager_(false),
      caller_id_(caller_id) {}
  ~CallerIdWrapper() {}
  bool caller_is_mananager() const { return caller_is_mananager_; }
  int caller_id() const { return caller_id_; }
 private:
  bool caller_is_mananager_;
  int caller_id_;
  DISALLOW_COPY_AND_ASSIGN(CallerIdWrapper);
};

}  // namespace

void DebuggerAgentManager::V8DebugHostDispatchHandler() {
  if (!DebuggerAgentManager::message_loop_dispatch_handler_ ||
      !attached_agents_map_) {
    return;
  }
  if (in_host_dispatch_handler_) {
    return;
  }
  in_host_dispatch_handler_ = true;

  Vector<WebViewImpl*> views;
  // 1. Disable active objects and input events.
  for (AttachedAgentsMap::iterator it = attached_agents_map_->begin();
       it != attached_agents_map_->end();
       ++it) {
    DebuggerAgentImpl* agent = it->second;
    page_deferrers_.set(
        agent->web_view(),
        new WebCore::PageGroupLoadDeferrer(agent->GetPage(), true));
    views.append(agent->web_view());
    agent->web_view()->SetIgnoreInputEvents(true);
  }

  // 2. Process messages.
  DebuggerAgentManager::message_loop_dispatch_handler_();

  // 3. Bring things back.
  for (Vector<WebViewImpl*>::iterator it = views.begin();
       it != views.end();
       ++it) {
    if (page_deferrers_.contains(*it)) {
      // The view was not closed during the dispatch.
      (*it)->SetIgnoreInputEvents(false);
    }
  }
  deleteAllValues(page_deferrers_);
  page_deferrers_.clear();

  in_host_dispatch_handler_ = false;
  if (!attached_agents_map_) {
    // Remove handlers if all agents were detached within host dispatch.
    v8::Debug::SetMessageHandler(NULL);
    v8::Debug::SetHostDispatchHandler(NULL);
  }
}

// static
DebuggerAgentManager::AttachedAgentsMap*
    DebuggerAgentManager::attached_agents_map_ = NULL;

// static
void DebuggerAgentManager::DebugAttach(DebuggerAgentImpl* debugger_agent) {
  if (!attached_agents_map_) {
    attached_agents_map_ = new AttachedAgentsMap();
    v8::Debug::SetMessageHandler2(&DebuggerAgentManager::OnV8DebugMessage);
    v8::Debug::SetHostDispatchHandler(
        &DebuggerAgentManager::V8DebugHostDispatchHandler, 100 /* ms */);
  }
  int host_id = debugger_agent->webdevtools_agent()->host_id();
  DCHECK(host_id != 0);
  attached_agents_map_->set(host_id, debugger_agent);
}

// static
void DebuggerAgentManager::DebugDetach(DebuggerAgentImpl* debugger_agent) {
  if (!attached_agents_map_) {
    NOTREACHED();
    return;
  }
  int host_id = debugger_agent->webdevtools_agent()->host_id();
  DCHECK(attached_agents_map_->get(host_id) == debugger_agent);
  attached_agents_map_->remove(host_id);

  if (attached_agents_map_->isEmpty()) {
    delete attached_agents_map_;
    attached_agents_map_ = NULL;
    // Note that we do not empty handlers while in dispatch - we schedule
    // continue and do removal once we are out of the dispatch.
    if (!in_host_dispatch_handler_) {
      v8::Debug::SetMessageHandler2(NULL);
      v8::Debug::SetHostDispatchHandler(NULL);
    } else if (FindAgentForCurrentV8Context() == debugger_agent) {
      // Force continue just in case to handle close while on a breakpoint.
      SendContinueCommandToV8();
    }
  }
}

// static
void DebuggerAgentManager::DebugBreak(DebuggerAgentImpl* debugger_agent) {
#if USE(V8)
  DCHECK(DebuggerAgentForHostId(debugger_agent->webdevtools_agent()->host_id())
             == debugger_agent);
  v8::Debug::DebugBreak();
#endif
}

// static
void DebuggerAgentManager::OnV8DebugMessage(const v8::Debug::Message& message) {
  v8::HandleScope scope;
  v8::String::Utf8Value value(message.GetJSON());
  std::string out(*value, value.length());

  // If caller_data is not NULL the message is a response to a debugger command.
  if (v8::Debug::ClientData* caller_data = message.GetClientData()) {
    CallerIdWrapper* wrapper = static_cast<CallerIdWrapper*>(caller_data);
    if (wrapper->caller_is_mananager()) {
      // Just ignore messages sent by this manager.
      return;
    }
    DebuggerAgentImpl* debugger_agent =
        DebuggerAgentForHostId(wrapper->caller_id());
    if (debugger_agent) {
      debugger_agent->DebuggerOutput(out);
    } else if (!message.WillStartRunning()) {
      // Autocontinue execution if there is no handler.
      SendContinueCommandToV8();
    }
    return;
  } // Otherwise it's an event message.
  DCHECK(message.IsEvent());

  v8::Handle<v8::Context> context = message.GetEventContext();
  // If the context is from one of the inpected tabs it must have host_id in
  // the data field. See DebuggerAgentManager::SetHostId for more details.
  if (context.IsEmpty() || !context->GetData()->IsInt32()) {
    // Unknown context, skip the event.
    return;
  }
  int host_id = context->GetData()->Int32Value();
  DebuggerAgentImpl* agent = DebuggerAgentForHostId(host_id);
  if (agent) {
    agent->DebuggerOutput(out);
  } else if (!message.WillStartRunning()) {
    // Autocontinue execution on break and exception  events if there is no
    // handler.
    SendContinueCommandToV8();
  }
}

// static
void DebuggerAgentManager::ExecuteDebuggerCommand(
    const std::string& command,
    int caller_id) {
  SendCommandToV8(UTF8ToWide(command), new CallerIdWrapper(caller_id));
}

// static
void DebuggerAgentManager::SetMessageLoopDispatchHandler(
    WebDevToolsAgent::MessageLoopDispatchHandler handler) {
  message_loop_dispatch_handler_ = handler;
}

// static
void DebuggerAgentManager::SetHostId(WebFrameImpl* webframe, int host_id) {
  WebCore::V8Proxy* proxy = WebCore::V8Proxy::retrieve(webframe->frame());
  if (!proxy || !proxy->ContextInitialized()) {
    return;
  }
  v8::HandleScope scope;
  v8::Handle<v8::Context> context = proxy->GetContext();
  if (context.IsEmpty() || !context->GetData()->IsUndefined()) {
    return;
  }
  context->SetData(v8::Integer::New(host_id));
}

// static
void DebuggerAgentManager::OnWebViewClosed(WebViewImpl* webview) {
  if (page_deferrers_.contains(webview)) {
    delete page_deferrers_.get(webview);
    page_deferrers_.remove(webview);
  }
}

// static
void DebuggerAgentManager::SendCommandToV8(const std::wstring& cmd,
                                           v8::Debug::ClientData* data) {
#if USE(V8)
  v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.data()),
                         cmd.length(),
                         data);
#endif
}

void DebuggerAgentManager::SendContinueCommandToV8() {
  std::wstring continue_cmd(
      L"{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}");
  SendCommandToV8(continue_cmd, new CallerIdWrapper());
}

// static
DebuggerAgentImpl* DebuggerAgentManager::FindAgentForCurrentV8Context() {
  if (!attached_agents_map_) {
    return NULL;
  }
  DCHECK(!attached_agents_map_->isEmpty());

  WebCore::Frame* frame = WebCore::V8Proxy::retrieveFrameForEnteredContext();
  if (!frame) {
    return NULL;
  }
  WebCore::Page* page = frame->page();
  for (AttachedAgentsMap::iterator it = attached_agents_map_->begin();
       it != attached_agents_map_->end(); ++it) {
    if (it->second->GetPage() == page) {
      return it->second;
    }
  }
  return NULL;
}

// static
DebuggerAgentImpl* DebuggerAgentManager::DebuggerAgentForHostId(int host_id) {
  if (!attached_agents_map_) {
    return NULL;
  }
  return attached_agents_map_->get(host_id);
}
<commit_msg>DevTools: only supported event types are forwarded to the client. Unsupported events may cause additional troubles. E.g. ScriptCollected event handling crashes on call to GetEventContext(this should be fixed on v8 side). Review URL: http://codereview.chromium.org/113695<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "config.h"

#include "Frame.h"
#include "PageGroupLoadDeferrer.h"
#include "v8_proxy.h"
#include <wtf/HashSet.h>
#undef LOG

#include "base/string_util.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
#include "webkit/glue/webview_impl.h"

#if USE(V8)
#include "v8/include/v8-debug.h"
#endif

WebDevToolsAgent::MessageLoopDispatchHandler
    DebuggerAgentManager::message_loop_dispatch_handler_ = NULL;

// static
bool DebuggerAgentManager::in_host_dispatch_handler_ = false;

// static
DebuggerAgentManager::DeferrersMap DebuggerAgentManager::page_deferrers_;

namespace {

class CallerIdWrapper : public v8::Debug::ClientData {
 public:
  CallerIdWrapper() : caller_is_mananager_(true), caller_id_(0) {}
  explicit CallerIdWrapper(int caller_id)
    : caller_is_mananager_(false),
      caller_id_(caller_id) {}
  ~CallerIdWrapper() {}
  bool caller_is_mananager() const { return caller_is_mananager_; }
  int caller_id() const { return caller_id_; }
 private:
  bool caller_is_mananager_;
  int caller_id_;
  DISALLOW_COPY_AND_ASSIGN(CallerIdWrapper);
};

}  // namespace

void DebuggerAgentManager::V8DebugHostDispatchHandler() {
  if (!DebuggerAgentManager::message_loop_dispatch_handler_ ||
      !attached_agents_map_) {
    return;
  }
  if (in_host_dispatch_handler_) {
    return;
  }
  in_host_dispatch_handler_ = true;

  Vector<WebViewImpl*> views;
  // 1. Disable active objects and input events.
  for (AttachedAgentsMap::iterator it = attached_agents_map_->begin();
       it != attached_agents_map_->end();
       ++it) {
    DebuggerAgentImpl* agent = it->second;
    page_deferrers_.set(
        agent->web_view(),
        new WebCore::PageGroupLoadDeferrer(agent->GetPage(), true));
    views.append(agent->web_view());
    agent->web_view()->SetIgnoreInputEvents(true);
  }

  // 2. Process messages.
  DebuggerAgentManager::message_loop_dispatch_handler_();

  // 3. Bring things back.
  for (Vector<WebViewImpl*>::iterator it = views.begin();
       it != views.end();
       ++it) {
    if (page_deferrers_.contains(*it)) {
      // The view was not closed during the dispatch.
      (*it)->SetIgnoreInputEvents(false);
    }
  }
  deleteAllValues(page_deferrers_);
  page_deferrers_.clear();

  in_host_dispatch_handler_ = false;
  if (!attached_agents_map_) {
    // Remove handlers if all agents were detached within host dispatch.
    v8::Debug::SetMessageHandler(NULL);
    v8::Debug::SetHostDispatchHandler(NULL);
  }
}

// static
DebuggerAgentManager::AttachedAgentsMap*
    DebuggerAgentManager::attached_agents_map_ = NULL;

// static
void DebuggerAgentManager::DebugAttach(DebuggerAgentImpl* debugger_agent) {
  if (!attached_agents_map_) {
    attached_agents_map_ = new AttachedAgentsMap();
    v8::Debug::SetMessageHandler2(&DebuggerAgentManager::OnV8DebugMessage);
    v8::Debug::SetHostDispatchHandler(
        &DebuggerAgentManager::V8DebugHostDispatchHandler, 100 /* ms */);
  }
  int host_id = debugger_agent->webdevtools_agent()->host_id();
  DCHECK(host_id != 0);
  attached_agents_map_->set(host_id, debugger_agent);
}

// static
void DebuggerAgentManager::DebugDetach(DebuggerAgentImpl* debugger_agent) {
  if (!attached_agents_map_) {
    NOTREACHED();
    return;
  }
  int host_id = debugger_agent->webdevtools_agent()->host_id();
  DCHECK(attached_agents_map_->get(host_id) == debugger_agent);
  attached_agents_map_->remove(host_id);

  if (attached_agents_map_->isEmpty()) {
    delete attached_agents_map_;
    attached_agents_map_ = NULL;
    // Note that we do not empty handlers while in dispatch - we schedule
    // continue and do removal once we are out of the dispatch.
    if (!in_host_dispatch_handler_) {
      v8::Debug::SetMessageHandler2(NULL);
      v8::Debug::SetHostDispatchHandler(NULL);
    } else if (FindAgentForCurrentV8Context() == debugger_agent) {
      // Force continue just in case to handle close while on a breakpoint.
      SendContinueCommandToV8();
    }
  }
}

// static
void DebuggerAgentManager::DebugBreak(DebuggerAgentImpl* debugger_agent) {
#if USE(V8)
  DCHECK(DebuggerAgentForHostId(debugger_agent->webdevtools_agent()->host_id())
             == debugger_agent);
  v8::Debug::DebugBreak();
#endif
}

// static
void DebuggerAgentManager::OnV8DebugMessage(const v8::Debug::Message& message) {
  v8::HandleScope scope;
  v8::String::Utf8Value value(message.GetJSON());
  std::string out(*value, value.length());

  // If caller_data is not NULL the message is a response to a debugger command.
  if (v8::Debug::ClientData* caller_data = message.GetClientData()) {
    CallerIdWrapper* wrapper = static_cast<CallerIdWrapper*>(caller_data);
    if (wrapper->caller_is_mananager()) {
      // Just ignore messages sent by this manager.
      return;
    }
    DebuggerAgentImpl* debugger_agent =
        DebuggerAgentForHostId(wrapper->caller_id());
    if (debugger_agent) {
      debugger_agent->DebuggerOutput(out);
    } else if (!message.WillStartRunning()) {
      // Autocontinue execution if there is no handler.
      SendContinueCommandToV8();
    }
    return;
  } // Otherwise it's an event message.
  DCHECK(message.IsEvent());

  // Ignore unsupported event types.
  if (message.GetEvent() != v8::AfterCompile &&
      message.GetEvent() != v8::Break &&
      message.GetEvent() != v8::Exception) {
    return;
  }

  v8::Handle<v8::Context> context = message.GetEventContext();
  // If the context is from one of the inpected tabs it must have host_id in
  // the data field. See DebuggerAgentManager::SetHostId for more details.
  if (context.IsEmpty() || !context->GetData()->IsInt32()) {
    // Unknown context, skip the event.
    return;
  }
  int host_id = context->GetData()->Int32Value();
  DebuggerAgentImpl* agent = DebuggerAgentForHostId(host_id);
  if (agent) {
    agent->DebuggerOutput(out);
  } else if (!message.WillStartRunning()) {
    // Autocontinue execution on break and exception  events if there is no
    // handler.
    SendContinueCommandToV8();
  }
}

// static
void DebuggerAgentManager::ExecuteDebuggerCommand(
    const std::string& command,
    int caller_id) {
  SendCommandToV8(UTF8ToWide(command), new CallerIdWrapper(caller_id));
}

// static
void DebuggerAgentManager::SetMessageLoopDispatchHandler(
    WebDevToolsAgent::MessageLoopDispatchHandler handler) {
  message_loop_dispatch_handler_ = handler;
}

// static
void DebuggerAgentManager::SetHostId(WebFrameImpl* webframe, int host_id) {
  WebCore::V8Proxy* proxy = WebCore::V8Proxy::retrieve(webframe->frame());
  if (!proxy || !proxy->ContextInitialized()) {
    return;
  }
  v8::HandleScope scope;
  v8::Handle<v8::Context> context = proxy->GetContext();
  if (context.IsEmpty() || !context->GetData()->IsUndefined()) {
    return;
  }
  context->SetData(v8::Integer::New(host_id));
}

// static
void DebuggerAgentManager::OnWebViewClosed(WebViewImpl* webview) {
  if (page_deferrers_.contains(webview)) {
    delete page_deferrers_.get(webview);
    page_deferrers_.remove(webview);
  }
}

// static
void DebuggerAgentManager::SendCommandToV8(const std::wstring& cmd,
                                           v8::Debug::ClientData* data) {
#if USE(V8)
  v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.data()),
                         cmd.length(),
                         data);
#endif
}

void DebuggerAgentManager::SendContinueCommandToV8() {
  std::wstring continue_cmd(
      L"{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}");
  SendCommandToV8(continue_cmd, new CallerIdWrapper());
}

// static
DebuggerAgentImpl* DebuggerAgentManager::FindAgentForCurrentV8Context() {
  if (!attached_agents_map_) {
    return NULL;
  }
  DCHECK(!attached_agents_map_->isEmpty());

  WebCore::Frame* frame = WebCore::V8Proxy::retrieveFrameForEnteredContext();
  if (!frame) {
    return NULL;
  }
  WebCore::Page* page = frame->page();
  for (AttachedAgentsMap::iterator it = attached_agents_map_->begin();
       it != attached_agents_map_->end(); ++it) {
    if (it->second->GetPage() == page) {
      return it->second;
    }
  }
  return NULL;
}

// static
DebuggerAgentImpl* DebuggerAgentManager::DebuggerAgentForHostId(int host_id) {
  if (!attached_agents_map_) {
    return NULL;
  }
  return attached_agents_map_->get(host_id);
}
<|endoftext|>


<commit_before>#include "helpers.hpp"
#include <string>

namespace bmrk {

BookmarkPtr createMockBookmark(
    String url, String title, Tags tags, String notes) {
	BookmarkData data;
  if (url.empty()) data.url = "http://pezzato.net";
  if (title.empty()) data.title = "Alessandro Pezzato";
  if (tags.empty()) data.tags = Tags({"foo", "bar", "zee"});
  if (notes.empty()) data.notes = "That guy who created bmrk";
  return BookmarkPtr(new Bookmark{data});
}
} /* bmrk  */
<commit_msg>fix mock bookmark<commit_after>#include "helpers.hpp"
#include <string>

namespace bmrk {

BookmarkPtr createMockBookmark(
    String url, String title, Tags tags, String notes) {
  BookmarkData data;
  data.url = url.empty() ? "http://pezzato.net" : url;
  data.title = title.empty() ? "Alessandro Pezzato" : title;
  data.tags = tags.empty() ? Tags({"foo", "bar", "zee"}) : tags;
  data.notes = notes.empty() ? "That guy who created bmrk" : notes;
  return BookmarkPtr(new Bookmark{data});
}

} /* bmrk  */
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <cstdio> // for fileno(), stdin

#ifdef WIN32
#include <io.h>      // for isatty()
#include <windows.h> // for SetStdinEcho()
#else
#include <sys/poll.h> // for StdinReady()
#include <termios.h>  // for SetStdinEcho()
#include <unistd.h>   // for SetStdinEcho(), isatty()
#endif

#include <compat/stdin.h>

// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
void SetStdinEcho(bool enable) {
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    if (!enable) {
        mode &= ~ENABLE_ECHO_INPUT;
    } else {
        mode |= ENABLE_ECHO_INPUT;
    }
    SetConsoleMode(hStdin, mode);
#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if (!enable) {
        tty.c_lflag &= ~ECHO;
    } else {
        tty.c_lflag |= ECHO;
    }
    (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}

bool StdinTerminal() {
#ifdef WIN32
    return _isatty(_fileno(stdin));
#else
    return isatty(fileno(stdin));
#endif
}

bool StdinReady() {
    if (!StdinTerminal()) {
        return true;
    }
#ifdef WIN32
    return false;
#else
    struct pollfd fds;
    fds.fd = 0; /* this is STDIN */
    fds.events = POLLIN;
    return poll(&fds, 1, 0) == 1;
#endif
}

NoechoInst::NoechoInst() {
    SetStdinEcho(false);
}
NoechoInst::~NoechoInst() {
    SetStdinEcho(true);
}
<commit_msg>build: Fix #include sys/poll.h to just poll.h (without sys/)<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <cstdio> // for fileno(), stdin

#ifdef WIN32
#include <io.h>      // for isatty()
#include <windows.h> // for SetStdinEcho()
#else
#include <poll.h>    // for StdinReady()
#include <termios.h> // for SetStdinEcho()
#include <unistd.h>  // for SetStdinEcho(), isatty()
#endif

#include <compat/stdin.h>

// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
void SetStdinEcho(bool enable) {
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    if (!enable) {
        mode &= ~ENABLE_ECHO_INPUT;
    } else {
        mode |= ENABLE_ECHO_INPUT;
    }
    SetConsoleMode(hStdin, mode);
#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if (!enable) {
        tty.c_lflag &= ~ECHO;
    } else {
        tty.c_lflag |= ECHO;
    }
    (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}

bool StdinTerminal() {
#ifdef WIN32
    return _isatty(_fileno(stdin));
#else
    return isatty(fileno(stdin));
#endif
}

bool StdinReady() {
    if (!StdinTerminal()) {
        return true;
    }
#ifdef WIN32
    return false;
#else
    struct pollfd fds;
    fds.fd = 0; /* this is STDIN */
    fds.events = POLLIN;
    return poll(&fds, 1, 0) == 1;
#endif
}

NoechoInst::NoechoInst() {
    SetStdinEcho(false);
}
NoechoInst::~NoechoInst() {
    SetStdinEcho(true);
}
<|endoftext|>