1/*
2 * Copyright 2011 Google Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
18#define SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
19
20#if defined (WIN32)
21#include <windows.h>
22#else  // Assume pthread.
23#include <pthread.h>
24#include <errno.h>
25#endif
26
27#include "sfntly/port/type.h"
28
29namespace sfntly {
30
31#if defined (WIN32)
32  typedef CRITICAL_SECTION OSLockType;
33#else  // Assume pthread.
34  typedef pthread_mutex_t OSLockType;
35#endif
36
37class Lock {
38 public:
39  Lock();
40  ~Lock();
41
42  // If the lock is not held, take it and return true.  If the lock is already
43  // held by something else, immediately return false.
44  bool Try();
45
46  // Take the lock, blocking until it is available if necessary.
47  void Acquire();
48
49  // Release the lock.  This must only be called by the lock's holder: after
50  // a successful call to Try, or a call to Lock.
51  void Unlock();
52
53 private:
54  OSLockType os_lock_;
55  NO_COPY_AND_ASSIGN(Lock);
56};
57
58// A helper class that acquires the given Lock while the AutoLock is in scope.
59class AutoLock {
60 public:
61  explicit AutoLock(Lock& lock) : lock_(lock) {
62    lock_.Acquire();
63  }
64
65  ~AutoLock() {
66    lock_.Unlock();
67  }
68
69 private:
70  Lock& lock_;
71  NO_COPY_AND_ASSIGN(AutoLock);
72};
73
74}  // namespace sfntly
75
76#endif  // SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
77