mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-03 12:37:36 +01:00
Remove include/base/cef_thread_collision_warner.h which is unused and causes linker errors with CFI builds (issue #2472)
This commit is contained in:
parent
66b5dc3d55
commit
10c01ff43e
@ -26,7 +26,6 @@
|
|||||||
'include/base/cef_string16.h',
|
'include/base/cef_string16.h',
|
||||||
'include/base/cef_template_util.h',
|
'include/base/cef_template_util.h',
|
||||||
'include/base/cef_thread_checker.h',
|
'include/base/cef_thread_checker.h',
|
||||||
'include/base/cef_thread_collision_warner.h',
|
|
||||||
'include/base/cef_trace_event.h',
|
'include/base/cef_trace_event.h',
|
||||||
'include/base/cef_tuple.h',
|
'include/base/cef_tuple.h',
|
||||||
'include/base/cef_weak_ptr.h',
|
'include/base/cef_weak_ptr.h',
|
||||||
@ -115,7 +114,6 @@
|
|||||||
'libcef_dll/base/cef_ref_counted.cc',
|
'libcef_dll/base/cef_ref_counted.cc',
|
||||||
'libcef_dll/base/cef_string16.cc',
|
'libcef_dll/base/cef_string16.cc',
|
||||||
'libcef_dll/base/cef_thread_checker_impl.cc',
|
'libcef_dll/base/cef_thread_checker_impl.cc',
|
||||||
'libcef_dll/base/cef_thread_collision_warner.cc',
|
|
||||||
'libcef_dll/base/cef_weak_ptr.cc',
|
'libcef_dll/base/cef_weak_ptr.cc',
|
||||||
],
|
],
|
||||||
'libcef_dll_wrapper_sources_common': [
|
'libcef_dll_wrapper_sources_common': [
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
#include "include/base/cef_atomic_ref_count.h"
|
#include "include/base/cef_atomic_ref_count.h"
|
||||||
#include "include/base/cef_build.h"
|
#include "include/base/cef_build.h"
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
#include "include/base/cef_thread_collision_warner.h"
|
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
@ -78,10 +77,6 @@ class RefCountedBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddRef() const {
|
void AddRef() const {
|
||||||
// TODO(maruel): Add back once it doesn't assert 500 times/sec.
|
|
||||||
// Current thread books the critical section "AddRelease"
|
|
||||||
// without release it.
|
|
||||||
// DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
|
|
||||||
#if DCHECK_IS_ON()
|
#if DCHECK_IS_ON()
|
||||||
DCHECK(!in_dtor_);
|
DCHECK(!in_dtor_);
|
||||||
#endif
|
#endif
|
||||||
@ -90,10 +85,6 @@ class RefCountedBase {
|
|||||||
|
|
||||||
// Returns true if the object should self-delete.
|
// Returns true if the object should self-delete.
|
||||||
bool Release() const {
|
bool Release() const {
|
||||||
// TODO(maruel): Add back once it doesn't assert 500 times/sec.
|
|
||||||
// Current thread books the critical section "AddRelease"
|
|
||||||
// without release it.
|
|
||||||
// DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
|
|
||||||
#if DCHECK_IS_ON()
|
#if DCHECK_IS_ON()
|
||||||
DCHECK(!in_dtor_);
|
DCHECK(!in_dtor_);
|
||||||
#endif
|
#endif
|
||||||
@ -112,8 +103,6 @@ class RefCountedBase {
|
|||||||
mutable bool in_dtor_;
|
mutable bool in_dtor_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DFAKE_MUTEX(add_release_);
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
|
DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,276 +0,0 @@
|
|||||||
// Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2012
|
|
||||||
// Google Inc. 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 Google Inc. nor the name Chromium Embedded
|
|
||||||
// Framework 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 THE COPYRIGHT
|
|
||||||
// OWNER OR 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.
|
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_BASE_CEF_THREAD_COLLISION_WARNER_H_
|
|
||||||
#define CEF_INCLUDE_BASE_CEF_THREAD_COLLISION_WARNER_H_
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if defined(BASE_THREADING_THREAD_COLLISION_WARNER_H_)
|
|
||||||
// Do nothing if the Chromium header has already been included.
|
|
||||||
// This can happen in cases where Chromium code is used directly by the
|
|
||||||
// client application. When using Chromium code directly always include
|
|
||||||
// the Chromium header first to avoid type conflicts.
|
|
||||||
#elif defined(USING_CHROMIUM_INCLUDES)
|
|
||||||
// When building CEF include the Chromium header directly.
|
|
||||||
#include "base/threading/thread_collision_warner.h"
|
|
||||||
#else // !USING_CHROMIUM_INCLUDES
|
|
||||||
// The following is substantially similar to the Chromium implementation.
|
|
||||||
// If the Chromium implementation diverges the below implementation should be
|
|
||||||
// updated to match.
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "include/base/cef_atomicops.h"
|
|
||||||
#include "include/base/cef_basictypes.h"
|
|
||||||
#include "include/base/cef_build.h"
|
|
||||||
#include "include/base/cef_logging.h"
|
|
||||||
#include "include/base/cef_macros.h"
|
|
||||||
|
|
||||||
// A helper class alongside macros to be used to verify assumptions about thread
|
|
||||||
// safety of a class.
|
|
||||||
//
|
|
||||||
// Example: Queue implementation non thread-safe but still usable if clients
|
|
||||||
// are synchronized somehow.
|
|
||||||
//
|
|
||||||
// In this case the macro DFAKE_SCOPED_LOCK has to be
|
|
||||||
// used, it checks that if a thread is inside the push/pop then
|
|
||||||
// noone else is still inside the pop/push
|
|
||||||
//
|
|
||||||
// class NonThreadSafeQueue {
|
|
||||||
// public:
|
|
||||||
// ...
|
|
||||||
// void push(int) { DFAKE_SCOPED_LOCK(push_pop_); ... }
|
|
||||||
// int pop() { DFAKE_SCOPED_LOCK(push_pop_); ... }
|
|
||||||
// ...
|
|
||||||
// private:
|
|
||||||
// DFAKE_MUTEX(push_pop_);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Example: Queue implementation non thread-safe but still usable if clients
|
|
||||||
// are synchronized somehow, it calls a method to "protect" from
|
|
||||||
// a "protected" method
|
|
||||||
//
|
|
||||||
// In this case the macro DFAKE_SCOPED_RECURSIVE_LOCK
|
|
||||||
// has to be used, it checks that if a thread is inside the push/pop
|
|
||||||
// then noone else is still inside the pop/push
|
|
||||||
//
|
|
||||||
// class NonThreadSafeQueue {
|
|
||||||
// public:
|
|
||||||
// void push(int) {
|
|
||||||
// DFAKE_SCOPED_LOCK(push_pop_);
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
// int pop() {
|
|
||||||
// DFAKE_SCOPED_RECURSIVE_LOCK(push_pop_);
|
|
||||||
// bar();
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
// void bar() { DFAKE_SCOPED_RECURSIVE_LOCK(push_pop_); ... }
|
|
||||||
// ...
|
|
||||||
// private:
|
|
||||||
// DFAKE_MUTEX(push_pop_);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Example: Queue implementation not usable even if clients are synchronized,
|
|
||||||
// so only one thread in the class life cycle can use the two members
|
|
||||||
// push/pop.
|
|
||||||
//
|
|
||||||
// In this case the macro DFAKE_SCOPED_LOCK_THREAD_LOCKED pins the
|
|
||||||
// specified
|
|
||||||
// critical section the first time a thread enters push or pop, from
|
|
||||||
// that time on only that thread is allowed to execute push or pop.
|
|
||||||
//
|
|
||||||
// class NonThreadSafeQueue {
|
|
||||||
// public:
|
|
||||||
// ...
|
|
||||||
// void push(int) { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... }
|
|
||||||
// int pop() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... }
|
|
||||||
// ...
|
|
||||||
// private:
|
|
||||||
// DFAKE_MUTEX(push_pop_);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Example: Class that has to be contructed/destroyed on same thread, it has
|
|
||||||
// a "shareable" method (with external synchronization) and a not
|
|
||||||
// shareable method (even with external synchronization).
|
|
||||||
//
|
|
||||||
// In this case 3 Critical sections have to be defined
|
|
||||||
//
|
|
||||||
// class ExoticClass {
|
|
||||||
// public:
|
|
||||||
// ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }
|
|
||||||
// ~ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }
|
|
||||||
//
|
|
||||||
// void Shareable() { DFAKE_SCOPED_LOCK(shareable_section_); ... }
|
|
||||||
// void NotShareable() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... }
|
|
||||||
// ...
|
|
||||||
// private:
|
|
||||||
// DFAKE_MUTEX(ctor_dtor_);
|
|
||||||
// DFAKE_MUTEX(shareable_section_);
|
|
||||||
// };
|
|
||||||
|
|
||||||
#if DCHECK_IS_ON()
|
|
||||||
|
|
||||||
// Defines a class member that acts like a mutex. It is used only as a
|
|
||||||
// verification tool.
|
|
||||||
#define DFAKE_MUTEX(obj) mutable base::ThreadCollisionWarner obj
|
|
||||||
// Asserts the call is never called simultaneously in two threads. Used at
|
|
||||||
// member function scope.
|
|
||||||
#define DFAKE_SCOPED_LOCK(obj) \
|
|
||||||
base::ThreadCollisionWarner::ScopedCheck s_check_##obj(&obj)
|
|
||||||
// Asserts the call is never called simultaneously in two threads. Used at
|
|
||||||
// member function scope. Same as DFAKE_SCOPED_LOCK but allows recursive locks.
|
|
||||||
#define DFAKE_SCOPED_RECURSIVE_LOCK(obj) \
|
|
||||||
base::ThreadCollisionWarner::ScopedRecursiveCheck sr_check_##obj(&obj)
|
|
||||||
// Asserts the code is always executed in the same thread.
|
|
||||||
#define DFAKE_SCOPED_LOCK_THREAD_LOCKED(obj) \
|
|
||||||
base::ThreadCollisionWarner::Check check_##obj(&obj)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define DFAKE_MUTEX(obj) typedef void InternalFakeMutexType##obj
|
|
||||||
#define DFAKE_SCOPED_LOCK(obj) ((void)0)
|
|
||||||
#define DFAKE_SCOPED_RECURSIVE_LOCK(obj) ((void)0)
|
|
||||||
#define DFAKE_SCOPED_LOCK_THREAD_LOCKED(obj) ((void)0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
|
|
||||||
// The class ThreadCollisionWarner uses an Asserter to notify the collision
|
|
||||||
// AsserterBase is the interfaces and DCheckAsserter is the default asserter
|
|
||||||
// used. During the unit tests is used another class that doesn't "DCHECK"
|
|
||||||
// in case of collision (check thread_collision_warner_unittests.cc)
|
|
||||||
struct AsserterBase {
|
|
||||||
virtual ~AsserterBase() {}
|
|
||||||
virtual void warn() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DCheckAsserter : public AsserterBase {
|
|
||||||
virtual ~DCheckAsserter() {}
|
|
||||||
virtual void warn() OVERRIDE;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ThreadCollisionWarner {
|
|
||||||
public:
|
|
||||||
// The parameter asserter is there only for test purpose
|
|
||||||
explicit ThreadCollisionWarner(AsserterBase* asserter = new DCheckAsserter())
|
|
||||||
: valid_thread_id_(0), counter_(0), asserter_(asserter) {}
|
|
||||||
|
|
||||||
~ThreadCollisionWarner() { delete asserter_; }
|
|
||||||
|
|
||||||
// This class is meant to be used through the macro
|
|
||||||
// DFAKE_SCOPED_LOCK_THREAD_LOCKED
|
|
||||||
// it doesn't leave the critical section, as opposed to ScopedCheck,
|
|
||||||
// because the critical section being pinned is allowed to be used only
|
|
||||||
// from one thread
|
|
||||||
class Check {
|
|
||||||
public:
|
|
||||||
explicit Check(ThreadCollisionWarner* warner) : warner_(warner) {
|
|
||||||
warner_->EnterSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Check() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadCollisionWarner* warner_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Check);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class is meant to be used through the macro
|
|
||||||
// DFAKE_SCOPED_LOCK
|
|
||||||
class ScopedCheck {
|
|
||||||
public:
|
|
||||||
explicit ScopedCheck(ThreadCollisionWarner* warner) : warner_(warner) {
|
|
||||||
warner_->Enter();
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedCheck() { warner_->Leave(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadCollisionWarner* warner_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class is meant to be used through the macro
|
|
||||||
// DFAKE_SCOPED_RECURSIVE_LOCK
|
|
||||||
class ScopedRecursiveCheck {
|
|
||||||
public:
|
|
||||||
explicit ScopedRecursiveCheck(ThreadCollisionWarner* warner)
|
|
||||||
: warner_(warner) {
|
|
||||||
warner_->EnterSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedRecursiveCheck() { warner_->Leave(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadCollisionWarner* warner_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ScopedRecursiveCheck);
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
// This method stores the current thread identifier and does a DCHECK
|
|
||||||
// if a another thread has already done it, it is safe if same thread
|
|
||||||
// calls this multiple time (recursion allowed).
|
|
||||||
void EnterSelf();
|
|
||||||
|
|
||||||
// Same as EnterSelf but recursion is not allowed.
|
|
||||||
void Enter();
|
|
||||||
|
|
||||||
// Removes the thread_id stored in order to allow other threads to
|
|
||||||
// call EnterSelf or Enter.
|
|
||||||
void Leave();
|
|
||||||
|
|
||||||
// This stores the thread id that is inside the critical section, if the
|
|
||||||
// value is 0 then no thread is inside.
|
|
||||||
volatile subtle::Atomic32 valid_thread_id_;
|
|
||||||
|
|
||||||
// Counter to trace how many time a critical section was "pinned"
|
|
||||||
// (when allowed) in order to unpin it when counter_ reaches 0.
|
|
||||||
volatile subtle::Atomic32 counter_;
|
|
||||||
|
|
||||||
// Here only for class unit tests purpose, during the test I need to not
|
|
||||||
// DCHECK but notify the collision with something else.
|
|
||||||
AsserterBase* asserter_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ThreadCollisionWarner);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace base
|
|
||||||
|
|
||||||
#endif // !USING_CHROMIUM_INCLUDES
|
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_BASE_CEF_THREAD_COLLISION_WARNER_H_
|
|
@ -3,7 +3,6 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/base/cef_ref_counted.h"
|
#include "include/base/cef_ref_counted.h"
|
||||||
#include "include/base/cef_thread_collision_warner.h"
|
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
#include "include/base/cef_thread_collision_warner.h"
|
|
||||||
|
|
||||||
#include "include/base/cef_logging.h"
|
|
||||||
#include "include/internal/cef_thread_internal.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
|
|
||||||
void DCheckAsserter::warn() {
|
|
||||||
NOTREACHED() << "Thread Collision";
|
|
||||||
}
|
|
||||||
|
|
||||||
static subtle::Atomic32 CurrentThread() {
|
|
||||||
const cef_platform_thread_id_t current_thread_id =
|
|
||||||
cef_get_current_platform_thread_id();
|
|
||||||
// We need to get the thread id into an atomic data type. This might be a
|
|
||||||
// truncating conversion, but any loss-of-information just increases the
|
|
||||||
// chance of a fault negative, not a false positive.
|
|
||||||
const subtle::Atomic32 atomic_thread_id =
|
|
||||||
static_cast<subtle::Atomic32>(current_thread_id);
|
|
||||||
|
|
||||||
return atomic_thread_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadCollisionWarner::EnterSelf() {
|
|
||||||
// If the active thread is 0 then I'll write the current thread ID
|
|
||||||
// if two or more threads arrive here only one will succeed to
|
|
||||||
// write on valid_thread_id_ the current thread ID.
|
|
||||||
subtle::Atomic32 current_thread_id = CurrentThread();
|
|
||||||
|
|
||||||
int previous_value =
|
|
||||||
subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, 0, current_thread_id);
|
|
||||||
if (previous_value != 0 && previous_value != current_thread_id) {
|
|
||||||
// gotcha! a thread is trying to use the same class and that is
|
|
||||||
// not current thread.
|
|
||||||
asserter_->warn();
|
|
||||||
}
|
|
||||||
|
|
||||||
subtle::NoBarrier_AtomicIncrement(&counter_, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadCollisionWarner::Enter() {
|
|
||||||
subtle::Atomic32 current_thread_id = CurrentThread();
|
|
||||||
|
|
||||||
if (subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, 0,
|
|
||||||
current_thread_id) != 0) {
|
|
||||||
// gotcha! another thread is trying to use the same class.
|
|
||||||
asserter_->warn();
|
|
||||||
}
|
|
||||||
|
|
||||||
subtle::NoBarrier_AtomicIncrement(&counter_, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadCollisionWarner::Leave() {
|
|
||||||
if (subtle::Barrier_AtomicIncrement(&counter_, -1) == 0) {
|
|
||||||
subtle::NoBarrier_Store(&valid_thread_id_, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace base
|
|
Loading…
x
Reference in New Issue
Block a user