2 * Copyright (c) 2005, Eric Crahen
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef __ZTBLOCKINGSTATE_H__
24 #define __ZTBLOCKINGSTATE_H__
34 * A Status is associated with each Thread's Monitor. Monitors rely on a
35 * Status object for providing information that will affect a blocking operations.
39 //! Aggregate of pending status changes
40 volatile unsigned short _pending
;
43 volatile unsigned short _mask
;
47 //! State for the monitor
60 ANYTHING
= (~INVALID
& ~CANCELED
)
64 Status() : _pending((unsigned short)INVALID
), _mask((unsigned short)ANYTHING
) { }
67 * Set the mask for the STATE's that next() will report.
68 * STATE's not covered by the interest mask can still be
69 * set, they just aren't reported until the mask is changed
70 * to cover that STATE.
73 * @pre accessed ONLY by the owning thread.
75 void interest(STATE mask
) {
76 _mask
= static_cast<unsigned short>(mask
);
79 bool masked(STATE mask
) {
80 return (_mask
& static_cast<unsigned short>(mask
)) == 0;
84 * Return true if next() will return a STATE covered
85 * by the current interest mask and by the mask given
88 * @param unsigned short
89 * @pre accessed ONLY by the owning thread.
91 bool pending(unsigned short mask
) {
93 assert(mask
!= INVALID
);
94 return ((_pending
& _mask
) & mask
) != INVALID
;
99 * Check the state without the interest mask.
102 * @return true if the flag is set
103 * @pre access must be serial
105 bool examine(STATE state
) {
106 return (_pending
& static_cast<unsigned short>(state
)) != INVALID
;
110 * Add the flags to the current state.
112 * @param interest - the flags to add to the current state.
113 * @pre access must be serial
115 void push(STATE interest
) {
116 _pending
|= interest
;
120 * Clear the flags from the current state
122 * @param interest - the flags to clear from the current state.
123 * @pre access must be serial
125 void clear(STATE interest
) {
127 assert(interest
!= INVALID
);
128 assert(interest
!= ANYTHING
);
129 assert(interest
!= CANCELED
);
131 _pending
&= ~interest
;
136 * Get the next state from set that has accumulated. The order STATES are
137 * reported in is SIGNALED, TIMEOUT, or INTERRUPTED. Setting the
138 * intrest mask allows certain state to be selectively ignored for
139 * a time - but not lost. The states will become visible again as soon
140 * as the interest mask is changed appropriately. The interest mask is
141 * generally used to create uninterruptable waits (waiting for threads
142 * to start, reacquiring a conditions predicate lock, etc)
145 * @pre access must be serial
149 STATE state
= INVALID
;
151 if(((_pending
& _mask
) & SIGNALED
) != 0) {
153 // Absorb the timeout if it happens when a signal
154 // is available at the same time
155 _pending
&= ~(SIGNALED
|TIMEDOUT
);
158 } else if(((_pending
& _mask
) & TIMEDOUT
) != 0) {
160 _pending
&= ~TIMEDOUT
;
163 } else if(((_pending
& _mask
) & INTERRUPTED
) != 0) {
165 _pending
&= ~INTERRUPTED
;
170 assert(state
!= INVALID
);
177 }; // namespace ZThread