Update audio_processing module

Corresponds to upstream commit 524e9b043e7e86fd72353b987c9d5f6a1ebf83e1

Update notes:

 * Pull in third party license file

 * Replace .gypi files with BUILD.gn to keep track of what changes
   upstream

 * Bunch of new filse pulled in as dependencies

 * Won't build yet due to changes needed on top of these
This commit is contained in:
Arun Raghavan
2015-10-13 17:25:22 +05:30
parent 5ae7a5d6cd
commit 753eada3aa
324 changed files with 52533 additions and 16117 deletions

592
webrtc/base/BUILD.gn Normal file
View File

@ -0,0 +1,592 @@
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
import("//build/config/crypto.gni")
import("//build/config/ui.gni")
import("../build/webrtc.gni")
config("rtc_base_config") {
include_dirs = [
"//third_party/jsoncpp/overrides/include",
"//third_party/jsoncpp/source/include",
]
defines = [
"FEATURE_ENABLE_SSL",
"LOGGING=1",
]
if (is_posix) {
# TODO(henrike): issue 3307, make rtc_base build without disabling
# these flags.
cflags_cc = [ "-Wno-non-virtual-dtor" ]
}
}
config("rtc_base_chromium_config") {
defines = [ "NO_MAIN_THREAD_WRAPPING" ]
}
config("openssl_config") {
defines = [
"SSL_USE_OPENSSL",
"HAVE_OPENSSL_SSL_H",
]
}
config("ios_config") {
libs = [
"CFNetwork.framework",
#"Foundation.framework", # Already included in //build/config:default_libs.
"Security.framework",
"SystemConfiguration.framework",
#"UIKit.framework", # Already included in //build/config:default_libs.
]
}
config("mac_config") {
libs = [
"Cocoa.framework",
#"Foundation.framework", # Already included in //build/config:default_libs.
#"IOKit.framework", # Already included in //build/config:default_libs.
#"Security.framework", # Already included in //build/config:default_libs.
"SystemConfiguration.framework",
]
}
config("mac_x86_config") {
libs = [
#"Carbon.framework", # Already included in //build/config:default_libs.
]
}
if (is_linux && !build_with_chromium) {
# Provides the same functionality as the //crypto:platform target, which
# WebRTC cannot use as we don't sync src/crypto from Chromium.
group("linux_system_ssl") {
if (use_openssl) {
deps = [
"//third_party/boringssl",
]
}
}
}
if (rtc_build_ssl == 0) {
config("external_ssl_library") {
assert(rtc_ssl_root != "",
"You must specify rtc_ssl_root when rtc_build_ssl==0.")
include_dirs = [ rtc_ssl_root ]
}
}
# The subset of rtc_base approved for use outside of libjingle.
static_library("rtc_base_approved") {
configs += [ "..:common_config" ]
public_configs = [ "..:common_inherited_config" ]
sources = [
"atomicops.h",
"bitbuffer.cc",
"bitbuffer.h",
"buffer.cc",
"buffer.h",
"bufferqueue.cc",
"bufferqueue.h",
"bytebuffer.cc",
"bytebuffer.h",
"byteorder.h",
"checks.cc",
"checks.h",
"criticalsection.cc",
"criticalsection.h",
"event.cc",
"event.h",
"event_tracer.cc",
"event_tracer.h",
"exp_filter.cc",
"exp_filter.h",
"md5.cc",
"md5.h",
"md5digest.cc",
"md5digest.h",
"platform_file.cc",
"platform_file.h",
"platform_thread.cc",
"platform_thread.h",
"safe_conversions.h",
"safe_conversions_impl.h",
"scoped_ptr.h",
"stringencode.cc",
"stringencode.h",
"stringutils.cc",
"stringutils.h",
"systeminfo.cc",
"systeminfo.h",
"template_util.h",
"thread_annotations.h",
"thread_checker.h",
"thread_checker_impl.cc",
"thread_checker_impl.h",
"timeutils.cc",
"timeutils.h",
"trace_event.h",
]
if (!build_with_chromium) {
sources += [
"basictypes.h",
"constructormagic.h",
"logging.cc",
"logging.h",
]
}
}
static_library("rtc_base") {
cflags = []
cflags_cc = []
libs = []
deps = [
":rtc_base_approved",
]
configs += [
"..:common_config",
":rtc_base_config",
]
public_configs = [
"..:common_inherited_config",
":rtc_base_config",
]
defines = [ "LOGGING=1" ]
sources = [
"arraysize.h",
"asyncfile.cc",
"asyncfile.h",
"asyncinvoker-inl.h",
"asyncinvoker.cc",
"asyncinvoker.h",
"asyncpacketsocket.cc",
"asyncpacketsocket.h",
"asyncresolverinterface.cc",
"asyncresolverinterface.h",
"asyncsocket.cc",
"asyncsocket.h",
"asynctcpsocket.cc",
"asynctcpsocket.h",
"asyncudpsocket.cc",
"asyncudpsocket.h",
"autodetectproxy.cc",
"autodetectproxy.h",
"base64.cc",
"base64.h",
"basicdefs.h",
"common.cc",
"common.h",
"crc32.cc",
"crc32.h",
"cryptstring.cc",
"cryptstring.h",
"diskcache.cc",
"diskcache.h",
"filerotatingstream.cc",
"filerotatingstream.h",
"fileutils.cc",
"fileutils.h",
"firewallsocketserver.cc",
"firewallsocketserver.h",
"flags.cc",
"flags.h",
"format_macros.h",
"gunit_prod.h",
"helpers.cc",
"helpers.h",
"httpbase.cc",
"httpbase.h",
"httpclient.cc",
"httpclient.h",
"httpcommon-inl.h",
"httpcommon.cc",
"httpcommon.h",
"httprequest.cc",
"httprequest.h",
"iosfilesystem.mm",
"ipaddress.cc",
"ipaddress.h",
"linked_ptr.h",
"mathutils.h",
"messagedigest.cc",
"messagedigest.h",
"messagehandler.cc",
"messagehandler.h",
"messagequeue.cc",
"messagequeue.h",
"nethelpers.cc",
"nethelpers.h",
"network.cc",
"network.h",
"nullsocketserver.h",
"pathutils.cc",
"pathutils.h",
"physicalsocketserver.cc",
"physicalsocketserver.h",
"proxydetect.cc",
"proxydetect.h",
"proxyinfo.cc",
"proxyinfo.h",
"ratelimiter.cc",
"ratelimiter.h",
"ratetracker.cc",
"ratetracker.h",
"rtccertificate.cc",
"rtccertificate.h",
"scoped_autorelease_pool.h",
"scoped_autorelease_pool.mm",
"sha1.cc",
"sha1.h",
"sha1digest.cc",
"sha1digest.h",
"signalthread.cc",
"signalthread.h",
"sigslot.cc",
"sigslot.h",
"sigslotrepeater.h",
"socket.h",
"socketadapters.cc",
"socketadapters.h",
"socketaddress.cc",
"socketaddress.h",
"socketaddresspair.cc",
"socketaddresspair.h",
"socketfactory.h",
"socketpool.cc",
"socketpool.h",
"socketserver.h",
"socketstream.cc",
"socketstream.h",
"ssladapter.cc",
"ssladapter.h",
"sslfingerprint.cc",
"sslfingerprint.h",
"sslidentity.cc",
"sslidentity.h",
"sslsocketfactory.cc",
"sslsocketfactory.h",
"sslstreamadapter.cc",
"sslstreamadapter.h",
"sslstreamadapterhelper.cc",
"sslstreamadapterhelper.h",
"stream.cc",
"stream.h",
"task.cc",
"task.h",
"taskparent.cc",
"taskparent.h",
"taskrunner.cc",
"taskrunner.h",
"thread.cc",
"thread.h",
"timing.cc",
"timing.h",
"urlencode.cc",
"urlencode.h",
"worker.cc",
"worker.h",
]
if (is_posix) {
sources += [
"unixfilesystem.cc",
"unixfilesystem.h",
]
}
if (build_with_chromium) {
sources += [
"../../webrtc_overrides/webrtc/base/logging.cc",
"../../webrtc_overrides/webrtc/base/logging.h",
]
deps += [ "..:webrtc_common" ]
if (is_win) {
sources += [ "../../webrtc_overrides/webrtc/base/win32socketinit.cc" ]
}
include_dirs = [
"../../webrtc_overrides",
"../../boringssl/src/include",
]
public_configs += [ ":rtc_base_chromium_config" ]
} else {
sources += [
"bandwidthsmoother.cc",
"bandwidthsmoother.h",
"bind.h",
"bind.h.pump",
"callback.h",
"callback.h.pump",
"fileutils_mock.h",
"genericslot.h",
"genericslot.h.pump",
"httpserver.cc",
"httpserver.h",
"json.cc",
"json.h",
"logsinks.cc",
"logsinks.h",
"mathutils.h",
"multipart.cc",
"multipart.h",
"natserver.cc",
"natserver.h",
"natsocketfactory.cc",
"natsocketfactory.h",
"nattypes.cc",
"nattypes.h",
"optionsfile.cc",
"optionsfile.h",
"profiler.cc",
"profiler.h",
"proxyserver.cc",
"proxyserver.h",
"refcount.h",
"referencecountedsingletonfactory.h",
"rollingaccumulator.h",
"scoped_ref_ptr.h",
"scopedptrcollection.h",
"sec_buffer.h",
"sharedexclusivelock.cc",
"sharedexclusivelock.h",
"sslconfig.h",
"sslroots.h",
"testclient.cc",
"testclient.h",
"transformadapter.cc",
"transformadapter.h",
"versionparsing.cc",
"versionparsing.h",
"virtualsocketserver.cc",
"virtualsocketserver.h",
"window.h",
"windowpicker.h",
"windowpickerfactory.h",
]
deps += [ "..:webrtc_common" ]
if (is_posix) {
sources += [
"latebindingsymboltable.cc",
"latebindingsymboltable.cc.def",
"latebindingsymboltable.h",
"latebindingsymboltable.h.def",
"posix.cc",
"posix.h",
]
}
if (is_linux) {
sources += [
"dbus.cc",
"dbus.h",
"libdbusglibsymboltable.cc",
"libdbusglibsymboltable.h",
"linuxfdwalk.c",
"linuxfdwalk.h",
]
}
if (is_mac) {
sources += [
"macasyncsocket.cc",
"macasyncsocket.h",
"maccocoasocketserver.h",
"maccocoasocketserver.mm",
"macsocketserver.cc",
"macsocketserver.h",
"macwindowpicker.cc",
"macwindowpicker.h",
]
}
if (is_win) {
sources += [
"diskcache_win32.cc",
"diskcache_win32.h",
"win32regkey.cc",
"win32regkey.h",
"win32socketinit.cc",
"win32socketinit.h",
"win32socketserver.cc",
"win32socketserver.h",
]
}
if (rtc_build_json) {
deps += [ "//third_party/jsoncpp" ]
} else {
include_dirs += [ rtc_jsoncpp_root ]
# When defined changes the include path for json.h to where it is
# expected to be when building json outside of the standalone build.
defines += [ "WEBRTC_EXTERNAL_JSON" ]
}
} # !build_with_chromium
# TODO(henrike): issue 3307, make rtc_base build with the Chromium default
# compiler settings.
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
if (!is_win) {
cflags += [ "-Wno-uninitialized" ]
cflags_cc += [ "-Wno-non-virtual-dtor" ]
}
if (use_openssl) {
public_configs += [ ":openssl_config" ]
if (rtc_build_ssl) {
deps += [ "//third_party/boringssl" ]
} else {
configs += [ "external_ssl_library" ]
}
sources += [
"openssl.h",
"openssladapter.cc",
"openssladapter.h",
"openssldigest.cc",
"openssldigest.h",
"opensslidentity.cc",
"opensslidentity.h",
"opensslstreamadapter.cc",
"opensslstreamadapter.h",
]
}
if (is_android) {
sources += [
"ifaddrs-android.cc",
"ifaddrs-android.h",
]
libs += [
"log",
"GLESv2",
]
}
if (is_ios) {
all_dependent_configs = [ ":ios_config" ]
sources += [
"macconversion.cc",
"macconversion.h",
]
}
if (use_x11) {
sources += [
"x11windowpicker.cc",
"x11windowpicker.h",
]
libs += [
"dl",
"rt",
"Xext",
"X11",
"Xcomposite",
"Xrender",
]
}
if (is_linux) {
libs += [
"dl",
"rt",
]
}
if (is_mac) {
sources += [
"maccocoathreadhelper.h",
"maccocoathreadhelper.mm",
"macconversion.cc",
"macconversion.h",
"macutils.cc",
"macutils.h",
]
all_dependent_configs = [ ":mac_config" ]
if (current_cpu == "x86") {
all_dependent_configs += [ ":mac_x86_config" ]
}
}
if (is_win) {
sources += [
"win32.cc",
"win32.h",
"win32filesystem.cc",
"win32filesystem.h",
"win32securityerrors.cc",
"win32window.cc",
"win32window.h",
"win32windowpicker.cc",
"win32windowpicker.h",
"winfirewall.cc",
"winfirewall.h",
"winping.cc",
"winping.h",
]
libs += [
"crypt32.lib",
"iphlpapi.lib",
"secur32.lib",
]
cflags += [
# Suppress warnings about WIN32_LEAN_AND_MEAN.
"/wd4005",
"/wd4703",
]
defines += [ "_CRT_NONSTDC_NO_DEPRECATE" ]
}
if (is_posix && is_debug) {
# The Chromium build/common.gypi defines this for all posix
# _except_ for ios & mac. We want it there as well, e.g.
# because ASSERT and friends trigger off of it.
defines += [ "_DEBUG" ]
}
if (is_ios || (is_mac && current_cpu != "x86")) {
defines += [ "CARBON_DEPRECATED=YES" ]
}
if (is_linux || is_android) {
sources += [
"linux.cc",
"linux.h",
]
}
if (is_nacl) {
deps += [ "//native_client_sdk/src/libraries/nacl_io" ]
defines += [ "timezone=_timezone" ]
}
}

