Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: remoting/host/native_messaging/log_message_handler.cc

Issue 1272833002: Pass error messages from native messaging to web-app. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added IT2Me support. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
Sergey Ulanov 2015/08/16 23:22:02 nit: remove (c)
Jamie 2015/08/17 17:32:23 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/host/native_messaging/log_message_handler.h"
6
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/string_util.h"
10 #include "base/synchronization/lock.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/tracked_objects.h"
13
14 namespace remoting {
15
16 namespace {
17 // Log message handler registration and deregistration is not thread-safe.
18 // This lock must be held in order to set or restore a log message handler,
19 // and when accessing the weak pointer to the LogMessageHandler instance.
20 base::LazyInstance<base::Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
21
22 // The singleton LogMessageHandler instance, or null if log messages are
23 // not being intercepted. It must be dereferenced and updated under a lock.
24 base::LazyInstance<base::WeakPtr<LogMessageHandler> >::Leaky
25 g_log_message_handler = LAZY_INSTANCE_INITIALIZER;
26 } // namespace
27
28 LogMessageHandler::LogMessageHandler(
29 const Delegate& delegate)
30 : delegate_(delegate),
31 suppress_logging_(false),
32 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
33 weak_ptr_factory_(this) {
34 base::AutoLock lock(g_lock.Get());
35 if (g_log_message_handler.Get()) {
36 LOG(FATAL) << "LogMessageHandler is already registered. Only one instance "
37 << "per process is allowed.";
38 }
39 previous_log_message_handler_ = logging::GetLogMessageHandler();
40 logging::SetLogMessageHandler(&LogMessageHandler::OnLogMessage);
41 g_log_message_handler.Get() = weak_ptr_factory_.GetWeakPtr();
42 }
43
44 LogMessageHandler::~LogMessageHandler() {
45 base::AutoLock lock(g_lock.Get());
46 if (logging::GetLogMessageHandler() != &LogMessageHandler::OnLogMessage) {
47 LOG(FATAL) << "LogMessageHandler is not the top-most message handler. "
48 << "Cannot unregister.";
49 }
50 logging::SetLogMessageHandler(previous_log_message_handler_);
51 g_log_message_handler.Get().reset();
52 }
53
54 bool LogMessageHandler::OnLogMessage(
Sergey Ulanov 2015/08/16 23:22:02 add //static comment to make clear that this is a
Jamie 2015/08/17 17:32:23 Done.
55 logging::LogSeverity severity, const char* file, int line,
56 size_t message_start, const std::string& str) {
57 base::AutoLock lock(g_lock.Get());
58 if (g_log_message_handler.Get()) {
Sergey Ulanov 2015/08/16 23:22:02 WeakPtr can be deferenced only on one thread, so y
Jamie 2015/08/17 17:32:23 Doesn't that introduce a race if the LogMessageHan
Sergey Ulanov 2015/08/17 21:01:16 You can still post the task using weak pointer. Po
Jamie 2015/08/17 21:23:35 Done.
59 g_log_message_handler.Get()->PostLogMessageToCorrectThread(
60 severity, file, line, message_start, str);
61 }
62 return false;
63 }
64
65 void LogMessageHandler::PostLogMessageToCorrectThread(
66 logging::LogSeverity severity, const char* file, int line,
67 size_t message_start, const std::string& str) {
Sergey Ulanov 2015/08/16 23:22:02 nit: one parameter per line please
Jamie 2015/08/17 17:32:23 Done.
68 // Don't process this message if we're already logging. This guards against
69 // an infinite loop if any code called by this class logs something. Note
70 // that this will also suppress messages logged on other threads while any
71 // message is being processed; this is an acceptable trade-off.
72 if (suppress_logging_) {
Sergey Ulanov 2015/08/16 23:22:02 I think this is necessary only on the caller threa
Jamie 2015/08/17 17:32:24 Done.
73 return;
74 }
75
76 // This method is always called under the global lock, so post a task to
77 // handle the log message, even if we're already on the correct thread.
78 // This alows the lock to be released quickly.
Sergey Ulanov 2015/08/16 23:22:02 One downside of this approach is that LOG_FATAL er
Jamie 2015/08/17 17:32:23 Done.
79 caller_task_runner_->PostTask(
80 FROM_HERE,
81 base::Bind(&LogMessageHandler::SendLogMessageToClient,
82 weak_ptr_factory_.GetWeakPtr(),
83 severity, file, line, message_start, str));
84 }
85
86 void LogMessageHandler::SendLogMessageToClient(
87 logging::LogSeverity severity, const char* file, int line,
88 size_t message_start, const std::string& str) {
89 suppress_logging_ = true;
90
91 std::string severity_string = "log";
92 switch (severity) {
93 case logging::LOG_WARNING:
94 severity_string = "warn";
95 break;
96 case logging::LOG_FATAL:
97 case logging::LOG_ERROR:
98 severity_string = "error";
99 break;
100 }
101
102 std::string message = str.c_str() + message_start;
Sergey Ulanov 2015/08/16 23:22:02 message = std.substr(message_start);
Jamie 2015/08/17 17:32:23 Done.
103 base::TrimWhitespaceASCII(message, base::TRIM_ALL, &message);
104
105 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue);
106 dictionary->SetString("type", "_debug_log");
107 dictionary->SetString("severity", severity_string);
108 dictionary->SetString("message", message);
109 dictionary->SetString("file", file);
110 dictionary->SetInteger("line", line);
111
112 delegate_.Run(dictionary.Pass());
113
114 suppress_logging_ = false;
115 }
116
117 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698