~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to gears/base/common/mutex_win32.cc

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2008, Google Inc.
 
2
//
 
3
// Redistribution and use in source and binary forms, with or without
 
4
// modification, are permitted provided that the following conditions are met:
 
5
//
 
6
//  1. Redistributions of source code must retain the above copyright notice,
 
7
//     this list of conditions and the following disclaimer.
 
8
//  2. Redistributions in binary form must reproduce the above copyright notice,
 
9
//     this list of conditions and the following disclaimer in the documentation
 
10
//     and/or other materials provided with the distribution.
 
11
//  3. Neither the name of Google Inc. nor the names of its contributors may be
 
12
//     used to endorse or promote products derived from this software without
 
13
//     specific prior written permission.
 
14
//
 
15
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
16
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
17
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
18
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
19
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
20
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
21
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
22
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
24
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
25
 
 
26
#if defined(WIN32) || defined(OS_WINCE)
 
27
 
 
28
#include <assert.h>
 
29
#include <windows.h>
 
30
 
 
31
#include "gears/base/common/mutex.h"
 
32
#include "gears/base/common/stopwatch.h"  // For GetCurrentTimeMillis()
 
33
 
 
34
void ThreadYield() {
 
35
  Sleep(0);  // equivalent to 'yield' in Win32
 
36
}
 
37
 
 
38
Mutex::Mutex()
 
39
#ifdef DEBUG
 
40
    : is_locked_(false)
 
41
#endif
 
42
{
 
43
  InitializeCriticalSection(&crit_sec_);
 
44
}
 
45
 
 
46
 
 
47
Mutex::~Mutex() {
 
48
  DeleteCriticalSection(&crit_sec_);
 
49
}
 
50
 
 
51
 
 
52
void Mutex::Lock() {
 
53
  EnterCriticalSection(&crit_sec_);
 
54
#ifdef DEBUG
 
55
  assert(!is_locked_); // Google frowns upon mutex re-entrancy
 
56
  is_locked_ = true;
 
57
#endif
 
58
}
 
59
 
 
60
 
 
61
void Mutex::Unlock() {
 
62
#ifdef DEBUG
 
63
  assert(is_locked_);
 
64
  is_locked_ = false;
 
65
#endif
 
66
  LeaveCriticalSection(&crit_sec_);
 
67
}
 
68
 
 
69
 
 
70
// CondVar::Event implementation
 
71
//
 
72
// This class adds reference counting to windows manual events.
 
73
// Since Windows XP & earlier do not implement native condition variables,
 
74
// we're implementing a condition variable using windows events.
 
75
 
 
76
 
 
77
class CondVar::Event : public RefCounted {
 
78
 public:
 
79
  Event();
 
80
  ~Event();
 
81
  HANDLE Handle() const;
 
82
 private:
 
83
  HANDLE event_;
 
84
};
 
85
 
 
86
 
 
87
CondVar::Event::Event() {
 
88
  event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
 
89
}
 
90
 
 
91
 
 
92
CondVar::Event::~Event() {
 
93
#ifdef DEBUG
 
94
  BOOL result = CloseHandle(event_);
 
95
  assert(result == TRUE);
 
96
#else
 
97
  CloseHandle(event_);
 
98
#endif
 
99
}
 
100
 
 
101
 
 
102
HANDLE CondVar::Event::Handle() const {
 
103
  return event_;
 
104
}
 
105
 
 
106
 
 
107
// CondVar implementation
 
108
//
 
109
// Each event will correspond to a single call to CondVar::SignalAll.
 
110
// An event is created when the first interested party calls Wait.
 
111
// Subsequent calls to Wait will wait on the same event.
 
112
// When signal is called, the CondVar removes its reference to the event then
 
113
// sets the event to wake up the current waiters.
 
114
// While those waiters are being serviced, subsequent calls to Wait will result
 
115
// in the creation of a new event.
 
116
 
 
117
 
 
118
CondVar::CondVar() {
 
119
}
 
120
 
 
121
 
 
122
CondVar::~CondVar() {
 
123
#ifdef DEBUG
 
124
  // Make sure nobody is waiting.
 
125
  MutexLock locker(&current_event_mutex_);
 
126
  if (current_event_.get()) {
 
127
    assert(current_event_->GetRef() == 1);
 
128
    current_event_.reset();
 
129
  }
 
130
#endif
 
131
}
 
132
 
 
133
 
 
134
void CondVar::Wait(Mutex *mutex) {
 
135
  WaitWithTimeout(mutex, INFINITE);
 
136
}
 
137
 
 
138
 
 
139
bool CondVar::WaitWithTimeout(Mutex *mutex, int milliseconds) {
 
140
#ifdef DEBUG
 
141
  assert(mutex->is_locked_);
 
142
#endif
 
143
  scoped_refptr<Event> event;
 
144
  {
 
145
    MutexLock locker(&current_event_mutex_);
 
146
    if (current_event_.get() == 0) {
 
147
      current_event_ = new Event;
 
148
    }
 
149
    event = current_event_;
 
150
  }
 
151
  mutex->Unlock();
 
152
  DWORD result = WaitForSingleObject(event->Handle(), milliseconds);
 
153
  mutex->Lock();
 
154
  return result == WAIT_TIMEOUT;
 
155
}
 
156
 
 
157
 
 
158
void CondVar::SignalAll() {
 
159
  scoped_refptr<Event> old_event;
 
160
  {
 
161
    MutexLock locker(&current_event_mutex_);
 
162
    if (current_event_.get() == 0) return;
 
163
    old_event = current_event_;
 
164
    current_event_.reset();
 
165
  }
 
166
#ifdef DEBUG
 
167
  BOOL result = SetEvent(old_event->Handle());
 
168
  assert(result == TRUE);
 
169
#else
 
170
  SetEvent(old_event->Handle());
 
171
#endif
 
172
}
 
173
 
 
174
#endif  // defined(WIN32) || defined(OS_WINCE)