| Module | Sync_m |
| In: |
lib/sync.rb
|
| RCS_ID | = | '-$Header$-' | ||
| UN | = | :UN | lock mode | |
| SH | = | :SH | ||
| EX | = | :EX |
| sync_ex_count | [RW] | |
| sync_ex_locker | [RW] | |
| sync_mode | [RW] | |
| sync_sh_locker | [RW] | |
| sync_upgrade_waiting | [RW] | |
| sync_waiting | [RW] |
# File lib/sync.rb, line 90
90: def Sync_m.append_features(cl)
91: super
92: unless cl.instance_of?(Module)
93: # do nothing for Modules
94: # make aliases and include the proper module.
95: define_aliases(cl)
96: end
97: end
# File lib/sync.rb, line 78
78: def Sync_m.define_aliases(cl)
79: cl.module_eval %q{
80: alias locked? sync_locked?
81: alias shared? sync_shared?
82: alias exclusive? sync_exclusive?
83: alias lock sync_lock
84: alias unlock sync_unlock
85: alias try_lock sync_try_lock
86: alias synchronize sync_synchronize
87: }
88: end
# File lib/sync.rb, line 99
99: def Sync_m.extend_object(obj)
100: super
101: obj.sync_extended
102: end
# File lib/sync.rb, line 104
104: def sync_extended
105: unless (defined? locked? and
106: defined? shared? and
107: defined? exclusive? and
108: defined? lock and
109: defined? unlock and
110: defined? try_lock and
111: defined? synchronize)
112: Sync_m.define_aliases(class<<self;self;end)
113: end
114: sync_initialize
115: end
# File lib/sync.rb, line 140
140: def sync_lock(m = EX)
141: return unlock if m == UN
142:
143: until (Thread.critical = true; sync_try_lock_sub(m))
144: if sync_sh_locker[Thread.current]
145: sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
146: sync_sh_locker.delete(Thread.current)
147: else
148: sync_waiting.push Thread.current
149: end
150: Thread.stop
151: end
152: Thread.critical = false
153: self
154: end
# File lib/sync.rb, line 226
226: def sync_synchronize(mode = EX)
227: begin
228: sync_lock(mode)
229: yield
230: ensure
231: sync_unlock
232: end
233: end
locking methods.
# File lib/sync.rb, line 131
131: def sync_try_lock(mode = EX)
132: return unlock if sync_mode == UN
133:
134: Thread.critical = true
135: ret = sync_try_lock_sub(sync_mode)
136: Thread.critical = false
137: ret
138: end
# File lib/sync.rb, line 156
156: def sync_unlock(m = EX)
157: Thread.critical = true
158: if sync_mode == UN
159: Thread.critical = false
160: Err::UnknownLocker.Fail(Thread.current)
161: end
162:
163: m = sync_mode if m == EX and sync_mode == SH
164:
165: runnable = false
166: case m
167: when UN
168: Thread.critical = false
169: Err::UnknownLocker.Fail(Thread.current)
170:
171: when EX
172: if sync_ex_locker == Thread.current
173: if (self.sync_ex_count = sync_ex_count - 1) == 0
174: self.sync_ex_locker = nil
175: if sync_sh_locker.include?(Thread.current)
176: self.sync_mode = SH
177: else
178: self.sync_mode = UN
179: end
180: runnable = true
181: end
182: else
183: Err::UnknownLocker.Fail(Thread.current)
184: end
185:
186: when SH
187: if (count = sync_sh_locker[Thread.current]).nil?
188: Err::UnknownLocker.Fail(Thread.current)
189: else
190: if (sync_sh_locker[Thread.current] = count - 1) == 0
191: sync_sh_locker.delete(Thread.current)
192: if sync_sh_locker.empty? and sync_ex_count == 0
193: self.sync_mode = UN
194: runnable = true
195: end
196: end
197: end
198: end
199:
200: if runnable
201: if sync_upgrade_waiting.size > 0
202: for k, v in sync_upgrade_waiting
203: sync_sh_locker[k] = v
204: end
205: wait = sync_upgrade_waiting
206: self.sync_upgrade_waiting = []
207: Thread.critical = false
208:
209: for w, v in wait
210: w.run
211: end
212: else
213: wait = sync_waiting
214: self.sync_waiting = []
215: Thread.critical = false
216: for w in wait
217: w.run
218: end
219: end
220: end
221:
222: Thread.critical = false
223: self
224: end
# File lib/sync.rb, line 245
245: def sync_initialize
246: @sync_mode = UN
247: @sync_waiting = []
248: @sync_upgrade_waiting = []
249: @sync_sh_locker = Hash.new
250: @sync_ex_locker = nil
251: @sync_ex_count = 0
252: end
# File lib/sync.rb, line 259
259: def sync_try_lock_sub(m)
260: case m
261: when SH
262: case sync_mode
263: when UN
264: self.sync_mode = m
265: sync_sh_locker[Thread.current] = 1
266: ret = true
267: when SH
268: count = 0 unless count = sync_sh_locker[Thread.current]
269: sync_sh_locker[Thread.current] = count + 1
270: ret = true
271: when EX
272: # in EX mode, lock will upgrade to EX lock
273: if sync_ex_locker == Thread.current
274: self.sync_ex_count = sync_ex_count + 1
275: ret = true
276: else
277: ret = false
278: end
279: end
280: when EX
281: if sync_mode == UN or
282: sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
283: self.sync_mode = m
284: self.sync_ex_locker = Thread.current
285: self.sync_ex_count = 1
286: ret = true
287: elsif sync_mode == EX && sync_ex_locker == Thread.current
288: self.sync_ex_count = sync_ex_count + 1
289: ret = true
290: else
291: ret = false
292: end
293: else
294: Thread.critical = false
295: Err::LockModeFailer.Fail mode
296: end
297: return ret
298: end