1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/system_wrappers/source/rw_lock_win.h"
12
13#include "webrtc/system_wrappers/interface/trace.h"
14
15namespace webrtc {
16
17static bool native_rw_locks_supported = false;
18static bool module_load_attempted = false;
19static HMODULE library = NULL;
20
21typedef void (WINAPI* InitializeSRWLock)(PSRWLOCK);
22
23typedef void (WINAPI* AcquireSRWLockExclusive)(PSRWLOCK);
24typedef void (WINAPI* ReleaseSRWLockExclusive)(PSRWLOCK);
25
26typedef void (WINAPI* AcquireSRWLockShared)(PSRWLOCK);
27typedef void (WINAPI* ReleaseSRWLockShared)(PSRWLOCK);
28
29InitializeSRWLock       initialize_srw_lock;
30AcquireSRWLockExclusive acquire_srw_lock_exclusive;
31AcquireSRWLockShared    acquire_srw_lock_shared;
32ReleaseSRWLockShared    release_srw_lock_shared;
33ReleaseSRWLockExclusive release_srw_lock_exclusive;
34
35RWLockWin::RWLockWin() {
36  initialize_srw_lock(&lock_);
37}
38
39RWLockWin* RWLockWin::Create() {
40  if (!LoadModule()) {
41    return NULL;
42  }
43  return new RWLockWin();
44}
45
46void RWLockWin::AcquireLockExclusive() {
47  acquire_srw_lock_exclusive(&lock_);
48}
49
50void RWLockWin::ReleaseLockExclusive() {
51  release_srw_lock_exclusive(&lock_);
52}
53
54void RWLockWin::AcquireLockShared() {
55  acquire_srw_lock_shared(&lock_);
56}
57
58void RWLockWin::ReleaseLockShared() {
59  release_srw_lock_shared(&lock_);
60}
61
62bool RWLockWin::LoadModule() {
63  if (module_load_attempted) {
64    return native_rw_locks_supported;
65  }
66  module_load_attempted = true;
67  // Use native implementation if supported (i.e Vista+)
68  library = LoadLibrary(TEXT("Kernel32.dll"));
69  if (!library) {
70    return false;
71  }
72  WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll");
73
74  initialize_srw_lock =
75    (InitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
76
77  acquire_srw_lock_exclusive =
78    (AcquireSRWLockExclusive)GetProcAddress(library,
79                                            "AcquireSRWLockExclusive");
80  release_srw_lock_exclusive =
81    (ReleaseSRWLockExclusive)GetProcAddress(library,
82                                            "ReleaseSRWLockExclusive");
83  acquire_srw_lock_shared =
84    (AcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
85  release_srw_lock_shared =
86    (ReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
87
88  if (initialize_srw_lock && acquire_srw_lock_exclusive &&
89      release_srw_lock_exclusive && acquire_srw_lock_shared &&
90      release_srw_lock_shared) {
91    WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Native RW Lock");
92    native_rw_locks_supported = true;
93  }
94  return native_rw_locks_supported;
95}
96
97}  // namespace webrtc
98