X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcontent%2Fchild%2Fchild_thread.cc;h=e38e3a5856e224eee4febc43777728d909a92000;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=5b54ee041f9b9c0198bdb90a4da2208eee7b8849;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/content/child/child_thread.cc b/src/content/child/child_thread.cc index 5b54ee0..e38e3a5 100644 --- a/src/content/child/child_thread.cc +++ b/src/content/child/child_thread.cc @@ -4,13 +4,17 @@ #include "content/child/child_thread.h" +#include + #include #include "base/allocator/allocator_extension.h" #include "base/base_switches.h" +#include "base/basictypes.h" #include "base/command_line.h" #include "base/debug/leak_annotations.h" #include "base/lazy_instance.h" +#include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/process/kill.h" #include "base/process/process_handle.h" @@ -64,6 +68,50 @@ base::LazyInstance > g_lazy_tls = // plugins), PluginThread has EnsureTerminateMessageFilter. #if defined(OS_POSIX) +// A thread delegate that waits for |duration| and then signals the process +// with SIGALRM. +class WaitAndExitDelegate : public base::PlatformThread::Delegate { + public: + explicit WaitAndExitDelegate(base::TimeDelta duration) + : duration_(duration) {} + virtual ~WaitAndExitDelegate() OVERRIDE {} + + virtual void ThreadMain() OVERRIDE { + base::PlatformThread::Sleep(duration_); + // This used to be implemented with alarm(2). Make sure to not break + // anything that requires the process being signaled. + CHECK_EQ(0, raise(SIGALRM)); + + base::PlatformThread::Sleep((base::TimeDelta::FromSeconds(10))); + // If something erroneously blocked SIGALRM, this will trigger. + NOTREACHED(); + _exit(0); + } + + private: + const base::TimeDelta duration_; + DISALLOW_COPY_AND_ASSIGN(WaitAndExitDelegate); +}; + +// This is similar to using alarm(2), except it will spawn a thread +// which will sleep for |duration| before raising SIGALRM. +bool CreateAlarmThread(base::TimeDelta duration) { + scoped_ptr delegate(new WaitAndExitDelegate(duration)); + + const bool thread_created = base::PlatformThread::CreateNonJoinable( + 0 /* stack_size */, delegate.get()); + if (!thread_created) + return false; + + // A non joinable thread has been created. The thread will either terminate + // the process or will be terminated by the process. Therefore, keep the + // delegate object alive for the lifetime of the process. + WaitAndExitDelegate* leaking_delegate = delegate.release(); + ANNOTATE_LEAKING_OBJECT_PTR(leaking_delegate); + ignore_result(leaking_delegate); + return true; +} + class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { public: // IPC::ChannelProxy::MessageFilter @@ -89,7 +137,7 @@ class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { // it 60 seconds to run exit handlers. Exit handlers may including ones // that write profile data to disk (which happens under profile collection // mode). - alarm(60); + CHECK(CreateAlarmThread(base::TimeDelta::FromSeconds(60))); #if defined(LEAK_SANITIZER) // Invoke LeakSanitizer early to avoid detecting shutdown-only leaks. If // leaks are found, the process will exit here.