1 mike 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "Condition.h"
35 #include "PegasusAssert.h"
36
37 PEGASUS_NAMESPACE_BEGIN
38
39 //==============================================================================
40 //
41 // PEGASUS_HAVE_PTHREADS
42 //
43 mike 1.2 //==============================================================================
44
45 #if defined(PEGASUS_HAVE_PTHREADS)
46
47 Condition::Condition()
48 {
49 pthread_cond_init(&_rep.cond, NULL);
50 }
51
52 Condition::~Condition()
53 {
54 pthread_cond_destroy(&_rep.cond);
55 }
56
57 void Condition::signal()
58 {
59 pthread_cond_signal(&_rep.cond);
60 }
61
62 void Condition::wait(Mutex& lock)
63 {
64 mike 1.2 pthread_cond_wait(&_rep.cond, &lock._rep.mutex);
65 }
66
67 #endif /* PEGASUS_HAVE_PTHREADS */
68
69 //==============================================================================
70 //
71 // PEGASUS_HAVE_WINDOWS_THREADS
72 //
73 //==============================================================================
74
75 #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
76
77 ConditionWaiter* _get_waiter()
78 {
|
81 mike 1.2 // be leaked when the thread exists.
82
83 static DWORD _waiter_tls = TlsAlloc();
84
85 // Obtain (or create) the waiter for this thread.
86
87 ConditionWaiter* waiter = (ConditionWaiter*)TlsGetValue(_waiter_tls);
88
89 if (waiter == 0)
90 {
91 waiter = new ConditionWaiter;
92 waiter->event = CreateEvent(0, TRUE, FALSE, 0);
93 PEGASUS_DEBUG_ASSERT(waiter->event != NULL);
94 TlsSetValue(_waiter_tls, waiter);
95 }
96
97 return waiter;
98 }
99
100 Condition::Condition()
101 {
102 mike 1.2 }
103
104 Condition::~Condition()
105 {
106 // Remove all of the waiters without deleting them (they are owned by
107 // the thread-local-storage slot defined above and should never be
108 // deleted.
109
110 while (_rep.waiters.size())
111 _rep.waiters.remove_front();
112 }
113
114 void Condition::signal()
115 {
116 // Remove the waiter at the front of the queue.
117
118 ConditionWaiter* waiter = _rep.waiters.remove_front();
119
120 if (waiter)
121 SetEvent(waiter->event);
122 }
123 mike 1.2
124 void Condition::wait(Mutex& mutex)
125 {
126 // Insert this thread's waiter at end of waiters queue.
127
128 ConditionWaiter* waiter = _get_waiter();
129 _rep.waiters.insert_back(waiter);
130
131 // Unlock the mutex.
132
133 size_t count = mutex._rep.count;
134
135 for (size_t i = 0; i < count; i++)
136 mutex.unlock();
137
138 // Wait for a signal.
139
140 DWORD rc = WaitForSingleObject(waiter->event, INFINITE);
141 PEGASUS_DEBUG_ASSERT(rc == WAIT_OBJECT_0);
142
143 // Relock the mutex.
144 mike 1.2
145 for (size_t i = 0; i < count; i++)
146 mutex.lock();
147
148 // Reset the event.
149
150 ResetEvent(waiter->event);
151 }
152
153 #endif /* PEGASUS_HAVE_WINDOWS_THREADS */
154
155 PEGASUS_NAMESPACE_END
|