27
webrtc/base/Makefile.am Normal file
View File

@ -0,0 +1,27 @@
noinst_LTLIBRARIES = libbase.la
noinst_HEADERS = arraysize.h \
basictypes.h \
checks.h \
constructormagic.h \
safe_conversions.h \
safe_conversions_impl.h \
scoped_ptr.h \
template_util.h \
thread_annotations.h
libbase_la_SOURCES = criticalsection.cc \
criticalsection.h \
event.cc \
event.h \
platform_thread.cc \
platform_thread.h \
platform_file.cc \
platform_file.h \
stringutils.cc \
stringutils.h \
thread_checker.h \
thread_checker_impl.cc \
thread_checker_impl.h
libbase_la_CXXFLAGS = $(AM_CXXFLAGS) $(COMMON_CXXFLAGS)

31
webrtc/base/arraysize.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_ARRAYSIZE_H_
#define WEBRTC_BASE_ARRAYSIZE_H_
#include <stddef.h>
// This file defines the arraysize() macro and is derived from Chromium's
// base/macros.h.
// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
#endif // WEBRTC_BASE_ARRAYSIZE_H_

68
webrtc/base/atomicops.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright 2011 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_ATOMICOPS_H_
#define WEBRTC_BASE_ATOMICOPS_H_
#if defined(WEBRTC_WIN)
// Include winsock2.h before including <windows.h> to maintain consistency with
// win32.h. We can't include win32.h directly here since it pulls in
// headers such as basictypes.h which causes problems in Chromium where webrtc
// exists as two separate projects, webrtc and libjingle.
#include <winsock2.h>
#include <windows.h>
#endif // defined(WEBRTC_WIN)
namespace rtc {
class AtomicOps {
public:
#if defined(WEBRTC_WIN)
// Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
static int Increment(volatile int* i) {
return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
}
static int Decrement(volatile int* i) {
return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
}
static int AcquireLoad(volatile const int* i) {
return *i;
}
static void ReleaseStore(volatile int* i, int value) {
*i = value;
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
new_value,
old_value);
}
#else
static int Increment(volatile int* i) {
return __sync_add_and_fetch(i, 1);
}
static int Decrement(volatile int* i) {
return __sync_sub_and_fetch(i, 1);
}
static int AcquireLoad(volatile const int* i) {
return __atomic_load_n(i, __ATOMIC_ACQUIRE);
}
static void ReleaseStore(volatile int* i, int value) {
__atomic_store_n(i, value, __ATOMIC_RELEASE);
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return __sync_val_compare_and_swap(i, old_value, new_value);
}
#endif
};
}
#endif // WEBRTC_BASE_ATOMICOPS_H_

