<commit_before>/*
 *  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 <signal.h>
#include <stdarg.h>

#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/socket_unittest.h"
#include "webrtc/base/testutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/test/testsupport/gtest_disable.h"

namespace rtc {

class PhysicalSocketTest : public SocketTest {
};

TEST_F(PhysicalSocketTest, TestConnectIPv4) {
  SocketTest::TestConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
#else
#define MAYBE_TestConnectIPv6 TestConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
  SocketTest::TestConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
  SocketTest::TestConnectWithDnsLookupIPv4();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
  SocketTest::TestConnectWithDnsLookupIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
  SocketTest::TestConnectFailIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
#else
#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
  SocketTest::TestConnectFailIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
  SocketTest::TestConnectWithDnsLookupFailIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
  DISABLED_TestConnectWithDnsLookupFailIPv6
#else
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
  TestConnectWithDnsLookupFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
  SocketTest::TestConnectWithDnsLookupFailIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
  SocketTest::TestConnectWithClosedSocketIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithClosedSocketIPv6 \
  DISABLED_TestConnectWithClosedSocketIPv6
#else
#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
  SocketTest::TestConnectWithClosedSocketIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
  SocketTest::TestConnectWhileNotClosedIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWhileNotClosedIPv6 \
  DISABLED_TestConnectWhileNotClosedIPv6
#else
#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
  SocketTest::TestConnectWhileNotClosedIPv6();
}

TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
  SocketTest::TestServerCloseDuringConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseDuringConnectIPv6 \
  DISABLED_TestServerCloseDuringConnectIPv6
#else
#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
  SocketTest::TestServerCloseDuringConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
  SocketTest::TestClientCloseDuringConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestClientCloseDuringConnectIPv6 \
  DISABLED_TestClientCloseDuringConnectIPv6
#else
#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
  SocketTest::TestClientCloseDuringConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
  SocketTest::TestServerCloseIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
#else
#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
  SocketTest::TestServerCloseIPv6();
}

TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
  SocketTest::TestCloseInClosedCallbackIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestCloseInClosedCallbackIPv6 \
  DISABLED_TestCloseInClosedCallbackIPv6
#else
#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
  SocketTest::TestCloseInClosedCallbackIPv6();
}

TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
  SocketTest::TestSocketServerWaitIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
#else
#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
  SocketTest::TestSocketServerWaitIPv6();
}

TEST_F(PhysicalSocketTest, TestTcpIPv4) {
  SocketTest::TestTcpIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
#else
#define MAYBE_TestTcpIPv6 TestTcpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
  SocketTest::TestTcpIPv6();
}

TEST_F(PhysicalSocketTest, TestUdpIPv4) {
  SocketTest::TestUdpIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
#else
#define MAYBE_TestUdpIPv6 TestUdpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
  SocketTest::TestUdpIPv6();
}

// Disable for TSan v2, see
// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
// Also disable for MSan, see:
// https://code.google.com/p/webrtc/issues/detail?id=4958
// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
// Also disable for ASan.
#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
  defined(ADDRESS_SANITIZER)
#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
#else
#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
  SocketTest::TestUdpReadyToSendIPv4();
}

TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
  SocketTest::TestUdpReadyToSendIPv6();
}

TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
  SocketTest::TestGetSetOptionsIPv4();
}

TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
  SocketTest::TestGetSetOptionsIPv6();
}

#if defined(WEBRTC_POSIX)

class PosixSignalDeliveryTest : public testing::Test {
 public:
  static void RecordSignal(int signum) {
    signals_received_.push_back(signum);
    signaled_thread_ = Thread::Current();
  }

 protected:
  void SetUp() {
    ss_.reset(new PhysicalSocketServer());
  }

  void TearDown() {
    ss_.reset(NULL);
    signals_received_.clear();
    signaled_thread_ = NULL;
  }

  bool ExpectSignal(int signum) {
    if (signals_received_.empty()) {
      LOG(LS_ERROR) << "ExpectSignal(): No signal received";
      return false;
    }
    if (signals_received_[0] != signum) {
      LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
          signals_received_[0] << ", expected " << signum;
      return false;
    }
    signals_received_.erase(signals_received_.begin());
    return true;
  }

  bool ExpectNone() {
    bool ret = signals_received_.empty();
    if (!ret) {
      LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
          << ", expected none";
    }
    return ret;
  }

  static std::vector<int> signals_received_;
  static Thread *signaled_thread_;

  scoped_ptr<PhysicalSocketServer> ss_;
};

std::vector<int> PosixSignalDeliveryTest::signals_received_;
Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;

// Test receiving a synchronous signal while not in Wait() and then entering
// Wait() afterwards.
TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
  ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
  raise(SIGTERM);
  EXPECT_TRUE(ss_->Wait(0, true));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_TRUE(ExpectNone());
}

// Test that we can handle getting tons of repeated signals and that we see all
// the different ones.
TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
  ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
  for (int i = 0; i < 10000; ++i) {
    raise(SIGTERM);
  }
  raise(SIGINT);
  EXPECT_TRUE(ss_->Wait(0, true));
  // Order will be lowest signal numbers first.
  EXPECT_TRUE(ExpectSignal(SIGINT));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_TRUE(ExpectNone());
}

// Test that a signal during a Wait() call is detected.
TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
  ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
  alarm(1);
  EXPECT_TRUE(ss_->Wait(1500, true));
  EXPECT_TRUE(ExpectSignal(SIGALRM));
  EXPECT_TRUE(ExpectNone());
}

class RaiseSigTermRunnable : public Runnable {
  void Run(Thread *thread) {
    thread->socketserver()->Wait(1000, false);

    // Allow SIGTERM. This will be the only thread with it not masked so it will
    // be delivered to us.
    sigset_t mask;
    sigemptyset(&mask);
    pthread_sigmask(SIG_SETMASK, &mask, NULL);

    // Raise it.
    raise(SIGTERM);
  }
};

// Test that it works no matter what thread the kernel chooses to give the
// signal to (since it's not guaranteed to be the one that Wait() runs on).
TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
  // Mask out SIGTERM so that it can't be delivered to this thread.
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGTERM);
  EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
  // Start a new thread that raises it. It will have to be delivered to that
  // thread. Our implementation should safely handle it and dispatch
  // RecordSignal() on this thread.
  scoped_ptr<Thread> thread(new Thread());
  scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
  thread->Start(runnable.get());
  EXPECT_TRUE(ss_->Wait(1500, true));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_EQ(Thread::Current(), signaled_thread_);
  EXPECT_TRUE(ExpectNone());
}

#endif

}  // namespace rtc
<commit_msg>Disable PhysicalSocketTest.TestUdpReadyToSendIPv4 on Android.<commit_after>/*
 *  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 <signal.h>
#include <stdarg.h>

#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/socket_unittest.h"
#include "webrtc/base/testutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/test/testsupport/gtest_disable.h"

namespace rtc {

class PhysicalSocketTest : public SocketTest {
};

TEST_F(PhysicalSocketTest, TestConnectIPv4) {
  SocketTest::TestConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
#else
#define MAYBE_TestConnectIPv6 TestConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
  SocketTest::TestConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
  SocketTest::TestConnectWithDnsLookupIPv4();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
  SocketTest::TestConnectWithDnsLookupIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
  SocketTest::TestConnectFailIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
#else
#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
  SocketTest::TestConnectFailIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
  SocketTest::TestConnectWithDnsLookupFailIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
  DISABLED_TestConnectWithDnsLookupFailIPv6
#else
#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
  TestConnectWithDnsLookupFailIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
  SocketTest::TestConnectWithDnsLookupFailIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
  SocketTest::TestConnectWithClosedSocketIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWithClosedSocketIPv6 \
  DISABLED_TestConnectWithClosedSocketIPv6
#else
#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
  SocketTest::TestConnectWithClosedSocketIPv6();
}

TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
  SocketTest::TestConnectWhileNotClosedIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestConnectWhileNotClosedIPv6 \
  DISABLED_TestConnectWhileNotClosedIPv6
#else
#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
  SocketTest::TestConnectWhileNotClosedIPv6();
}

TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
  SocketTest::TestServerCloseDuringConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseDuringConnectIPv6 \
  DISABLED_TestServerCloseDuringConnectIPv6
#else
#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
  SocketTest::TestServerCloseDuringConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
  SocketTest::TestClientCloseDuringConnectIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestClientCloseDuringConnectIPv6 \
  DISABLED_TestClientCloseDuringConnectIPv6
#else
#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
  SocketTest::TestClientCloseDuringConnectIPv6();
}

TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
  SocketTest::TestServerCloseIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
#else
#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
  SocketTest::TestServerCloseIPv6();
}

TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
  SocketTest::TestCloseInClosedCallbackIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestCloseInClosedCallbackIPv6 \
  DISABLED_TestCloseInClosedCallbackIPv6
#else
#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
  SocketTest::TestCloseInClosedCallbackIPv6();
}

TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
  SocketTest::TestSocketServerWaitIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
#else
#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
  SocketTest::TestSocketServerWaitIPv6();
}

TEST_F(PhysicalSocketTest, TestTcpIPv4) {
  SocketTest::TestTcpIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
#else
#define MAYBE_TestTcpIPv6 TestTcpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
  SocketTest::TestTcpIPv6();
}

TEST_F(PhysicalSocketTest, TestUdpIPv4) {
  SocketTest::TestUdpIPv4();
}

// Crashes on Linux. See webrtc:4923.
#if defined(WEBRTC_LINUX)
#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
#else
#define MAYBE_TestUdpIPv6 TestUdpIPv6
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
  SocketTest::TestUdpIPv6();
}

// Disable for TSan v2, see
// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
// Also disable for MSan, see:
// https://code.google.com/p/webrtc/issues/detail?id=4958
// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
// Also disable for ASan.
// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
  defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID)
#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
#else
#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
#endif
TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
  SocketTest::TestUdpReadyToSendIPv4();
}

TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
  SocketTest::TestUdpReadyToSendIPv6();
}

TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
  SocketTest::TestGetSetOptionsIPv4();
}

TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
  SocketTest::TestGetSetOptionsIPv6();
}

#if defined(WEBRTC_POSIX)

class PosixSignalDeliveryTest : public testing::Test {
 public:
  static void RecordSignal(int signum) {
    signals_received_.push_back(signum);
    signaled_thread_ = Thread::Current();
  }

 protected:
  void SetUp() {
    ss_.reset(new PhysicalSocketServer());
  }

  void TearDown() {
    ss_.reset(NULL);
    signals_received_.clear();
    signaled_thread_ = NULL;
  }

  bool ExpectSignal(int signum) {
    if (signals_received_.empty()) {
      LOG(LS_ERROR) << "ExpectSignal(): No signal received";
      return false;
    }
    if (signals_received_[0] != signum) {
      LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
          signals_received_[0] << ", expected " << signum;
      return false;
    }
    signals_received_.erase(signals_received_.begin());
    return true;
  }

  bool ExpectNone() {
    bool ret = signals_received_.empty();
    if (!ret) {
      LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
          << ", expected none";
    }
    return ret;
  }

  static std::vector<int> signals_received_;
  static Thread *signaled_thread_;

  scoped_ptr<PhysicalSocketServer> ss_;
};

std::vector<int> PosixSignalDeliveryTest::signals_received_;
Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;

// Test receiving a synchronous signal while not in Wait() and then entering
// Wait() afterwards.
TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
  ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
  raise(SIGTERM);
  EXPECT_TRUE(ss_->Wait(0, true));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_TRUE(ExpectNone());
}

// Test that we can handle getting tons of repeated signals and that we see all
// the different ones.
TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
  ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
  for (int i = 0; i < 10000; ++i) {
    raise(SIGTERM);
  }
  raise(SIGINT);
  EXPECT_TRUE(ss_->Wait(0, true));
  // Order will be lowest signal numbers first.
  EXPECT_TRUE(ExpectSignal(SIGINT));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_TRUE(ExpectNone());
}

// Test that a signal during a Wait() call is detected.
TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
  ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
  alarm(1);
  EXPECT_TRUE(ss_->Wait(1500, true));
  EXPECT_TRUE(ExpectSignal(SIGALRM));
  EXPECT_TRUE(ExpectNone());
}

class RaiseSigTermRunnable : public Runnable {
  void Run(Thread *thread) {
    thread->socketserver()->Wait(1000, false);

    // Allow SIGTERM. This will be the only thread with it not masked so it will
    // be delivered to us.
    sigset_t mask;
    sigemptyset(&mask);
    pthread_sigmask(SIG_SETMASK, &mask, NULL);

    // Raise it.
    raise(SIGTERM);
  }
};

// Test that it works no matter what thread the kernel chooses to give the
// signal to (since it's not guaranteed to be the one that Wait() runs on).
TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
  // Mask out SIGTERM so that it can't be delivered to this thread.
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGTERM);
  EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
  // Start a new thread that raises it. It will have to be delivered to that
  // thread. Our implementation should safely handle it and dispatch
  // RecordSignal() on this thread.
  scoped_ptr<Thread> thread(new Thread());
  scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
  thread->Start(runnable.get());
  EXPECT_TRUE(ss_->Wait(1500, true));
  EXPECT_TRUE(ExpectSignal(SIGTERM));
  EXPECT_EQ(Thread::Current(), signaled_thread_);
  EXPECT_TRUE(ExpectNone());
}

#endif

}  // namespace rtc
<|endoftext|>


<commit_before>#include <osg/LightSource>

#include <osgDB/ReadFile>

#if defined(_MSC_VER)
#pragma warning( disable : 4505 )
#pragma warning( default : 4996 )
#endif
#include <fbxsdk.h>

#include "fbxReader.h"

osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount)
{
    const FbxLight* fbxLight = FbxCast<FbxLight>(pNode->GetNodeAttribute());

    if (!fbxLight)
    {
        return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
    }

    osg::Light* osgLight = new osg::Light;
    osg::LightSource* osgLightSource = new osg::LightSource;

    osgLightSource->setLight(osgLight);
    osgLight->setLightNum(nLightCount++);

    FbxLight::EType fbxLightType = fbxLight->LightType.IsValid() ?
        fbxLight->LightType.Get() : FbxLight::ePoint;

    osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != FbxLight::eDirectional));

    if (fbxLightType == FbxLight::eSpot)
    {
        double coneAngle = fbxLight->OuterAngle.Get();
        double hotSpot = fbxLight->InnerAngle.Get();
        const float MIN_HOTSPOT = 0.467532f;

        osgLight->setSpotCutoff(static_cast<float>(coneAngle));

        //Approximate the hotspot using the GL light exponent.
        // This formula maps a hotspot of 180 to exponent 0 (uniform light
        // distribution) and a hotspot of 45 to exponent 1 (effective light
        // intensity is attenuated by the cosine of the angle between the
        // direction of the light and the direction from the light to the vertex
        // being lighted). A hotspot close to 0 maps to exponent 128 (maximum).
        float exponent = (180.0f / (std::max)(static_cast<float>(hotSpot),
            MIN_HOTSPOT) - 1.0f) / 3.0f;
        osgLight->setSpotExponent(exponent);
    }

    if (fbxLight->DecayType.IsValid() &&
        fbxLight->DecayStart.IsValid())
    {
        double fbxDecayStart = fbxLight->DecayStart.Get();

        switch (fbxLight->DecayType.Get())
        {
        case FbxLight::eNone:
            break;
        case FbxLight::eLinear:
            osgLight->setLinearAttenuation(fbxDecayStart);
            break;
        case FbxLight::eQuadratic:
        case FbxLight::eCubic:
            osgLight->setQuadraticAttenuation(fbxDecayStart);
            break;
        }
    }

    osg::Vec3f osgDiffuseSpecular(1.0f, 1.0f, 1.0f);
    osg::Vec3f osgAmbient(0.0f, 0.0f, 0.0f);
    if (fbxLight->Color.IsValid())
    {
        FbxDouble3 fbxColor = fbxLight->Color.Get();
        osgDiffuseSpecular.set(
            static_cast<float>(fbxColor[0]),
            static_cast<float>(fbxColor[1]),
            static_cast<float>(fbxColor[2]));
    }
    if (fbxLight->Intensity.IsValid())
    {
        osgDiffuseSpecular *= static_cast<float>(fbxLight->Intensity.Get()) * 0.01f;
    }
    if (fbxLight->ShadowColor.IsValid())
    {
        FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get();
        osgAmbient.set(
            static_cast<float>(fbxShadowColor[0]),
            static_cast<float>(fbxShadowColor[1]),
            static_cast<float>(fbxShadowColor[2]));
    }

    osgLight->setDiffuse(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setSpecular(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setAmbient(osg::Vec4f(osgAmbient, 1.0f));

    return osgDB::ReaderWriter::ReadResult(osgLightSource);
}
<commit_msg>From  Konstantin Matveyev, "Multiple light fix in FBX-importer"<commit_after>#include <osg/LightSource>

#include <osgDB/ReadFile>

#if defined(_MSC_VER)
#pragma warning( disable : 4505 )
#pragma warning( default : 4996 )
#endif
#include <fbxsdk.h>

#include "fbxReader.h"

osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(FbxNode* pNode, int& nLightCount)
{
    const FbxLight* fbxLight = FbxCast<FbxLight>(pNode->GetNodeAttribute());

    if (!fbxLight)
    {
        return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
    }

    osg::Light* osgLight = new osg::Light;
    osgLight->setLightNum(nLightCount++);

    osg::LightSource* osgLightSource = new osg::LightSource;
    osgLightSource->setLight(osgLight);

    FbxLight::EType fbxLightType = fbxLight->LightType.IsValid() ?
        fbxLight->LightType.Get() : FbxLight::ePoint;

    osgLight->setPosition(osg::Vec4(0,0,0,fbxLightType != FbxLight::eDirectional));

    if (fbxLightType == FbxLight::eSpot)
    {
        double coneAngle = fbxLight->OuterAngle.Get();
        double hotSpot = fbxLight->InnerAngle.Get();
        const float MIN_HOTSPOT = 0.467532f;

        osgLight->setSpotCutoff(static_cast<float>(coneAngle));

        //Approximate the hotspot using the GL light exponent.
        // This formula maps a hotspot of 180 to exponent 0 (uniform light
        // distribution) and a hotspot of 45 to exponent 1 (effective light
        // intensity is attenuated by the cosine of the angle between the
        // direction of the light and the direction from the light to the vertex
        // being lighted). A hotspot close to 0 maps to exponent 128 (maximum).
        float exponent = (180.0f / (std::max)(static_cast<float>(hotSpot),
            MIN_HOTSPOT) - 1.0f) / 3.0f;
        osgLight->setSpotExponent(exponent);
    }

    if (fbxLight->DecayType.IsValid() &&
        fbxLight->DecayStart.IsValid())
    {
        double fbxDecayStart = fbxLight->DecayStart.Get();

        switch (fbxLight->DecayType.Get())
        {
        case FbxLight::eNone:
            break;
        case FbxLight::eLinear:
            osgLight->setLinearAttenuation(fbxDecayStart);
            break;
        case FbxLight::eQuadratic:
        case FbxLight::eCubic:
            osgLight->setQuadraticAttenuation(fbxDecayStart);
            break;
        }
    }

    osg::Vec3f osgDiffuseSpecular(1.0f, 1.0f, 1.0f);
    osg::Vec3f osgAmbient(0.0f, 0.0f, 0.0f);
    if (fbxLight->Color.IsValid())
    {
        FbxDouble3 fbxColor = fbxLight->Color.Get();
        osgDiffuseSpecular.set(
            static_cast<float>(fbxColor[0]),
            static_cast<float>(fbxColor[1]),
            static_cast<float>(fbxColor[2]));
    }
    if (fbxLight->Intensity.IsValid())
    {
        osgDiffuseSpecular *= static_cast<float>(fbxLight->Intensity.Get()) * 0.01f;
    }
    if (fbxLight->ShadowColor.IsValid())
    {
        FbxDouble3 fbxShadowColor = fbxLight->ShadowColor.Get();
        osgAmbient.set(
            static_cast<float>(fbxShadowColor[0]),
            static_cast<float>(fbxShadowColor[1]),
            static_cast<float>(fbxShadowColor[2]));
    }

    osgLight->setDiffuse(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setSpecular(osg::Vec4f(osgDiffuseSpecular, 1.0f));
    osgLight->setAmbient(osg::Vec4f(osgAmbient, 1.0f));

    return osgDB::ReaderWriter::ReadResult(osgLightSource);
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/CubeMapGenerator>
#include <stdlib.h>

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:    osg::Referenced(),
    texture_size_(texture_size)
{
    for (int i=0; i<6; ++i)
    {
        osg::ref_ptr<osg::Image> image = new osg::Image;
        unsigned char* data = new unsigned char [texture_size*texture_size*4];
        image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE);
        images_.push_back(image);
    }
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:    osg::Referenced(copy),
    texture_size_(copy.texture_size_)
{
    Image_list::const_iterator i;
    for (i=copy.images_.begin(); i!=copy.images_.end(); ++i)
    {
        images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
    }
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
    const float duv = 2.0f/(texture_size_-1);

    float v = 1;
    for (int i=0; i<texture_size_; ++i) {
        float u = 1;
        for (int j=0; j<texture_size_; ++j) {
            if (use_osg_system) {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, -u, v)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, u, v)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, v, 1)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -v, -1)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, -1, v)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, 1, v)));
            } else {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, v, -u)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, v, u)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, 1, v)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -1, -v)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, v, -1)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, v, 1)));
            }
            u -= duv;
        }
        v -= duv;
    }
}
<commit_msg>From Marco Jez, improvement to the handling of coordinates frame in CubeMapGenerator.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/CubeMapGenerator>
#include <stdlib.h>

#include <osg/Matrix>

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:    osg::Referenced(),
    texture_size_(texture_size)
{
    for (int i=0; i<6; ++i)
    {
        osg::ref_ptr<osg::Image> image = new osg::Image;
        unsigned char* data = new unsigned char [texture_size*texture_size*4];
        image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE);
        images_.push_back(image);
    }
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:    osg::Referenced(copy),
    texture_size_(copy.texture_size_)
{
    Image_list::const_iterator i;
    for (i=copy.images_.begin(); i!=copy.images_.end(); ++i)
    {
        images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
    }
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
	osg::Matrix M;

	if (use_osg_system) {
		M = osg::Matrix::rotate(osg::PI_2, osg::Vec3(1, 0, 0));
	} else {
		M = osg::Matrix::identity();
	}

    const float dst = 2.0f/(texture_size_-1);

    float t = -1;
    for (int i=0; i<texture_size_; ++i) {
        float s = -1;
        for (int j=0; j<texture_size_; ++j) {
			set_pixel(0, j, i, compute_color(osg::Vec3(1, -t, -s)  * M));
            set_pixel(1, j, i, compute_color(osg::Vec3(-1, -t, s)  * M));
            set_pixel(2, j, i, compute_color(osg::Vec3(s, 1, t)    * M));
            set_pixel(3, j, i, compute_color(osg::Vec3(s, -1, -t)  * M));
            set_pixel(4, j, i, compute_color(osg::Vec3(s, -t, 1)   * M));
            set_pixel(5, j, i, compute_color(osg::Vec3(-s, -t, -1) * M));
            s += dst;
        }
        t += dst;
    }
}
<|endoftext|>


<commit_before>// This file is part of Parsito <http://github.com/ufal/parsito/>.
//
// Copyright 2015 Institute of Formal and Applied Linguistics, Faculty of
// Mathematics and Physics, Charles University in Prague, Czech Republic.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>
#include <atomic>
#include <fstream>
#include <limits>
#include <random>
#include <thread>
#include <unordered_set>

#include "network/neural_network_trainer.h"
#include "parser_nn.h"
#include "parser_nn_trainer.h"
#include "utils/parse_double.h"
#include "utils/parse_int.h"
#include "utils/split.h"

namespace ufal {
namespace parsito {

void parser_nn_trainer::train(const string& transition_system_name, const string& transition_oracle_name,
                              const string& embeddings_description, const string& nodes_description, const network_parameters& parameters,
                              unsigned number_of_threads, const vector<tree>& train, const vector<tree>& heldout, binary_encoder& enc) {
  if (train.empty()) runtime_failure("No training data was given!");

  // Random generator with fixed seed for reproducibility
  mt19937 generator(42);

  // Check that all non-root nodes have heads and nonempty deprel
  for (auto&& tree : train)
    for (auto&& node : tree.nodes)
      if (node.id) {
        if (node.head < 0) runtime_failure("The node '" << node.form << "' with id " << node.id << " has no head set!");
        if (node.deprel.empty()) runtime_failure("The node '" << node.form << "' with id " << node.id << " has no deprel set!");
      }

  // Generate labels for transition system
  parser_nn parser;
  unordered_set<string> labels_set;

  for (auto&& tree : train)
    for (auto&& node : tree.nodes)
      if (node.id && !labels_set.count(node.deprel)) {
        labels_set.insert(node.deprel);
        parser.labels.push_back(node.deprel);
      }

  // Create transition system and transition oracle
  parser.system.reset(transition_system::create(transition_system_name, parser.labels));
  if (!parser.system) runtime_failure("Cannot create transition system '" << transition_system_name << "'!");

  unique_ptr<transition_oracle> oracle(parser.system->oracle(transition_oracle_name));
  if (!oracle) runtime_failure("Cannot create transition oracle '" << transition_oracle_name << "' for transition system '" << transition_system_name << "'!");

  // Create node_extractor
  string error;
  if (!parser.nodes.create(nodes_description, error)) runtime_failure(error);

  // Load value_extractors and embeddings
  vector<string> value_names;
  vector<string_piece> lines, tokens;
  split(embeddings_description, '\n', lines);
  for (auto&& line : lines) {
    // Ignore empty lines and comments
    if (!line.len || line.str[0] == '#') continue;

    split(line, ' ', tokens);
    if (!(tokens.size() >= 3 && tokens.size() <= 6))
      runtime_failure("Expected 3 to 6 columns on embedding description line '" << line << "'!");

    value_names.emplace_back(string(tokens[0].str, tokens[0].len));
    parser.values.emplace_back();
    if (!parser.values.back().create(tokens[0], error)) runtime_failure(error);

    int dimension = parse_int(tokens[1], "embedding dimension");
    int min_count = parse_int(tokens[2], "minimum frequency count");
    unsigned updatable_index = 0;
    unsigned embeddings_from_file = 0;
    string embeddings_from_file_comment;
    vector<pair<string, vector<float>>> weights;
    unordered_set<string> weights_set;

    // Compute words and counts present in the training data
    string word;
    unordered_map<string, int> word_counts;
    for (auto&& tree : train)
      for (auto&& node : tree.nodes)
        if (node.id) {
          parser.values.back().extract(node, word);
          word_counts[word]++;
        }

    // Load embedding if it was given
    if (tokens.size() >= 4) {
      int update_weights = tokens.size() >= 5 ? parse_int(tokens[4], "update weights") : 1;
      int max_embeddings = tokens.size() >= 6 ? parse_int(tokens[5], "maximum embeddings count") : numeric_limits<int>::max();
      ifstream in(string(tokens[3].str, tokens[3].len));
      if (!in.is_open()) runtime_failure("Cannot load '" << tokens[0] << "' embedding from file '" << tokens[4] << "'!");

      // Load first line containing dictionary size and dimensions
      string line;
      vector<string_piece> parts;
      if (!getline(in, line)) runtime_failure("Cannot read first line from embedding file '" << tokens[4] << "'!");
      split(line, ' ', parts);
      if (parts.size() != 2) runtime_failure("Expected two numbers on the first line of embedding file '" << tokens[4] << "'!");
      int file_dimension = parse_int(parts[1], "embedding file dimension");

      if (file_dimension < dimension) runtime_failure("The embedding file '" << tokens[4] << "' has lower dimension than required!");

      // Generate random projection when smaller dimension is required
      vector<vector<float>> projection;
      if (file_dimension > dimension) {
        embeddings_from_file_comment = "[dim" + to_string(file_dimension) + "->" + to_string(dimension) + "]";

        uniform_real_distribution<double> uniform(0, 1);
        projection.resize(dimension);
        for (auto&& row : projection) {
          row.resize(file_dimension);
          for (auto&& weight : row) weight = uniform(generator);

          double sum = 0;
          for (auto&& weight : row) sum += weight;
          for (auto&& weight : row) weight /= sum;
        }
      }

      // Load input embedding
      vector<double> input_weights(file_dimension);
      vector<float> projected_weights(dimension);
      while (getline(in, line) && int(weights.size()) < max_embeddings) {
        split(line, ' ', parts);
        if (!parts.empty() && !parts.back().len) parts.pop_back(); // Ignore space at the end of line
        if (int(parts.size()) != file_dimension + 1) runtime_failure("Wrong number of values on line '" << line << "' of embedding file '" << tokens[4]);
        for (int i = 0; i < file_dimension; i++)
          input_weights[i] = parse_double(parts[1 + i], "embedding weight");

        string word(parts[0].str, parts[0].len);

        // For update_weights == 2, ignore embeddings for unknown words
        if (update_weights == 2 && !word_counts.count(word))
          continue;

        for (int i = 0; i < dimension; i++)
          if (file_dimension == dimension) {
            projected_weights[i] = input_weights[i];
          } else {
            projected_weights[i] = 0;
            for (int j = 0; j < file_dimension; j++)
              projected_weights[i] += projection[i][j] * input_weights[j];
          }

        if (!weights_set.count(word)) {
          weights.emplace_back(word, projected_weights);
          weights_set.insert(word);
        }
      }
      embeddings_from_file = weights.size();
      updatable_index = update_weights ? 0 : embeddings_from_file;
    }

    // Add embedding for non-present word with min_count
    {
      vector<float> word_weights(dimension);
      uniform_real_distribution<float> uniform(-1, 1);
      for (auto&& word_count : word_counts)
        if (word_count.second >= min_count && !weights_set.count(word_count.first)) {
          for (auto&& word_weight : word_weights)
            word_weight = uniform(generator);

          weights.emplace_back(word_count.first, word_weights);
        }
    }

    // Add the embedding
    parser.embeddings.emplace_back();
    parser.embeddings.back().create(dimension, updatable_index, weights);

    // Count the cover of this embedding
    string buffer;
    unsigned words_total = 0, words_covered = 0, words_covered_from_file = 0;
    for (auto&& tree : train)
      for (auto&& node : tree.nodes)
        if (node.id) {
          parser.values.back().extract(node, word);
          words_total++;
          int word_id = parser.embeddings.back().lookup_word(word, buffer);
          words_covered += word_id >= 0;
          words_covered_from_file += word_id >= 0 && unsigned(word_id) < embeddings_from_file;
        }

    cerr << "Initialized '" << tokens[0] << "' embedding with " << embeddings_from_file << embeddings_from_file_comment
         << "," << weights.size() << " words and " << fixed << setprecision(1) << 100. * words_covered_from_file / words_total
         << "%," << 100. * words_covered / words_total << "% coverage." << endl;
  }

  // Train the network
  unsigned total_dimension = 0, total_nodes = 0;
  for (auto&& embedding : parser.embeddings) total_dimension += embedding.dimension;
  for (auto&& tree : train) total_nodes += tree.nodes.size() - 1;
  auto scaled_parameters = parameters;
  scaled_parameters.l1_regularization /= train.size();
  scaled_parameters.l2_regularization /= total_nodes;
  neural_network_trainer network_trainer(parser.network, total_dimension * parser.nodes.node_count(), parser.system->transition_count(), scaled_parameters, generator);

  vector<int> permutation;
  for (size_t i = 0; i < train.size(); i++)
    permutation.push_back(permutation.size());

  for (int iteration = 1; network_trainer.next_iteration(); iteration++) {
    // Train on training data
    shuffle(permutation.begin(), permutation.end(), generator);

    atomic<unsigned> atomic_index(0);
    atomic<double> atomic_logprob(0);
    auto training = [&]() {
      tree t;
      configuration conf;
      string word, word_buffer;
      vector<vector<int>> nodes_embeddings;
      vector<int> extracted_nodes;
      vector<const vector<int>*> extracted_embeddings;
      neural_network_trainer::workspace workspace;
      double logprob = 0;

      for (unsigned current_index; (current_index = atomic_index++) < permutation.size();) {
        const tree& gold = train[permutation[current_index]];
        t = gold;
        t.unlink_all_nodes();
        conf.init(&t);

        // Compute embeddings
        if (t.nodes.size() > nodes_embeddings.size()) nodes_embeddings.resize(t.nodes.size());
        for (size_t i = 0; i < t.nodes.size(); i++) {
          nodes_embeddings[i].resize(parser.embeddings.size());
          for (size_t j = 0; j < parser.embeddings.size(); j++) {
            parser.values[j].extract(t.nodes[i], word);
            nodes_embeddings[i][j] = parser.embeddings[j].lookup_word(word, word_buffer);
          }
        }

        // Train the network
        while (!conf.final()) {
          // Extract nodes
          parser.nodes.extract(conf, extracted_nodes);
          extracted_embeddings.resize(extracted_nodes.size());
          for (size_t i = 0; i < extracted_nodes.size(); i++)
            extracted_embeddings[i] = extracted_nodes[i] >= 0 ? &nodes_embeddings[extracted_nodes[i]] : nullptr;

          // Propagate
          network_trainer.propagate(parser.embeddings, extracted_embeddings, workspace);

          // Find most probable applicable transition
          int network_best = -1;
          for (unsigned i = 0; i < workspace.outcomes.size(); i++)
            if (parser.system->applicable(conf, i) && (network_best < 0 || workspace.outcomes[i] > workspace.outcomes[network_best]))
              network_best = i;

          // Apply the oracle
          auto prediction = oracle->predict(conf, gold, network_best);

          // Update logprob
          if (workspace.outcomes[prediction.best])
            logprob += log(workspace.outcomes[prediction.best]);

          // Backpropagate the chosen outcome
          network_trainer.backpropagate(parser.embeddings, extracted_embeddings, prediction.best, workspace);

          // Follow the chosen outcome
          int child = parser.system->perform(conf, prediction.to_follow);

          // If a node was linked, recompute its not-found embeddings as deprel has changed
          if (child >= 0)
            for (size_t i = 0; i < parser.embeddings.size(); i++)
              if (nodes_embeddings[child][i] < 0) {
                parser.values[i].extract(t.nodes[child], word);
                nodes_embeddings[child][i] = parser.embeddings[i].lookup_word(word, word_buffer);
              }
        }
        network_trainer.finalize_sentence();
      }
      for (double old_atomic_logprob = atomic_logprob; atomic_logprob.compare_exchange_weak(old_atomic_logprob, old_atomic_logprob + logprob); ) {}
    };

    cerr << "Iteration " << iteration << ": ";
    if (number_of_threads > 1) {
      vector<thread> threads;
      for (unsigned i = 0; i < number_of_threads; i++) threads.emplace_back(training);
      for (; !threads.empty(); threads.pop_back()) threads.back().join();
    } else {
      training();
    }
    cerr << "training logprob " << scientific << setprecision(4) << atomic_logprob;

    // Evaluate heldout data if present
    if (!heldout.empty()) {
      tree t;

      unsigned total = 0, correct_unlabelled = 0, correct_labelled = 0;
      for (auto&& gold : heldout) {
        t = gold;
        t.unlink_all_nodes();
        parser.parse(t);
        for (size_t i = 1; i < t.nodes.size(); i++) {
          total++;
          correct_unlabelled += t.nodes[i].head == gold.nodes[i].head;
          correct_labelled += t.nodes[i].head == gold.nodes[i].head && t.nodes[i].deprel == gold.nodes[i].deprel;
        }
      }

      cerr << ", heldout UAS " << fixed << setprecision(2) << (100. * correct_unlabelled / total) << "%, LAS " << (100. * correct_labelled / total) << "%";
    }

    cerr << endl;
  }

  // Encode transition system
  enc.add_2B(parser.labels.size());
  for (auto&& label : parser.labels)
    enc.add_str(label);
  enc.add_str(transition_system_name);

  // Encode nodes selector
  enc.add_str(nodes_description);

  // Encode value extractors and embeddings
  enc.add_2B(value_names.size());
  for (auto&& value_name : value_names)
    enc.add_str(value_name);
  for (auto&& embedding : parser.embeddings)
    embedding.save(enc);

  // Encode the network
  network_trainer.save_network(enc);
}

} // namespace parsito
} // namespace ufal
<commit_msg>Fix filename index in error outputs.<commit_after>// This file is part of Parsito <http://github.com/ufal/parsito/>.
//
// Copyright 2015 Institute of Formal and Applied Linguistics, Faculty of
// Mathematics and Physics, Charles University in Prague, Czech Republic.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <algorithm>
#include <atomic>
#include <fstream>
#include <limits>
#include <random>
#include <thread>
#include <unordered_set>

#include "network/neural_network_trainer.h"
#include "parser_nn.h"
#include "parser_nn_trainer.h"
#include "utils/parse_double.h"
#include "utils/parse_int.h"
#include "utils/split.h"

namespace ufal {
namespace parsito {

void parser_nn_trainer::train(const string& transition_system_name, const string& transition_oracle_name,
                              const string& embeddings_description, const string& nodes_description, const network_parameters& parameters,
                              unsigned number_of_threads, const vector<tree>& train, const vector<tree>& heldout, binary_encoder& enc) {
  if (train.empty()) runtime_failure("No training data was given!");

  // Random generator with fixed seed for reproducibility
  mt19937 generator(42);

  // Check that all non-root nodes have heads and nonempty deprel
  for (auto&& tree : train)
    for (auto&& node : tree.nodes)
      if (node.id) {
        if (node.head < 0) runtime_failure("The node '" << node.form << "' with id " << node.id << " has no head set!");
        if (node.deprel.empty()) runtime_failure("The node '" << node.form << "' with id " << node.id << " has no deprel set!");
      }

  // Generate labels for transition system
  parser_nn parser;
  unordered_set<string> labels_set;

  for (auto&& tree : train)
    for (auto&& node : tree.nodes)
      if (node.id && !labels_set.count(node.deprel)) {
        labels_set.insert(node.deprel);
        parser.labels.push_back(node.deprel);
      }

  // Create transition system and transition oracle
  parser.system.reset(transition_system::create(transition_system_name, parser.labels));
  if (!parser.system) runtime_failure("Cannot create transition system '" << transition_system_name << "'!");

  unique_ptr<transition_oracle> oracle(parser.system->oracle(transition_oracle_name));
  if (!oracle) runtime_failure("Cannot create transition oracle '" << transition_oracle_name << "' for transition system '" << transition_system_name << "'!");

  // Create node_extractor
  string error;
  if (!parser.nodes.create(nodes_description, error)) runtime_failure(error);

  // Load value_extractors and embeddings
  vector<string> value_names;
  vector<string_piece> lines, tokens;
  split(embeddings_description, '\n', lines);
  for (auto&& line : lines) {
    // Ignore empty lines and comments
    if (!line.len || line.str[0] == '#') continue;

    split(line, ' ', tokens);
    if (!(tokens.size() >= 3 && tokens.size() <= 6))
      runtime_failure("Expected 3 to 6 columns on embedding description line '" << line << "'!");

    value_names.emplace_back(string(tokens[0].str, tokens[0].len));
    parser.values.emplace_back();
    if (!parser.values.back().create(tokens[0], error)) runtime_failure(error);

    int dimension = parse_int(tokens[1], "embedding dimension");
    int min_count = parse_int(tokens[2], "minimum frequency count");
    unsigned updatable_index = 0;
    unsigned embeddings_from_file = 0;
    string embeddings_from_file_comment;
    vector<pair<string, vector<float>>> weights;
    unordered_set<string> weights_set;

    // Compute words and counts present in the training data
    string word;
    unordered_map<string, int> word_counts;
    for (auto&& tree : train)
      for (auto&& node : tree.nodes)
        if (node.id) {
          parser.values.back().extract(node, word);
          word_counts[word]++;
        }

    // Load embedding if it was given
    if (tokens.size() >= 4) {
      int update_weights = tokens.size() >= 5 ? parse_int(tokens[4], "update weights") : 1;
      int max_embeddings = tokens.size() >= 6 ? parse_int(tokens[5], "maximum embeddings count") : numeric_limits<int>::max();
      ifstream in(string(tokens[3].str, tokens[3].len));
      if (!in.is_open()) runtime_failure("Cannot load '" << tokens[0] << "' embedding from file '" << tokens[3] << "'!");

      // Load first line containing dictionary size and dimensions
      string line;
      vector<string_piece> parts;
      if (!getline(in, line)) runtime_failure("Cannot read first line from embedding file '" << tokens[3] << "'!");
      split(line, ' ', parts);
      if (parts.size() != 2) runtime_failure("Expected two numbers on the first line of embedding file '" << tokens[3] << "'!");
      int file_dimension = parse_int(parts[1], "embedding file dimension");

      if (file_dimension < dimension) runtime_failure("The embedding file '" << tokens[3] << "' has lower dimension than required!");

      // Generate random projection when smaller dimension is required
      vector<vector<float>> projection;
      if (file_dimension > dimension) {
        embeddings_from_file_comment = "[dim" + to_string(file_dimension) + "->" + to_string(dimension) + "]";

        uniform_real_distribution<double> uniform(0, 1);
        projection.resize(dimension);
        for (auto&& row : projection) {
          row.resize(file_dimension);
          for (auto&& weight : row) weight = uniform(generator);

          double sum = 0;
          for (auto&& weight : row) sum += weight;
          for (auto&& weight : row) weight /= sum;
        }
      }

      // Load input embedding
      vector<double> input_weights(file_dimension);
      vector<float> projected_weights(dimension);
      while (getline(in, line) && int(weights.size()) < max_embeddings) {
        split(line, ' ', parts);
        if (!parts.empty() && !parts.back().len) parts.pop_back(); // Ignore space at the end of line
        if (int(parts.size()) != file_dimension + 1) runtime_failure("Wrong number of values on line '" << line << "' of embedding file '" << tokens[3]);
        for (int i = 0; i < file_dimension; i++)
          input_weights[i] = parse_double(parts[1 + i], "embedding weight");

        string word(parts[0].str, parts[0].len);

        // For update_weights == 2, ignore embeddings for unknown words
        if (update_weights == 2 && !word_counts.count(word))
          continue;

        for (int i = 0; i < dimension; i++)
          if (file_dimension == dimension) {
            projected_weights[i] = input_weights[i];
          } else {
            projected_weights[i] = 0;
            for (int j = 0; j < file_dimension; j++)
              projected_weights[i] += projection[i][j] * input_weights[j];
          }

        if (!weights_set.count(word)) {
          weights.emplace_back(word, projected_weights);
          weights_set.insert(word);
        }
      }
      embeddings_from_file = weights.size();
      updatable_index = update_weights ? 0 : embeddings_from_file;
    }

    // Add embedding for non-present word with min_count
    {
      vector<float> word_weights(dimension);
      uniform_real_distribution<float> uniform(-1, 1);
      for (auto&& word_count : word_counts)
        if (word_count.second >= min_count && !weights_set.count(word_count.first)) {
          for (auto&& word_weight : word_weights)
            word_weight = uniform(generator);

          weights.emplace_back(word_count.first, word_weights);
        }
    }

    // Add the embedding
    parser.embeddings.emplace_back();
    parser.embeddings.back().create(dimension, updatable_index, weights);

    // Count the cover of this embedding
    string buffer;
    unsigned words_total = 0, words_covered = 0, words_covered_from_file = 0;
    for (auto&& tree : train)
      for (auto&& node : tree.nodes)
        if (node.id) {
          parser.values.back().extract(node, word);
          words_total++;
          int word_id = parser.embeddings.back().lookup_word(word, buffer);
          words_covered += word_id >= 0;
          words_covered_from_file += word_id >= 0 && unsigned(word_id) < embeddings_from_file;
        }

    cerr << "Initialized '" << tokens[0] << "' embedding with " << embeddings_from_file << embeddings_from_file_comment
         << "," << weights.size() << " words and " << fixed << setprecision(1) << 100. * words_covered_from_file / words_total
         << "%," << 100. * words_covered / words_total << "% coverage." << endl;
  }

  // Train the network
  unsigned total_dimension = 0, total_nodes = 0;
  for (auto&& embedding : parser.embeddings) total_dimension += embedding.dimension;
  for (auto&& tree : train) total_nodes += tree.nodes.size() - 1;
  auto scaled_parameters = parameters;
  scaled_parameters.l1_regularization /= train.size();
  scaled_parameters.l2_regularization /= total_nodes;
  neural_network_trainer network_trainer(parser.network, total_dimension * parser.nodes.node_count(), parser.system->transition_count(), scaled_parameters, generator);

  vector<int> permutation;
  for (size_t i = 0; i < train.size(); i++)
    permutation.push_back(permutation.size());

  for (int iteration = 1; network_trainer.next_iteration(); iteration++) {
    // Train on training data
    shuffle(permutation.begin(), permutation.end(), generator);

    atomic<unsigned> atomic_index(0);
    atomic<double> atomic_logprob(0);
    auto training = [&]() {
      tree t;
      configuration conf;
      string word, word_buffer;
      vector<vector<int>> nodes_embeddings;
      vector<int> extracted_nodes;
      vector<const vector<int>*> extracted_embeddings;
      neural_network_trainer::workspace workspace;
      double logprob = 0;

      for (unsigned current_index; (current_index = atomic_index++) < permutation.size();) {
        const tree& gold = train[permutation[current_index]];
        t = gold;
        t.unlink_all_nodes();
        conf.init(&t);

        // Compute embeddings
        if (t.nodes.size() > nodes_embeddings.size()) nodes_embeddings.resize(t.nodes.size());
        for (size_t i = 0; i < t.nodes.size(); i++) {
          nodes_embeddings[i].resize(parser.embeddings.size());
          for (size_t j = 0; j < parser.embeddings.size(); j++) {
            parser.values[j].extract(t.nodes[i], word);
            nodes_embeddings[i][j] = parser.embeddings[j].lookup_word(word, word_buffer);
          }
        }

        // Train the network
        while (!conf.final()) {
          // Extract nodes
          parser.nodes.extract(conf, extracted_nodes);
          extracted_embeddings.resize(extracted_nodes.size());
          for (size_t i = 0; i < extracted_nodes.size(); i++)
            extracted_embeddings[i] = extracted_nodes[i] >= 0 ? &nodes_embeddings[extracted_nodes[i]] : nullptr;

          // Propagate
          network_trainer.propagate(parser.embeddings, extracted_embeddings, workspace);

          // Find most probable applicable transition
          int network_best = -1;
          for (unsigned i = 0; i < workspace.outcomes.size(); i++)
            if (parser.system->applicable(conf, i) && (network_best < 0 || workspace.outcomes[i] > workspace.outcomes[network_best]))
              network_best = i;

          // Apply the oracle
          auto prediction = oracle->predict(conf, gold, network_best);

          // Update logprob
          if (workspace.outcomes[prediction.best])
            logprob += log(workspace.outcomes[prediction.best]);

          // Backpropagate the chosen outcome
          network_trainer.backpropagate(parser.embeddings, extracted_embeddings, prediction.best, workspace);

          // Follow the chosen outcome
          int child = parser.system->perform(conf, prediction.to_follow);

          // If a node was linked, recompute its not-found embeddings as deprel has changed
          if (child >= 0)
            for (size_t i = 0; i < parser.embeddings.size(); i++)
              if (nodes_embeddings[child][i] < 0) {
                parser.values[i].extract(t.nodes[child], word);
                nodes_embeddings[child][i] = parser.embeddings[i].lookup_word(word, word_buffer);
              }
        }
        network_trainer.finalize_sentence();
      }
      for (double old_atomic_logprob = atomic_logprob; atomic_logprob.compare_exchange_weak(old_atomic_logprob, old_atomic_logprob + logprob); ) {}
    };

    cerr << "Iteration " << iteration << ": ";
    if (number_of_threads > 1) {
      vector<thread> threads;
      for (unsigned i = 0; i < number_of_threads; i++) threads.emplace_back(training);
      for (; !threads.empty(); threads.pop_back()) threads.back().join();
    } else {
      training();
    }
    cerr << "training logprob " << scientific << setprecision(4) << atomic_logprob;

    // Evaluate heldout data if present
    if (!heldout.empty()) {
      tree t;

      unsigned total = 0, correct_unlabelled = 0, correct_labelled = 0;
      for (auto&& gold : heldout) {
        t = gold;
        t.unlink_all_nodes();
        parser.parse(t);
        for (size_t i = 1; i < t.nodes.size(); i++) {
          total++;
          correct_unlabelled += t.nodes[i].head == gold.nodes[i].head;
          correct_labelled += t.nodes[i].head == gold.nodes[i].head && t.nodes[i].deprel == gold.nodes[i].deprel;
        }
      }

      cerr << ", heldout UAS " << fixed << setprecision(2) << (100. * correct_unlabelled / total) << "%, LAS " << (100. * correct_labelled / total) << "%";
    }

    cerr << endl;
  }

  // Encode transition system
  enc.add_2B(parser.labels.size());
  for (auto&& label : parser.labels)
    enc.add_str(label);
  enc.add_str(transition_system_name);

  // Encode nodes selector
  enc.add_str(nodes_description);

  // Encode value extractors and embeddings
  enc.add_2B(value_names.size());
  for (auto&& value_name : value_names)
    enc.add_str(value_name);
  for (auto&& embedding : parser.embeddings)
    embedding.save(enc);

  // Encode the network
  network_trainer.save_network(enc);
}

} // namespace parsito
} // namespace ufal
<|endoftext|>


<commit_before>// Copyright 2014 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.

// This file contains the default suppressions for ThreadSanitizer.
// You can also pass additional suppressions via TSAN_OPTIONS:
// TSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =
// False positives in libflashplayer.so and libglib.so. Since we don't
// instrument them, we cannot reason about the synchronization in them.
"race:libflashplayer.so\n"
"race:libglib*.so\n"

// Intentional race in ToolsSanityTest.DataRace in base_unittests.
"race:base/tools_sanity_unittest.cc\n"

// Data race on WatchdogCounter [test-only].
"race:base/threading/watchdog_unittest.cc\n"

// Races in libevent, http://crbug.com/23244.
"race:libevent/event.c\n"

// http://crbug.com/46840.
"race:base::HistogramSamples::IncreaseSum\n"
"race:base::Histogram::Add\n"
"race:base::HistogramSamples::Add\n"

// http://crbug.com/84094.
"race:sqlite3StatusSet\n"
"race:pcache1EnforceMaxPage\n"
"race:pcache1AllocPage\n"

// http://crbug.com/102327.
// Test-only race, won't fix.
"race:tracked_objects::ThreadData::ShutdownSingleThreadedCleanup\n"

// http://crbug.com/115540
"race:*GetCurrentThreadIdentifier\n"

// http://crbug.com/120808
"race:base/threading/watchdog.cc\n"

// http://crbug.com/157586
"race:third_party/libvpx/source/libvpx/vp8/decoder/threading.c\n"

// http://crbug.com/158718
"race:third_party/ffmpeg/libavcodec/pthread.c\n"
"race:third_party/ffmpeg/libavcodec/pthread_frame.c\n"
"race:third_party/ffmpeg/libavcodec/vp8.c\n"
"race:third_party/ffmpeg/libavutil/mem.c\n"
"race:*HashFrameForTesting\n"
"race:third_party/ffmpeg/libavcodec/h264pred.c\n"
"race:media::ReleaseData\n"

// http://crbug.com/158922
"race:third_party/libvpx/source/libvpx/vp8/encoder/*\n"

// http://crbug.com/189177
"race:thread_manager\n"
"race:v8::Locker::Initialize\n"

// http://crbug.com/223352
"race:uprv_malloc_52\n"
"race:uprv_realloc_52\n"

// http://crbug.com/239359
"race:media::TestInputCallback::OnData\n"

// http://crbug.com/244368
"race:skia::BeginPlatformPaint\n"

// http://crbug.com/244385
"race:unixTempFileDir\n"

// http://crbug.com/244755
"race:v8::internal::Zone::NewExpand\n"
"race:TooLateToEnableNow\n"
"race:adjust_segment_bytes_allocated\n"

// http://crbug.com/244774
"race:webrtc::RTPReceiver::ProcessBitrate\n"
"race:webrtc::RTPSender::ProcessBitrate\n"
"race:webrtc::VideoCodingModuleImpl::Decode\n"
"race:webrtc::RTPSender::SendOutgoingData\n"
"race:webrtc::VP8EncoderImpl::GetEncodedPartitions\n"
"race:webrtc::VP8EncoderImpl::Encode\n"
"race:webrtc::ViEEncoder::DeliverFrame\n"
"race:webrtc::vcm::VideoReceiver::Decode\n"
"race:webrtc::VCMReceiver::FrameForDecoding\n"
"race:*trace_event_unique_catstatic*\n"

// http://crbug.com/244856
"race:AutoPulseLock\n"

// http://crbug.com/246968
"race:webrtc::VideoCodingModuleImpl::RegisterPacketRequestCallback\n"

// http://crbug.com/246970
"race:webrtc::EventPosix::StartTimer\n"

// http://crbug.com/246974
"race:content::GpuWatchdogThread::CheckArmed\n"

// http://crbug.com/257396
"race:base::debug::TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n"

// http://crbug.com/258479
"race:SamplingStateScope\n"
"race:g_trace_state\n"

// http://crbug.com/258499
"race:third_party/skia/include/core/SkRefCnt.h\n"

// http://crbug.com/268924
"race:base::g_power_monitor\n"
"race:base::PowerMonitor::PowerMonitor\n"
"race:base::PowerMonitor::AddObserver\n"
"race:base::PowerMonitor::RemoveObserver\n"
"race:base::PowerMonitor::IsOnBatteryPower\n"

// http://crbug.com/268941
"race:tracked_objects::ThreadData::tls_index_\n"

// http://crbug.com/270037
"race:gLibCleanupFunctions\n"

// http://crbug.com/272095
"race:base::g_top_manager\n"

// http://crbug.com/272987
"race:webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>::set_enabled\n"

// http://crbug.com/273047
"race:base::*::g_lazy_tls_ptr\n"
"race:IPC::SyncChannel::ReceivedSyncMsgQueue::lazy_tls_ptr_\n"

// http://crbug.com/280466
"race:content::WebRtcAudioCapturer::SetCapturerSource\n"

// http://crbug.com/285242
"race:media::PulseAudioOutputStream::SetVolume\n"

// http://crbug.com/296883
"race:net::URLFetcherCore::Stop\n"

// http://crbug.com/308590
"race:CustomThreadWatcher::~CustomThreadWatcher\n"

// http://crbug.com/310851
"race:net::ProxyResolverV8Tracing::Job::~Job\n"

// http://crbug.com/313726
"race:CallbackWasCalled\n"

// http://crbug.com/327330
"race:PrepareTextureMailbox\n"
"race:cc::LayerTreeHost::PaintLayerContents\n"

// http://crbug.com/328826
"race:gLCDOrder\n"
"race:gLCDOrientation\n"

// http://crbug.com/328868
"race:PR_Lock\n"

// http://crbug.com/329225
"race:blink::currentTimeFunction\n"

// http://crbug.com/329460
"race:extensions::InfoMap::AddExtension\n"

// http://crbug.com/333244
"race:content::"
    "VideoCaptureImplTest::MockVideoCaptureImpl::~MockVideoCaptureImpl\n"

// http://crbug.com/333871
"race:v8::internal::Interface::NewValue()::value_interface\n"
"race:v8::internal::IsMinusZero(double)::minus_zero\n"
"race:v8::internal::FastCloneShallowObjectStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedLoadStubCompiler::registers\n"
"race:v8::internal::KeyedStoreStubCompiler::registers()::registers\n"
"race:v8::internal::KeyedLoadFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedStoreFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::LoadStubCompiler::registers\n"
"race:v8::internal::StoreStubCompiler::registers\n"
"race:v8::internal::HValue::LoopWeight\n"

// http://crbug.com/334140
"race:CommandLine::HasSwitch\n"
"race:CommandLine::current_process_commandline_\n"
"race:CommandLine::GetSwitchValueASCII\n"

// http://crbug.com/338675
"race:blink::s_platform\n"
"race:content::"
    "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n"

// http://crbug.com/345240
"race:WTF::s_shutdown\n"

// http://crbug.com/345245
"race:jingle_glue::JingleThreadWrapper::~JingleThreadWrapper\n"
"race:webrtc::voe::Channel::UpdatePacketDelay\n"
"race:webrtc::voe::Channel::GetDelayEstimate\n"
"race:webrtc::VCMCodecDataBase::DeregisterReceiveCodec\n"
"race:webrtc::GainControlImpl::set_stream_analog_level\n"

// http://crbug.com/345618
"race:WebCore::AudioDestinationNode::render\n"

// http://crbug.com/345624
"race:media::DataSource::set_host\n"

// http://crbug.com/347534
"race:v8::internal::V8::TearDown\n"

// http://crbug.com/347538
"race:sctp_timer_start\n"

// http://crbug.com/347548
"race:cricket::WebRtcVideoMediaChannel::MaybeResetVieSendCodec\n"
"race:cricket::WebRtcVideoMediaChannel::SetSendCodec\n"

// http://crbug.com/347553
"race:blink::WebString::reset\n"

// http://crbug.com/348511
"race:webrtc::acm1::AudioCodingModuleImpl::PlayoutData10Ms\n"

// http://crbug.com/348982
"race:cricket::P2PTransportChannel::OnConnectionDestroyed\n"
"race:cricket::P2PTransportChannel::AddConnection\n"

// http://crbug.com/348984
"race:sctp_express_handle_sack\n"
"race:system_base_info\n"

// http://crbug.com/363999
"race:v8::internal::EnterDebugger::*EnterDebugger\n"

// http://crbug.com/364006
"race:gfx::ImageFamily::~ImageFamily\n"

// http://crbug.com/364014
"race:WTF::Latin1Encoding()::globalLatin1Encoding\n"

// https://code.google.com/p/v8/issues/detail?id=3143
"race:v8::internal::FLAG_track_double_fields\n"

// https://crbug.com/369257
// TODO(mtklein): annotate properly and remove suppressions.
"race:SandboxIPCHandler::HandleFontMatchRequest\n"
"race:SkFontConfigInterfaceDirect::matchFamilyName\n"
"race:SkFontConfigInterface::GetSingletonDirectInterface\n"
"race:FcStrStaticName\n"

// http://crbug.com/372807
"deadlock:net::X509Certificate::CreateCertificateListFromBytes\n"
"deadlock:net::X509Certificate::CreateFromBytes\n"
"deadlock:net::SSLClientSocketNSS::Core::DoHandshakeLoop\n"

// http://crbug.com/374135
"race:media::AlsaWrapper::PcmWritei\n"

// False positive in libc's tzset_internal, http://crbug.com/379738.
"race:tzset_internal\n"

// http://crbug.com/380554
"deadlock:g_type_add_interface_static\n"

// http:://crbug.com/386385
"race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"

// http://crbug.com/388730
"race:g_next_user_script_id\n"

// http://crbug.com/389098
"race:webrtc::RtpToNtpMs\n"
"race:webrtc::UpdateRtcpList\n"
"race:webrtc::RemoteNtpTimeEstimator::Estimate\n"
"race:webrtc::voe::TransmitMixer::EnableStereoChannelSwapping\n"

// http://crbug.com/397022
"deadlock:"
"base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"

// http://crbug.com/415472
"deadlock:base::debug::TraceLog::GetCategoryGroupEnabled\n"

// http://crbug.com/425057
"deadlock:webrtc::ViEChannelManagerScoped::ViEChannelManagerScoped\n"

// https://crbug.com/433993
"deadlock:content::WebRtcAudioDeviceImpl\n"

// http://crbug.com/417193
// Suppressing both AudioContext.{cpp,h}.
"race:modules/webaudio/AudioContext\n"

// https://code.google.com/p/skia/issues/detail?id=3294
"race:SkBaseMutex::acquire\n"

// https://crbug.com/447461
"race:net::SSLConfig::SSLConfig\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<commit_msg>Suppress a race between using a ChildGpuMemoryBufferManager and destroying it.<commit_after>// Copyright 2014 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.

// This file contains the default suppressions for ThreadSanitizer.
// You can also pass additional suppressions via TSAN_OPTIONS:
// TSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =
// False positives in libflashplayer.so and libglib.so. Since we don't
// instrument them, we cannot reason about the synchronization in them.
"race:libflashplayer.so\n"
"race:libglib*.so\n"

// Intentional race in ToolsSanityTest.DataRace in base_unittests.
"race:base/tools_sanity_unittest.cc\n"

// Data race on WatchdogCounter [test-only].
"race:base/threading/watchdog_unittest.cc\n"

// Races in libevent, http://crbug.com/23244.
"race:libevent/event.c\n"

// http://crbug.com/46840.
"race:base::HistogramSamples::IncreaseSum\n"
"race:base::Histogram::Add\n"
"race:base::HistogramSamples::Add\n"

// http://crbug.com/84094.
"race:sqlite3StatusSet\n"
"race:pcache1EnforceMaxPage\n"
"race:pcache1AllocPage\n"

// http://crbug.com/102327.
// Test-only race, won't fix.
"race:tracked_objects::ThreadData::ShutdownSingleThreadedCleanup\n"

// http://crbug.com/115540
"race:*GetCurrentThreadIdentifier\n"

// http://crbug.com/120808
"race:base/threading/watchdog.cc\n"

// http://crbug.com/157586
"race:third_party/libvpx/source/libvpx/vp8/decoder/threading.c\n"

// http://crbug.com/158718
"race:third_party/ffmpeg/libavcodec/pthread.c\n"
"race:third_party/ffmpeg/libavcodec/pthread_frame.c\n"
"race:third_party/ffmpeg/libavcodec/vp8.c\n"
"race:third_party/ffmpeg/libavutil/mem.c\n"
"race:*HashFrameForTesting\n"
"race:third_party/ffmpeg/libavcodec/h264pred.c\n"
"race:media::ReleaseData\n"

// http://crbug.com/158922
"race:third_party/libvpx/source/libvpx/vp8/encoder/*\n"

// http://crbug.com/189177
"race:thread_manager\n"
"race:v8::Locker::Initialize\n"

// http://crbug.com/223352
"race:uprv_malloc_52\n"
"race:uprv_realloc_52\n"

// http://crbug.com/239359
"race:media::TestInputCallback::OnData\n"

// http://crbug.com/244368
"race:skia::BeginPlatformPaint\n"

// http://crbug.com/244385
"race:unixTempFileDir\n"

// http://crbug.com/244755
"race:v8::internal::Zone::NewExpand\n"
"race:TooLateToEnableNow\n"
"race:adjust_segment_bytes_allocated\n"

// http://crbug.com/244774
"race:webrtc::RTPReceiver::ProcessBitrate\n"
"race:webrtc::RTPSender::ProcessBitrate\n"
"race:webrtc::VideoCodingModuleImpl::Decode\n"
"race:webrtc::RTPSender::SendOutgoingData\n"
"race:webrtc::VP8EncoderImpl::GetEncodedPartitions\n"
"race:webrtc::VP8EncoderImpl::Encode\n"
"race:webrtc::ViEEncoder::DeliverFrame\n"
"race:webrtc::vcm::VideoReceiver::Decode\n"
"race:webrtc::VCMReceiver::FrameForDecoding\n"
"race:*trace_event_unique_catstatic*\n"

// http://crbug.com/244856
"race:AutoPulseLock\n"

// http://crbug.com/246968
"race:webrtc::VideoCodingModuleImpl::RegisterPacketRequestCallback\n"

// http://crbug.com/246970
"race:webrtc::EventPosix::StartTimer\n"

// http://crbug.com/246974
"race:content::GpuWatchdogThread::CheckArmed\n"

// http://crbug.com/257396
"race:base::debug::TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n"

// http://crbug.com/258479
"race:SamplingStateScope\n"
"race:g_trace_state\n"

// http://crbug.com/258499
"race:third_party/skia/include/core/SkRefCnt.h\n"

// http://crbug.com/268924
"race:base::g_power_monitor\n"
"race:base::PowerMonitor::PowerMonitor\n"
"race:base::PowerMonitor::AddObserver\n"
"race:base::PowerMonitor::RemoveObserver\n"
"race:base::PowerMonitor::IsOnBatteryPower\n"

// http://crbug.com/268941
"race:tracked_objects::ThreadData::tls_index_\n"

// http://crbug.com/270037
"race:gLibCleanupFunctions\n"

// http://crbug.com/272095
"race:base::g_top_manager\n"

// http://crbug.com/272987
"race:webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>::set_enabled\n"

// http://crbug.com/273047
"race:base::*::g_lazy_tls_ptr\n"
"race:IPC::SyncChannel::ReceivedSyncMsgQueue::lazy_tls_ptr_\n"

// http://crbug.com/280466
"race:content::WebRtcAudioCapturer::SetCapturerSource\n"

// http://crbug.com/285242
"race:media::PulseAudioOutputStream::SetVolume\n"

// http://crbug.com/296883
"race:net::URLFetcherCore::Stop\n"

// http://crbug.com/308590
"race:CustomThreadWatcher::~CustomThreadWatcher\n"

// http://crbug.com/310851
"race:net::ProxyResolverV8Tracing::Job::~Job\n"

// http://crbug.com/313726
"race:CallbackWasCalled\n"

// http://crbug.com/327330
"race:PrepareTextureMailbox\n"
"race:cc::LayerTreeHost::PaintLayerContents\n"

// http://crbug.com/328826
"race:gLCDOrder\n"
"race:gLCDOrientation\n"

// http://crbug.com/328868
"race:PR_Lock\n"

// http://crbug.com/329225
"race:blink::currentTimeFunction\n"

// http://crbug.com/329460
"race:extensions::InfoMap::AddExtension\n"

// http://crbug.com/333244
"race:content::"
    "VideoCaptureImplTest::MockVideoCaptureImpl::~MockVideoCaptureImpl\n"

// http://crbug.com/333871
"race:v8::internal::Interface::NewValue()::value_interface\n"
"race:v8::internal::IsMinusZero(double)::minus_zero\n"
"race:v8::internal::FastCloneShallowObjectStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedLoadStubCompiler::registers\n"
"race:v8::internal::KeyedStoreStubCompiler::registers()::registers\n"
"race:v8::internal::KeyedLoadFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::KeyedStoreFastElementStub::InitializeInterfaceDescriptor\n"
"race:v8::internal::LoadStubCompiler::registers\n"
"race:v8::internal::StoreStubCompiler::registers\n"
"race:v8::internal::HValue::LoopWeight\n"

// http://crbug.com/334140
"race:CommandLine::HasSwitch\n"
"race:CommandLine::current_process_commandline_\n"
"race:CommandLine::GetSwitchValueASCII\n"

// http://crbug.com/338675
"race:blink::s_platform\n"
"race:content::"
    "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n"

// http://crbug.com/345240
"race:WTF::s_shutdown\n"

// http://crbug.com/345245
"race:jingle_glue::JingleThreadWrapper::~JingleThreadWrapper\n"
"race:webrtc::voe::Channel::UpdatePacketDelay\n"
"race:webrtc::voe::Channel::GetDelayEstimate\n"
"race:webrtc::VCMCodecDataBase::DeregisterReceiveCodec\n"
"race:webrtc::GainControlImpl::set_stream_analog_level\n"

// http://crbug.com/345618
"race:WebCore::AudioDestinationNode::render\n"

// http://crbug.com/345624
"race:media::DataSource::set_host\n"

// http://crbug.com/347534
"race:v8::internal::V8::TearDown\n"

// http://crbug.com/347538
"race:sctp_timer_start\n"

// http://crbug.com/347548
"race:cricket::WebRtcVideoMediaChannel::MaybeResetVieSendCodec\n"
"race:cricket::WebRtcVideoMediaChannel::SetSendCodec\n"

// http://crbug.com/347553
"race:blink::WebString::reset\n"

// http://crbug.com/348511
"race:webrtc::acm1::AudioCodingModuleImpl::PlayoutData10Ms\n"

// http://crbug.com/348982
"race:cricket::P2PTransportChannel::OnConnectionDestroyed\n"
"race:cricket::P2PTransportChannel::AddConnection\n"

// http://crbug.com/348984
"race:sctp_express_handle_sack\n"
"race:system_base_info\n"

// http://crbug.com/363999
"race:v8::internal::EnterDebugger::*EnterDebugger\n"

// http://crbug.com/364006
"race:gfx::ImageFamily::~ImageFamily\n"

// http://crbug.com/364014
"race:WTF::Latin1Encoding()::globalLatin1Encoding\n"

// https://code.google.com/p/v8/issues/detail?id=3143
"race:v8::internal::FLAG_track_double_fields\n"

// https://crbug.com/369257
// TODO(mtklein): annotate properly and remove suppressions.
"race:SandboxIPCHandler::HandleFontMatchRequest\n"
"race:SkFontConfigInterfaceDirect::matchFamilyName\n"
"race:SkFontConfigInterface::GetSingletonDirectInterface\n"
"race:FcStrStaticName\n"

// http://crbug.com/372807
"deadlock:net::X509Certificate::CreateCertificateListFromBytes\n"
"deadlock:net::X509Certificate::CreateFromBytes\n"
"deadlock:net::SSLClientSocketNSS::Core::DoHandshakeLoop\n"

// http://crbug.com/374135
"race:media::AlsaWrapper::PcmWritei\n"

// False positive in libc's tzset_internal, http://crbug.com/379738.
"race:tzset_internal\n"

// http://crbug.com/380554
"deadlock:g_type_add_interface_static\n"

// http:://crbug.com/386385
"race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"

// http://crbug.com/388730
"race:g_next_user_script_id\n"

// http://crbug.com/389098
"race:webrtc::RtpToNtpMs\n"
"race:webrtc::UpdateRtcpList\n"
"race:webrtc::RemoteNtpTimeEstimator::Estimate\n"
"race:webrtc::voe::TransmitMixer::EnableStereoChannelSwapping\n"

// http://crbug.com/397022
"deadlock:"
"base::debug::TraceEventTestFixture_ThreadOnceBlocking_Test::TestBody\n"

// http://crbug.com/415472
"deadlock:base::debug::TraceLog::GetCategoryGroupEnabled\n"

// http://crbug.com/425057
"deadlock:webrtc::ViEChannelManagerScoped::ViEChannelManagerScoped\n"

// https://crbug.com/433993
"deadlock:content::WebRtcAudioDeviceImpl\n"

// http://crbug.com/417193
// Suppressing both AudioContext.{cpp,h}.
"race:modules/webaudio/AudioContext\n"

// https://code.google.com/p/skia/issues/detail?id=3294
"race:SkBaseMutex::acquire\n"

// https://crbug.com/447461
"race:net::SSLConfig::SSLConfig\n"

// https://crbug.com/430533
"race:content::ChildGpuMemoryBufferManager::~ChildGpuMemoryBufferManager\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<|endoftext|>