--- /dev/null
+// Copyright 2016 The Chromium Embedded Framework Authors. Portions copyright
+// 2012 The Chromium Authors. All rights reserved. Use of this source code is
+// governed by a BSD-style license that can be found in the LICENSE file.
+
+#include "include/base/cef_bind.h"
+#include "include/cef_thread.h"
+#include "include/cef_waitable_event.h"
+#include "include/wrapper/cef_closure_task.h"
+#include "tests/gtest/include/gtest/gtest.h"
+
+// Test manual reset.
+TEST(WaitableEventTest, ManualReset) {
+ CefRefPtr<CefWaitableEvent> event =
+ CefWaitableEvent::CreateWaitableEvent(false, false);
+
+ EXPECT_FALSE(event->IsSignaled());
+
+ event->Signal();
+ EXPECT_TRUE(event->IsSignaled());
+ EXPECT_TRUE(event->IsSignaled());
+
+ event->Reset();
+ EXPECT_FALSE(event->IsSignaled());
+ EXPECT_FALSE(event->TimedWait(10));
+
+ event->Signal();
+ event->Wait();
+ EXPECT_TRUE(event->TimedWait(10));
+}
+
+// Test automatic reset.
+TEST(WaitableEventTest, AutomaticReset) {
+ CefRefPtr<CefWaitableEvent> event =
+ CefWaitableEvent::CreateWaitableEvent(true, false);
+
+ EXPECT_FALSE(event->IsSignaled());
+
+ event->Signal();
+ EXPECT_TRUE(event->IsSignaled());
+ EXPECT_FALSE(event->IsSignaled());
+
+ event->Reset();
+ EXPECT_FALSE(event->IsSignaled());
+ EXPECT_FALSE(event->TimedWait(10));
+
+ event->Signal();
+ event->Wait();
+ EXPECT_FALSE(event->TimedWait(10));
+
+ event->Signal();
+ EXPECT_TRUE(event->TimedWait(10));
+}
+
+namespace {
+
+void SignalEvent(CefWaitableEvent* event) {
+ event->Signal();
+}
+
+} // namespace
+
+// Tests that a WaitableEvent can be safely deleted when |Wait| is done without
+// additional synchronization.
+TEST(WaitableEventTest, WaitAndDelete) {
+ CefRefPtr<CefWaitableEvent> event =
+ CefWaitableEvent::CreateWaitableEvent(true, false);
+
+ CefRefPtr<CefThread> thread = CefThread::CreateThread("waitable_event_test");
+ thread->GetTaskRunner()->PostDelayedTask(
+ CefCreateClosureTask(base::Bind(SignalEvent,
+ base::Unretained(event.get()))), 10);
+
+ event->Wait();
+ event = nullptr;
+
+ thread->Stop();
+ thread = nullptr;
+}