74
webrtc/base/basictypes.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_BASICTYPES_H_
#define WEBRTC_BASE_BASICTYPES_H_
#include <stddef.h> // for NULL, size_t
#include <stdint.h> // for uintptr_t and (u)int_t types.
#ifdef HAVE_CONFIG_H
#include "config.h" // NOLINT
#endif
// Detect compiler is for x86 or x64.
#if defined(__x86_64__) || defined(_M_X64) || \
defined(__i386__) || defined(_M_IX86)
#define CPU_X86 1
#endif
// Detect compiler is for arm.
#if defined(__arm__) || defined(_M_ARM)
#define CPU_ARM 1
#endif
#if defined(CPU_X86) && defined(CPU_ARM)
#error CPU_X86 and CPU_ARM both defined.
#endif
#if !defined(RTC_ARCH_CPU_BIG_ENDIAN) && !defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
// x86, arm or GCC provided __BYTE_ORDER__ macros
#if CPU_X86 || CPU_ARM || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define RTC_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define RTC_ARCH_CPU_BIG_ENDIAN
#else
#error RTC_ARCH_CPU_BIG_ENDIAN or RTC_ARCH_CPU_LITTLE_ENDIAN should be defined.
#endif
#endif
#if defined(RTC_ARCH_CPU_BIG_ENDIAN) && defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
#error RTC_ARCH_CPU_BIG_ENDIAN and RTC_ARCH_CPU_LITTLE_ENDIAN both defined.
#endif
#if defined(WEBRTC_WIN)
typedef int socklen_t;
#endif
// The following only works for C++
#ifdef __cplusplus
#ifndef ALIGNP
#define ALIGNP(p, t) \
(reinterpret_cast<uint8_t*>(((reinterpret_cast<uintptr_t>(p) + \
((t) - 1)) & ~((t) - 1))))
#endif
#define RTC_IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
// Use these to declare and define a static local variable that gets leaked so
// that its destructors are not called at exit.
#define RTC_DEFINE_STATIC_LOCAL(type, name, arguments) \
static type& name = *new type arguments
#endif // __cplusplus
#endif // WEBRTC_BASE_BASICTYPES_H_

View File

