1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/trace/common/service_util.h"
16 :
17 : #include "base/bind.h"
18 : #include "base/strings/stringprintf.h"
19 : #include "base/synchronization/condition_variable.h"
20 : #include "base/threading/thread.h"
21 : #include "gtest/gtest.h"
22 :
23 : namespace trace {
24 : namespace common {
25 :
26 : namespace {
27 :
28 : typedef base::Callback<bool()> BoolCallback;
29 :
30 : void InvokeOnAnotherThreadTask(BoolCallback task,
31 : base::Lock* lock,
32 : base::ConditionVariable* cv,
33 : bool* result,
34 E : bool* finished) {
35 E : DCHECK(lock != NULL);
36 E : DCHECK(cv != NULL);
37 E : DCHECK(result != NULL);
38 :
39 E : *result = task.Run();
40 :
41 : {
42 E : base::AutoLock auto_lock(*lock);
43 E : *finished = true;
44 E : cv->Signal();
45 E : }
46 E : }
47 :
48 E : bool InvokeOnAnotherThread(BoolCallback task) {
49 E : base::Lock lock;
50 E : base::ConditionVariable cv(&lock);
51 E : bool result = false;
52 E : bool finished = false;
53 :
54 E : base::Thread worker("worker");
55 E : worker.Start();
56 : worker.message_loop()->PostTask(
57 : FROM_HERE,
58 : base::Bind(&InvokeOnAnotherThreadTask,
59 : task,
60 : base::Unretained(&lock),
61 : base::Unretained(&cv),
62 : base::Unretained(&result),
63 E : base::Unretained(&finished)));
64 :
65 E : base::AutoLock hold(lock);
66 E : while (!finished)
67 E : cv.Wait();
68 :
69 E : worker.Stop();
70 :
71 E : return result;
72 E : }
73 :
74 : } // namespace
75 :
76 E : TEST(ServiceUtilTest, AcquireMutex) {
77 : // We generate a mutex name that will be unique to this process so that
78 : // running multiple copies of the unittest doesn't cause problems.
79 : std::wstring mutex_name = base::StringPrintf(
80 E : L"ServiceUtilTest-AcquireMutex-%08X", ::GetCurrentProcessId());
81 :
82 : // We should be able to acquire the mutex.
83 E : base::win::ScopedHandle mutex1;
84 E : EXPECT_TRUE(AcquireMutex(mutex_name, &mutex1));
85 :
86 : // We should not be able to acquire the mutex, as it is already held.
87 E : base::win::ScopedHandle mutex2;
88 : EXPECT_FALSE(InvokeOnAnotherThread(base::Bind(&AcquireMutex,
89 : mutex_name,
90 E : base::Unretained(&mutex2))));
91 :
92 : // Releasing the mutex should make us be able to acquire it once again.
93 E : ::ReleaseMutex(mutex1.Get());
94 E : mutex1.Close();
95 E : EXPECT_TRUE(AcquireMutex(mutex_name, &mutex2));
96 E : }
97 :
98 E : TEST(ServiceUtilTest, InitEvent) {
99 : std::wstring event_name = base::StringPrintf(
100 E : L"ServiceUtilTest-InitEvent-%08X", ::GetCurrentProcessId());
101 :
102 E : base::win::ScopedHandle named_event;
103 E : EXPECT_TRUE(InitEvent(event_name, &named_event));
104 :
105 E : ::SetEvent(named_event.Get());
106 :
107 E : ::WaitForSingleObject(named_event.Get(), INFINITE);
108 E : }
109 :
110 : } // namespace common
111 : } // namespace trace
|