@ -0,0 +1,169 @@
/*
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/checks.h"
namespace rtc {
CriticalSection::CriticalSection() {
#if defined(WEBRTC_WIN)
InitializeCriticalSection(&crit_);
#else
pthread_mutexattr_t mutex_attribute;
pthread_mutexattr_init(&mutex_attribute);
pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex_, &mutex_attribute);
pthread_mutexattr_destroy(&mutex_attribute);
CS_DEBUG_CODE(thread_ = 0);
CS_DEBUG_CODE(recursion_count_ = 0);
#endif
}
CriticalSection::~CriticalSection() {
#if defined(WEBRTC_WIN)
DeleteCriticalSection(&crit_);
#else
pthread_mutex_destroy(&mutex_);
#endif
}
void CriticalSection::Enter() EXCLUSIVE_LOCK_FUNCTION() {
#if defined(WEBRTC_WIN)
EnterCriticalSection(&crit_);
#else
pthread_mutex_lock(&mutex_);
#if CS_DEBUG_CHECKS
if (!recursion_count_) {
RTC_DCHECK(!thread_);
thread_ = pthread_self();
} else {
RTC_DCHECK(CurrentThreadIsOwner());
}
++recursion_count_;
#endif
#endif
}
bool CriticalSection::TryEnter() EXCLUSIVE_TRYLOCK_FUNCTION(true) {
#if defined(WEBRTC_WIN)
return TryEnterCriticalSection(&crit_) != FALSE;
#else
if (pthread_mutex_trylock(&mutex_) != 0)
return false;
#if CS_DEBUG_CHECKS
if (!recursion_count_) {
RTC_DCHECK(!thread_);
thread_ = pthread_self();
} else {
RTC_DCHECK(CurrentThreadIsOwner());
}
++recursion_count_;
#endif
return true;
#endif
}
void CriticalSection::Leave() UNLOCK_FUNCTION() {
RTC_DCHECK(CurrentThreadIsOwner());
#if defined(WEBRTC_WIN)
LeaveCriticalSection(&crit_);
#else
#if CS_DEBUG_CHECKS
--recursion_count_;
RTC_DCHECK(recursion_count_ >= 0);
if (!recursion_count_)
thread_ = 0;
#endif
pthread_mutex_unlock(&mutex_);
#endif
}
bool CriticalSection::CurrentThreadIsOwner() const {
#if defined(WEBRTC_WIN)
// OwningThread has type HANDLE but actually contains the Thread ID:
// http://stackoverflow.com/questions/12675301/why-is-the-owningthread-member-of-critical-section-of-type-handle-when-it-is-de
// Converting through size_t avoids the VS 2015 warning C4312: conversion from
// 'type1' to 'type2' of greater size
return crit_.OwningThread ==
reinterpret_cast<HANDLE>(static_cast<size_t>(GetCurrentThreadId()));
#else
#if CS_DEBUG_CHECKS
return pthread_equal(thread_, pthread_self());
#else
return true;
#endif // CS_DEBUG_CHECKS
#endif
}
bool CriticalSection::IsLocked() const {
#if defined(WEBRTC_WIN)
return crit_.LockCount != -1;
#else
#if CS_DEBUG_CHECKS
return thread_ != 0;
#else
return true;
#endif
#endif
}
CritScope::CritScope(CriticalSection* cs) : cs_(cs) { cs_->Enter(); }
CritScope::~CritScope() { cs_->Leave(); }
TryCritScope::TryCritScope(CriticalSection* cs)
: cs_(cs), locked_(cs->TryEnter()) {
CS_DEBUG_CODE(lock_was_called_ = false);
}
TryCritScope::~TryCritScope() {
CS_DEBUG_CODE(RTC_DCHECK(lock_was_called_));
if (locked_)
cs_->Leave();
}
bool TryCritScope::locked() const {
CS_DEBUG_CODE(lock_was_called_ = true);
return locked_;
}
void GlobalLockPod::Lock() {
#if !defined(WEBRTC_WIN)
const struct timespec ts_null = {0};
#endif
while (AtomicOps::CompareAndSwap(&lock_acquired, 0, 1)) {
#if defined(WEBRTC_WIN)
::Sleep(0);
#else
nanosleep(&ts_null, nullptr);
#endif
}
}
void GlobalLockPod::Unlock() {
int old_value = AtomicOps::CompareAndSwap(&lock_acquired, 1, 0);
RTC_DCHECK_EQ(1, old_value) << "Unlock called without calling Lock first";
}
GlobalLock::GlobalLock() {
lock_acquired = 0;
}
GlobalLockScope::GlobalLockScope(GlobalLockPod* lock)
: lock_(lock) {
lock_->Lock();
}
GlobalLockScope::~GlobalLockScope() {
lock_->Unlock();
}
} // namespace rtc

View File

@ -0,0 +1,129 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_CRITICALSECTION_H_
#define WEBRTC_BASE_CRITICALSECTION_H_
#include "webrtc/base/atomicops.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/thread_annotations.h"
#if defined(WEBRTC_WIN)
// Include winsock2.h before including <windows.h> to maintain consistency with
// win32.h. We can't include win32.h directly here since it pulls in
// headers such as basictypes.h which causes problems in Chromium where webrtc
// exists as two separate projects, webrtc and libjingle.
#include <winsock2.h>
#include <windows.h>
#include <sal.h> // must come after windows headers.
#endif // defined(WEBRTC_WIN)
#if defined(WEBRTC_POSIX)
#include <pthread.h>
#endif
#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
#define CS_DEBUG_CHECKS 1
#endif
#if CS_DEBUG_CHECKS
#define CS_DEBUG_CODE(x) x
#else // !CS_DEBUG_CHECKS
#define CS_DEBUG_CODE(x)
#endif // !CS_DEBUG_CHECKS
namespace rtc {
class LOCKABLE CriticalSection {
public:
CriticalSection();
~CriticalSection();
void Enter() EXCLUSIVE_LOCK_FUNCTION();
bool TryEnter() EXCLUSIVE_TRYLOCK_FUNCTION(true);
void Leave() UNLOCK_FUNCTION();
// Use only for RTC_DCHECKing.
bool CurrentThreadIsOwner() const;
// Use only for RTC_DCHECKing.
bool IsLocked() const;
private:
#if defined(WEBRTC_WIN)
CRITICAL_SECTION crit_;
#elif defined(WEBRTC_POSIX)
pthread_mutex_t mutex_;
CS_DEBUG_CODE(pthread_t thread_);
CS_DEBUG_CODE(int recursion_count_);
#endif
};
// CritScope, for serializing execution through a scope.
class SCOPED_LOCKABLE CritScope {
public:
explicit CritScope(CriticalSection* cs) EXCLUSIVE_LOCK_FUNCTION(cs);
~CritScope() UNLOCK_FUNCTION();
private:
CriticalSection* const cs_;
RTC_DISALLOW_COPY_AND_ASSIGN(CritScope);
};
// Tries to lock a critical section on construction via
// CriticalSection::TryEnter, and unlocks on destruction if the
// lock was taken. Never blocks.
//
// IMPORTANT: Unlike CritScope, the lock may not be owned by this thread in
// subsequent code. Users *must* check locked() to determine if the
// lock was taken. If you're not calling locked(), you're doing it wrong!
class TryCritScope {
public:
explicit TryCritScope(CriticalSection* cs);
~TryCritScope();
#if defined(WEBRTC_WIN)
_Check_return_ bool locked() const;
#else
bool locked() const __attribute__((warn_unused_result));
#endif
private:
CriticalSection* const cs_;
const bool locked_;
CS_DEBUG_CODE(mutable bool lock_was_called_);
RTC_DISALLOW_COPY_AND_ASSIGN(TryCritScope);
};
// A POD lock used to protect global variables. Do NOT use for other purposes.
// No custom constructor or private data member should be added.
class LOCKABLE GlobalLockPod {
public:
void Lock() EXCLUSIVE_LOCK_FUNCTION();
void Unlock() UNLOCK_FUNCTION();
volatile int lock_acquired;
};
class GlobalLock : public GlobalLockPod {
public:
GlobalLock();
};
// GlobalLockScope, for serializing execution through a scope.
class SCOPED_LOCKABLE GlobalLockScope {
public:
explicit GlobalLockScope(GlobalLockPod* lock) EXCLUSIVE_LOCK_FUNCTION(lock);
~GlobalLockScope() UNLOCK_FUNCTION();
private:
GlobalLockPod* const lock_;
RTC_DISALLOW_COPY_AND_ASSIGN(GlobalLockScope);
};
} // namespace rtc
#endif // WEBRTC_BASE_CRITICALSECTION_H_

135
webrtc/base/event.cc Normal file
View File

@ -0,0 +1,135 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/event.h"
#if defined(WEBRTC_WIN)
#include <windows.h>
#elif defined(WEBRTC_POSIX)
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#else
#error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
#endif
#include "webrtc/base/checks.h"
namespace rtc {
#if defined(WEBRTC_WIN)
Event::Event(bool manual_reset, bool initially_signaled) {
event_handle_ = ::CreateEvent(NULL, // Security attributes.
manual_reset,
initially_signaled,
NULL); // Name.
RTC_CHECK(event_handle_);
}
Event::~Event() {
CloseHandle(event_handle_);
}
void Event::Set() {
SetEvent(event_handle_);
}
void Event::Reset() {
ResetEvent(event_handle_);
}
bool Event::Wait(int milliseconds) {
DWORD ms = (milliseconds == kForever) ? INFINITE : milliseconds;
return (WaitForSingleObject(event_handle_, ms) == WAIT_OBJECT_0);
}
#elif defined(WEBRTC_POSIX)
Event::Event(bool manual_reset, bool initially_signaled)
: is_manual_reset_(manual_reset),
event_status_(initially_signaled) {
RTC_CHECK(pthread_mutex_init(&event_mutex_, NULL) == 0);
RTC_CHECK(pthread_cond_init(&event_cond_, NULL) == 0);
}
Event::~Event() {
pthread_mutex_destroy(&event_mutex_);
pthread_cond_destroy(&event_cond_);
}
void Event::Set() {
pthread_mutex_lock(&event_mutex_);
event_status_ = true;
pthread_cond_broadcast(&event_cond_);
pthread_mutex_unlock(&event_mutex_);
}
void Event::Reset() {
pthread_mutex_lock(&event_mutex_);
event_status_ = false;
pthread_mutex_unlock(&event_mutex_);
}
bool Event::Wait(int milliseconds) {
pthread_mutex_lock(&event_mutex_);
int error = 0;
if (milliseconds != kForever) {
// Converting from seconds and microseconds (1e-6) plus
// milliseconds (1e-3) to seconds and nanoseconds (1e-9).
struct timespec ts;
#if HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
// Use relative time version, which tends to be more efficient for
// pthread implementations where provided (like on Android).
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
ts.tv_sec = tv.tv_sec + (milliseconds / 1000);
ts.tv_nsec = tv.tv_usec * 1000 + (milliseconds % 1000) * 1000000;
// Handle overflow.
if (ts.tv_nsec >= 1000000000) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
#endif
while (!event_status_ && error == 0) {
#if HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
error = pthread_cond_timedwait_relative_np(
&event_cond_, &event_mutex_, &ts);
#else
error = pthread_cond_timedwait(&event_cond_, &event_mutex_, &ts);
#endif
}
} else {
while (!event_status_ && error == 0)
error = pthread_cond_wait(&event_cond_, &event_mutex_);
}
// NOTE(liulk): Exactly one thread will auto-reset this event. All
// the other threads will think it's unsignaled. This seems to be
// consistent with auto-reset events in WEBRTC_WIN
if (error == 0 && !is_manual_reset_)
event_status_ = false;
pthread_mutex_unlock(&event_mutex_);
return (error == 0);
}
#endif
} // namespace rtc

53
webrtc/base/event.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_EVENT_H__
#define WEBRTC_BASE_EVENT_H__
#if defined(WEBRTC_WIN)
#include "webrtc/base/win32.h" // NOLINT: consider this a system header.
#elif defined(WEBRTC_POSIX)
#include <pthread.h>
#else
#error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
#endif
#include "webrtc/base/basictypes.h"
namespace rtc {
class Event {
public:
static const int kForever = -1;
Event(bool manual_reset, bool initially_signaled);
~Event();
void Set();
void Reset();
// Wait for the event to become signaled, for the specified number of
// |milliseconds|. To wait indefinetly, pass kForever.
bool Wait(int milliseconds);
private:
#if defined(WEBRTC_WIN)
HANDLE event_handle_;
#elif defined(WEBRTC_POSIX)
pthread_mutex_t event_mutex_;
pthread_cond_t event_cond_;
const bool is_manual_reset_;
bool event_status_;
#endif
};
} // namespace rtc
#endif // WEBRTC_BASE_EVENT_H__

View File

@ -0,0 +1,49 @@
/*
* Copyright 2014 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/platform_file.h"
#if defined(WEBRTC_WIN)
#include <io.h>
#else
#include <unistd.h>
#endif
namespace rtc {
#if defined(WEBRTC_WIN)
const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
FILE* FdopenPlatformFileForWriting(PlatformFile file) {
if (file == kInvalidPlatformFileValue)
return NULL;
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(file), 0);
if (fd < 0)
return NULL;
return _fdopen(fd, "w");
}
bool ClosePlatformFile(PlatformFile file) {
return CloseHandle(file) != 0;
}
#else
const PlatformFile kInvalidPlatformFileValue = -1;
FILE* FdopenPlatformFileForWriting(PlatformFile file) {
return fdopen(file, "w");
}
bool ClosePlatformFile(PlatformFile file) {
return close(file);
}
#endif
} // namespace rtc

View File

@ -0,0 +1,44 @@
/*
* Copyright 2014 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_PLATFORM_FILE_H_
#define WEBRTC_BASE_PLATFORM_FILE_H_
#include <stdio.h>
#if defined(WEBRTC_WIN)
#include <windows.h>
#endif
namespace rtc {
#if defined(WEBRTC_WIN)
typedef HANDLE PlatformFile;
#elif defined(WEBRTC_POSIX)
typedef int PlatformFile;
#else
#error Unsupported platform
#endif
extern const PlatformFile kInvalidPlatformFileValue;
// Associates a standard FILE stream with an existing PlatformFile.
// Note that after this function has returned a valid FILE stream,
// the PlatformFile should no longer be used.
FILE* FdopenPlatformFileForWriting(PlatformFile file);
// Closes a PlatformFile.
// Don't use ClosePlatformFile to close a file opened with FdopenPlatformFile.
// Use fclose instead.
bool ClosePlatformFile(PlatformFile file);
} // namespace rtc
#endif // WEBRTC_BASE_PLATFORM_FILE_H_

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/platform_thread.h"
#include <string.h>
#include "webrtc/base/checks.h"
#if defined(WEBRTC_LINUX)
#include <sys/prctl.h>
#include <sys/syscall.h>
#endif
namespace rtc {
PlatformThreadId CurrentThreadId() {
PlatformThreadId ret;
#if defined(WEBRTC_WIN)
ret = GetCurrentThreadId();
#elif defined(WEBRTC_POSIX)
#if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
ret = pthread_mach_thread_np(pthread_self());
#elif defined(WEBRTC_LINUX)
ret = syscall(__NR_gettid);
#elif defined(WEBRTC_ANDROID)
ret = gettid();
#else
// Default implementation for nacl and solaris.
ret = reinterpret_cast<pid_t>(pthread_self());
#endif
#endif // defined(WEBRTC_POSIX)
RTC_DCHECK(ret);
return ret;
}
PlatformThreadRef CurrentThreadRef() {
#if defined(WEBRTC_WIN)
return GetCurrentThreadId();
#elif defined(WEBRTC_POSIX)
return pthread_self();
#endif
}
bool IsThreadRefEqual(const PlatformThreadRef& a, const PlatformThreadRef& b) {
#if defined(WEBRTC_WIN)
return a == b;
#elif defined(WEBRTC_POSIX)
return pthread_equal(a, b);
#endif
}
void SetCurrentThreadName(const char* name) {
RTC_DCHECK(strlen(name) < 64);
#if defined(WEBRTC_WIN)
struct {
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
} threadname_info = {0x1000, name, static_cast<DWORD>(-1), 0};
__try {
::RaiseException(0x406D1388, 0, sizeof(threadname_info) / sizeof(DWORD),
reinterpret_cast<ULONG_PTR*>(&threadname_info));
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID)
prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name));
#elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
pthread_setname_np(name);
#endif
}
} // namespace rtc

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_PLATFORM_THREAD_H_
#define WEBRTC_BASE_PLATFORM_THREAD_H_
#if defined(WEBRTC_WIN)
#include <winsock2.h>
#include <windows.h>
#elif defined(WEBRTC_POSIX)
#include <pthread.h>
#include <unistd.h>
#endif
namespace rtc {
#if defined(WEBRTC_WIN)
typedef DWORD PlatformThreadId;
typedef DWORD PlatformThreadRef;
#elif defined(WEBRTC_POSIX)
typedef pid_t PlatformThreadId;
typedef pthread_t PlatformThreadRef;
#endif
PlatformThreadId CurrentThreadId();
PlatformThreadRef CurrentThreadRef();
// Compares two thread identifiers for equality.
bool IsThreadRefEqual(const PlatformThreadRef& a, const PlatformThreadRef& b);
// Sets the current thread name.
void SetCurrentThreadName(const char* name);
} // namespace rtc
#endif // WEBRTC_BASE_PLATFORM_THREAD_H_

View File

@ -0,0 +1,70 @@
/*
* Copyright 2014 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/numerics/safe_conversions.h.
#ifndef WEBRTC_BASE_SAFE_CONVERSIONS_H_
#define WEBRTC_BASE_SAFE_CONVERSIONS_H_
#include <limits>
#include "webrtc/base/checks.h"
#include "webrtc/base/safe_conversions_impl.h"
namespace rtc {
// Convenience function that returns true if the supplied value is in range
// for the destination type.
template <typename Dst, typename Src>
inline bool IsValueInRangeForNumericType(Src value) {
return internal::RangeCheck<Dst>(value) == internal::TYPE_VALID;
}
// checked_cast<> is analogous to static_cast<> for numeric types,
// except that it CHECKs that the specified numeric conversion will not
// overflow or underflow. NaN source will always trigger a CHECK.
template <typename Dst, typename Src>
inline Dst checked_cast(Src value) {
RTC_CHECK(IsValueInRangeForNumericType<Dst>(value));
return static_cast<Dst>(value);
}
// saturated_cast<> is analogous to static_cast<> for numeric types, except
// that the specified numeric conversion will saturate rather than overflow or
// underflow. NaN assignment to an integral will trigger a RTC_CHECK condition.
template <typename Dst, typename Src>
inline Dst saturated_cast(Src value) {
// Optimization for floating point values, which already saturate.
if (std::numeric_limits<Dst>::is_iec559)
return static_cast<Dst>(value);
switch (internal::RangeCheck<Dst>(value)) {
case internal::TYPE_VALID:
return static_cast<Dst>(value);
case internal::TYPE_UNDERFLOW:
return std::numeric_limits<Dst>::min();
case internal::TYPE_OVERFLOW:
return std::numeric_limits<Dst>::max();
// Should fail only on attempting to assign NaN to a saturated integer.
case internal::TYPE_INVALID:
FATAL();
return std::numeric_limits<Dst>::max();
}
FATAL();
return static_cast<Dst>(value);
}
} // namespace rtc
#endif // WEBRTC_BASE_SAFE_CONVERSIONS_H_

View File

@ -0,0 +1,188 @@
/*
* Copyright 2014 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/numerics/safe_conversions_impl.h.
#ifndef WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_
#define WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_
#include <limits>
namespace rtc {
namespace internal {
enum DstSign {
DST_UNSIGNED,
DST_SIGNED
};
enum SrcSign {
SRC_UNSIGNED,
SRC_SIGNED
};
enum DstRange {
OVERLAPS_RANGE,
CONTAINS_RANGE
};
// Helper templates to statically determine if our destination type can contain
// all values represented by the source type.
template <typename Dst, typename Src,
DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
SRC_SIGNED : SRC_UNSIGNED>
struct StaticRangeCheck {};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_SIGNED> {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> SrcLimits;
// Compare based on max_exponent, which we must compute for integrals.
static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
DstLimits::max_exponent :
(sizeof(Dst) * 8 - 1);
static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
SrcLimits::max_exponent :
(sizeof(Src) * 8 - 1);
static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
CONTAINS_RANGE : OVERLAPS_RANGE;
};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED> {
static const DstRange value = sizeof(Dst) >= sizeof(Src) ?
CONTAINS_RANGE : OVERLAPS_RANGE;
};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_SIGNED, SRC_UNSIGNED> {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> SrcLimits;
// Compare based on max_exponent, which we must compute for integrals.
static const size_t kDstMaxExponent = DstLimits::is_iec559 ?
DstLimits::max_exponent :
(sizeof(Dst) * 8 - 1);
static const size_t kSrcMaxExponent = sizeof(Src) * 8;
static const DstRange value = kDstMaxExponent >= kSrcMaxExponent ?
CONTAINS_RANGE : OVERLAPS_RANGE;
};
template <typename Dst, typename Src>
struct StaticRangeCheck<Dst, Src, DST_UNSIGNED, SRC_SIGNED> {
static const DstRange value = OVERLAPS_RANGE;
};
enum RangeCheckResult {
TYPE_VALID = 0, // Value can be represented by the destination type.
TYPE_UNDERFLOW = 1, // Value would overflow.
TYPE_OVERFLOW = 2, // Value would underflow.
TYPE_INVALID = 3 // Source value is invalid (i.e. NaN).
};
// This macro creates a RangeCheckResult from an upper and lower bound
// check by taking advantage of the fact that only NaN can be out of range in
// both directions at once.
#define BASE_NUMERIC_RANGE_CHECK_RESULT(is_in_upper_bound, is_in_lower_bound) \
RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \
((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW))
template <typename Dst,
typename Src,
DstSign IsDstSigned = std::numeric_limits<Dst>::is_signed ?
DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = std::numeric_limits<Src>::is_signed ?
SRC_SIGNED : SRC_UNSIGNED,
DstRange IsSrcRangeContained = StaticRangeCheck<Dst, Src>::value>
struct RangeCheckImpl {};
// The following templates are for ranges that must be verified at runtime. We
// split it into checks based on signedness to avoid confusing casts and
// compiler warnings on signed an unsigned comparisons.
// Dst range always contains the result: nothing to check.
template <typename Dst, typename Src, DstSign IsDstSigned, SrcSign IsSrcSigned>
struct RangeCheckImpl<Dst, Src, IsDstSigned, IsSrcSigned, CONTAINS_RANGE> {
static RangeCheckResult Check(Src value) {
return TYPE_VALID;
}
};
// Signed to signed narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return DstLimits::is_iec559 ?
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(DstLimits::max() * -1)) :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(DstLimits::min()));
}
};
// Unsigned to unsigned narrowing.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()), true);
}
};
// Unsigned to signed.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_SIGNED, SRC_UNSIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
return sizeof(Dst) > sizeof(Src) ? TYPE_VALID :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()), true);
}
};
// Signed to unsigned.
template <typename Dst, typename Src>
struct RangeCheckImpl<Dst, Src, DST_UNSIGNED, SRC_SIGNED, OVERLAPS_RANGE> {
static RangeCheckResult Check(Src value) {
typedef std::numeric_limits<Dst> DstLimits;
typedef std::numeric_limits<Src> SrcLimits;
// Compare based on max_exponent, which we must compute for integrals.
static const size_t kDstMaxExponent = sizeof(Dst) * 8;
static const size_t kSrcMaxExponent = SrcLimits::is_iec559 ?
SrcLimits::max_exponent :
(sizeof(Src) * 8 - 1);
return (kDstMaxExponent >= kSrcMaxExponent) ?
BASE_NUMERIC_RANGE_CHECK_RESULT(true, value >= static_cast<Src>(0)) :
BASE_NUMERIC_RANGE_CHECK_RESULT(
value <= static_cast<Src>(DstLimits::max()),
value >= static_cast<Src>(0));
}
};
template <typename Dst, typename Src>
inline RangeCheckResult RangeCheck(Src value) {
static_assert(std::numeric_limits<Src>::is_specialized,
"argument must be numeric");
static_assert(std::numeric_limits<Dst>::is_specialized,
"result must be numeric");
return RangeCheckImpl<Dst, Src>::Check(value);
}
} // namespace internal
} // namespace rtc
#endif // WEBRTC_BASE_SAFE_CONVERSIONS_IMPL_H_

133
webrtc/base/stringutils.cc Normal file
View File

@ -0,0 +1,133 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/checks.h"
#include "webrtc/base/stringutils.h"
namespace rtc {
bool memory_check(const void* memory, int c, size_t count) {
const char* char_memory = static_cast<const char*>(memory);
char char_c = static_cast<char>(c);
for (size_t i = 0; i < count; ++i) {
if (char_memory[i] != char_c) {
return false;
}
}
return true;
}
bool string_match(const char* target, const char* pattern) {
while (*pattern) {
if (*pattern == '*') {
if (!*++pattern) {
return true;
}
while (*target) {
if ((toupper(*pattern) == toupper(*target))
&& string_match(target + 1, pattern + 1)) {
return true;
}
++target;
}
return false;
} else {
if (toupper(*pattern) != toupper(*target)) {
return false;
}
++target;
++pattern;
}
}
return !*target;
}
#if defined(WEBRTC_WIN)
int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
CharacterTransformation transformation) {
wchar_t c1, c2;
while (true) {
if (n-- == 0) return 0;
c1 = transformation(*s1);
// Double check that characters are not UTF-8
RTC_DCHECK_LT(static_cast<unsigned char>(*s2), 128);
// Note: *s2 gets implicitly promoted to wchar_t
c2 = transformation(*s2);
if (c1 != c2) return (c1 < c2) ? -1 : 1;
if (!c1) return 0;
++s1;
++s2;
}
}
size_t asccpyn(wchar_t* buffer, size_t buflen,
const char* source, size_t srclen) {
if (buflen <= 0)
return 0;
if (srclen == SIZE_UNKNOWN) {
srclen = strlenn(source, buflen - 1);
} else if (srclen >= buflen) {
srclen = buflen - 1;
}
#if _DEBUG
// Double check that characters are not UTF-8
for (size_t pos = 0; pos < srclen; ++pos)
RTC_DCHECK_LT(static_cast<unsigned char>(source[pos]), 128);
#endif // _DEBUG
std::copy(source, source + srclen, buffer);
buffer[srclen] = 0;
return srclen;
}
#endif // WEBRTC_WIN
void replace_substrs(const char *search,
size_t search_len,
const char *replace,
size_t replace_len,
std::string *s) {
size_t pos = 0;
while ((pos = s->find(search, pos, search_len)) != std::string::npos) {
s->replace(pos, search_len, replace, replace_len);
pos += replace_len;
}
}
bool starts_with(const char *s1, const char *s2) {
return strncmp(s1, s2, strlen(s2)) == 0;
}
bool ends_with(const char *s1, const char *s2) {
size_t s1_length = strlen(s1);
size_t s2_length = strlen(s2);
if (s2_length > s1_length) {
return false;
}
const char* start = s1 + (s1_length - s2_length);
return strncmp(start, s2, s2_length) == 0;
}
static const char kWhitespace[] = " \n\r\t";
std::string string_trim(const std::string& s) {
std::string::size_type first = s.find_first_not_of(kWhitespace);
std::string::size_type last = s.find_last_not_of(kWhitespace);
if (first == std::string::npos || last == std::string::npos) {
return std::string("");
}
return s.substr(first, last - first + 1);
}
} // namespace rtc

318
webrtc/base/stringutils.h Normal file
View File

@ -0,0 +1,318 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_STRINGUTILS_H__
#define WEBRTC_BASE_STRINGUTILS_H__
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(WEBRTC_WIN)
#include <malloc.h>
#include <wchar.h>
#define alloca _alloca
#endif // WEBRTC_WIN
#if defined(WEBRTC_POSIX)
#ifdef BSD
#include <stdlib.h>
#else // BSD
#include <alloca.h>
#endif // !BSD
#endif // WEBRTC_POSIX
#include <string>
#include "webrtc/base/basictypes.h"
///////////////////////////////////////////////////////////////////////////////
// Generic string/memory utilities
///////////////////////////////////////////////////////////////////////////////
#define STACK_ARRAY(TYPE, LEN) static_cast<TYPE*>(::alloca((LEN)*sizeof(TYPE)))
namespace rtc {
// Complement to memset. Verifies memory consists of count bytes of value c.
bool memory_check(const void* memory, int c, size_t count);
// Determines whether the simple wildcard pattern matches target.
// Alpha characters in pattern match case-insensitively.
// Asterisks in pattern match 0 or more characters.
// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
bool string_match(const char* target, const char* pattern);
} // namespace rtc
///////////////////////////////////////////////////////////////////////////////
// Rename a bunch of common string functions so they are consistent across
// platforms and between char and wchar_t variants.
// Here is the full list of functions that are unified:
// strlen, strcmp, stricmp, strncmp, strnicmp
// strchr, vsnprintf, strtoul, tolowercase
// tolowercase is like tolower, but not compatible with end-of-file value
//
// It's not clear if we will ever use wchar_t strings on unix. In theory,
// all strings should be Utf8 all the time, except when interfacing with Win32
// APIs that require Utf16.
///////////////////////////////////////////////////////////////////////////////
inline char tolowercase(char c) {
return static_cast<char>(tolower(c));
}
#if defined(WEBRTC_WIN)
inline size_t strlen(const wchar_t* s) {
return wcslen(s);
}
inline int strcmp(const wchar_t* s1, const wchar_t* s2) {
return wcscmp(s1, s2);
}
inline int stricmp(const wchar_t* s1, const wchar_t* s2) {
return _wcsicmp(s1, s2);
}
inline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
return wcsncmp(s1, s2, n);
}
inline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
return _wcsnicmp(s1, s2, n);
}
inline const wchar_t* strchr(const wchar_t* s, wchar_t c) {
return wcschr(s, c);
}
inline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) {
return wcsstr(haystack, needle);
}
#ifndef vsnprintf
inline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) {
return _vsnwprintf(buf, n, fmt, args);
}
#endif // !vsnprintf
inline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) {
return wcstoul(snum, end, base);
}
inline wchar_t tolowercase(wchar_t c) {
return static_cast<wchar_t>(towlower(c));
}
#endif // WEBRTC_WIN
#if defined(WEBRTC_POSIX)
inline int _stricmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2);
}
inline int _strnicmp(const char* s1, const char* s2, size_t n) {
return strncasecmp(s1, s2, n);
}
#endif // WEBRTC_POSIX
///////////////////////////////////////////////////////////////////////////////
// Traits simplifies porting string functions to be CTYPE-agnostic
///////////////////////////////////////////////////////////////////////////////
namespace rtc {
const size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
template<class CTYPE>
struct Traits {
// STL string type
//typedef XXX string;
// Null-terminated string
//inline static const CTYPE* empty_str();
};
///////////////////////////////////////////////////////////////////////////////
// String utilities which work with char or wchar_t
///////////////////////////////////////////////////////////////////////////////
template<class CTYPE>
inline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) {
return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
}
template<class CTYPE>
const CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
for (size_t i=0; str[i]; ++i) {
for (size_t j=0; chs[j]; ++j) {
if (str[i] == chs[j]) {
return str + i;
}
}
}
return 0;
}
template<class CTYPE>
const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
for (size_t i=0; i<slen && str[i]; ++i) {
if (str[i] == ch) {
return str + i;
}
}
return 0;
}
template<class CTYPE>
size_t strlenn(const CTYPE* buffer, size_t buflen) {
size_t bufpos = 0;
while (buffer[bufpos] && (bufpos < buflen)) {
++bufpos;
}
return bufpos;
}
// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
// null-terminate.
template<class CTYPE>
size_t strcpyn(CTYPE* buffer, size_t buflen,
const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
if (buflen <= 0)
return 0;
if (srclen == SIZE_UNKNOWN) {
srclen = strlenn(source, buflen - 1);
} else if (srclen >= buflen) {
srclen = buflen - 1;
}
memcpy(buffer, source, srclen * sizeof(CTYPE));
buffer[srclen] = 0;
return srclen;
}
template<class CTYPE>
size_t strcatn(CTYPE* buffer, size_t buflen,
const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
if (buflen <= 0)
return 0;
size_t bufpos = strlenn(buffer, buflen - 1);
return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
}
// Some compilers (clang specifically) require vsprintfn be defined before
// sprintfn.
template<class CTYPE>
size_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format,
va_list args) {
int len = vsnprintf(buffer, buflen, format, args);
if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
len = static_cast<int>(buflen - 1);
buffer[len] = 0;
}
return len;
}
template<class CTYPE>
size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...);
template<class CTYPE>
size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) {
va_list args;
va_start(args, format);
size_t len = vsprintfn(buffer, buflen, format, args);
va_end(args);
return len;
}
///////////////////////////////////////////////////////////////////////////////
// Allow safe comparing and copying ascii (not UTF-8) with both wide and
// non-wide character strings.
///////////////////////////////////////////////////////////////////////////////
inline int asccmp(const char* s1, const char* s2) {
return strcmp(s1, s2);
}
inline int ascicmp(const char* s1, const char* s2) {
return _stricmp(s1, s2);
}
inline int ascncmp(const char* s1, const char* s2, size_t n) {
return strncmp(s1, s2, n);
}
inline int ascnicmp(const char* s1, const char* s2, size_t n) {
return _strnicmp(s1, s2, n);
}
inline size_t asccpyn(char* buffer, size_t buflen,
const char* source, size_t srclen = SIZE_UNKNOWN) {
return strcpyn(buffer, buflen, source, srclen);
}
#if defined(WEBRTC_WIN)
typedef wchar_t(*CharacterTransformation)(wchar_t);
inline wchar_t identity(wchar_t c) { return c; }
int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
CharacterTransformation transformation);
inline int asccmp(const wchar_t* s1, const char* s2) {
return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
}
inline int ascicmp(const wchar_t* s1, const char* s2) {
return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
}
inline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
return ascii_string_compare(s1, s2, n, identity);
}
inline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
return ascii_string_compare(s1, s2, n, tolowercase);
}
size_t asccpyn(wchar_t* buffer, size_t buflen,
const char* source, size_t srclen = SIZE_UNKNOWN);
#endif // WEBRTC_WIN
///////////////////////////////////////////////////////////////////////////////
// Traits<char> specializations
///////////////////////////////////////////////////////////////////////////////
template<>
struct Traits<char> {
typedef std::string string;
inline static const char* empty_str() { return ""; }
};
///////////////////////////////////////////////////////////////////////////////
// Traits<wchar_t> specializations (Windows only, currently)
///////////////////////////////////////////////////////////////////////////////
#if defined(WEBRTC_WIN)
template<>
struct Traits<wchar_t> {
typedef std::wstring string;
inline static const wchar_t* empty_str() { return L""; }
};
#endif // WEBRTC_WIN
// Replaces all occurrences of "search" with "replace".
void replace_substrs(const char *search,
size_t search_len,
const char *replace,
size_t replace_len,
std::string *s);
// True iff s1 starts with s2.
bool starts_with(const char *s1, const char *s2);
// True iff s1 ends with s2.
bool ends_with(const char *s1, const char *s2);
// Remove leading and trailing whitespaces.
std::string string_trim(const std::string& s);
} // namespace rtc
#endif // WEBRTC_BASE_STRINGUTILS_H__

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/threading/thread_checker.h.
#ifndef WEBRTC_BASE_THREAD_CHECKER_H_
#define WEBRTC_BASE_THREAD_CHECKER_H_
// Apart from debug builds, we also enable the thread checker in
// builds with DCHECK_ALWAYS_ON so that trybots and waterfall bots
// with this define will get the same level of thread checking as
// debug bots.
//
// Note that this does not perfectly match situations where RTC_DCHECK is
// enabled. For example a non-official release build may have
// DCHECK_ALWAYS_ON undefined (and therefore ThreadChecker would be
// disabled) but have RTC_DCHECKs enabled at runtime.
#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
#define ENABLE_THREAD_CHECKER 1
#else
#define ENABLE_THREAD_CHECKER 0
#endif
#include "webrtc/base/thread_checker_impl.h"
namespace rtc {
// Do nothing implementation, for use in release mode.
//
// Note: You should almost always use the ThreadChecker class to get the
// right version for your build configuration.
class ThreadCheckerDoNothing {
public:
bool CalledOnValidThread() const {
return true;
}
void DetachFromThread() {}
};
// ThreadChecker is a helper class used to help verify that some methods of a
// class are called from the same thread. It provides identical functionality to
// base::NonThreadSafe, but it is meant to be held as a member variable, rather
// than inherited from base::NonThreadSafe.
//
// While inheriting from base::NonThreadSafe may give a clear indication about
// the thread-safety of a class, it may also lead to violations of the style
// guide with regard to multiple inheritance. The choice between having a
// ThreadChecker member and inheriting from base::NonThreadSafe should be based
// on whether:
// - Derived classes need to know the thread they belong to, as opposed to
// having that functionality fully encapsulated in the base class.
// - Derived classes should be able to reassign the base class to another
// thread, via DetachFromThread.
//
// If neither of these are true, then having a ThreadChecker member and calling
// CalledOnValidThread is the preferable solution.
//
// Example:
// class MyClass {
// public:
// void Foo() {
// RTC_DCHECK(thread_checker_.CalledOnValidThread());
// ... (do stuff) ...
// }
//
// private:
// ThreadChecker thread_checker_;
// }
//
// In Release mode, CalledOnValidThread will always return true.
#if ENABLE_THREAD_CHECKER
class ThreadChecker : public ThreadCheckerImpl {
};
#else
class ThreadChecker : public ThreadCheckerDoNothing {
};
#endif // ENABLE_THREAD_CHECKER
#undef ENABLE_THREAD_CHECKER
} // namespace rtc
#endif // WEBRTC_BASE_THREAD_CHECKER_H_

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/threading/thread_checker_impl.cc.
#include "webrtc/base/thread_checker_impl.h"
namespace rtc {
ThreadCheckerImpl::ThreadCheckerImpl() : valid_thread_(CurrentThreadRef()) {
}
ThreadCheckerImpl::~ThreadCheckerImpl() {
}
bool ThreadCheckerImpl::CalledOnValidThread() const {
const PlatformThreadRef current_thread = CurrentThreadRef();
CritScope scoped_lock(&lock_);
if (!valid_thread_) // Set if previously detached.
valid_thread_ = current_thread;
return IsThreadRefEqual(valid_thread_, current_thread);
}
void ThreadCheckerImpl::DetachFromThread() {
CritScope scoped_lock(&lock_);
valid_thread_ = 0;
}
} // namespace rtc

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/threading/thread_checker_impl.h.
#ifndef WEBRTC_BASE_THREAD_CHECKER_IMPL_H_
#define WEBRTC_BASE_THREAD_CHECKER_IMPL_H_
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/platform_thread.h"
namespace rtc {
// Real implementation of ThreadChecker, for use in debug mode, or
// for temporary use in release mode (e.g. to RTC_CHECK on a threading issue
// seen only in the wild).
//
// Note: You should almost always use the ThreadChecker class to get the
// right version for your build configuration.
class ThreadCheckerImpl {
public:
ThreadCheckerImpl();
~ThreadCheckerImpl();
bool CalledOnValidThread() const;
// Changes the thread that is checked for in CalledOnValidThread. This may
// be useful when an object may be created on one thread and then used
// exclusively on another thread.
void DetachFromThread();
private:
mutable CriticalSection lock_;
// This is mutable so that CalledOnValidThread can set it.
// It's guarded by |lock_|.
mutable PlatformThreadRef valid_thread_;
};
} // namespace rtc
#endif // WEBRTC_BASE_THREAD_CHECKER_IMPL_H_