1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
<copyright> AutoLock class.
Written by <a href="mailto:silovic@zeois.fer.hr">Miroslav Silovic</a>
Copyright © 1999 Pieter J. Schoenmakers.
This file is part of TOM. TOM is distributed under the terms of the
TOM License, a copy of which can be found in the TOM distribution; see
the file LICENSE.
<id>$Id: AutoLock.t,v 1.2 1999/09/28 21:57:57 tiggr Exp $</id>
</copyright>
<doc> This extension provides deadlock-condition. </doc>
implementation class
Conditions extension AutoLock
{
static ConditionClass deadlock-condition;
}
end;
implementation instance
Conditions extension AutoLock
end;
<doc> Necessary glue within {Thread} class. </doc>
implementation class
Thread extension AutoLock
end;
implementation instance
Thread extension AutoLock
{
<doc> The thread which has to release a lock so we can continue. </doc>
public Thread blockedBy;
}
<doc> Return {TRUE} if we are waiting for the argument to finish. This
includes implied waiting. </doc>
boolean
isWaitingFor Thread t
{
Thread i;
for (i = blockedBy; !!i; i = [i blockedBy])
if (i == t)
return YES;
return NO;
}
void
setBlockedBy Thread t
{
blockedBy = t;
}
end;
<doc> Recursive lock with deadlock detection. If deadlock occurs, the
faulty thread will be unjammed by receiving deadlock-condition. </doc>
implementation class
AutoLock: RecursiveLock, Conditions
<doc> Initialisation method. </doc>
void
load MutableArray arguments
{
deadlock-condition = [ConditionClass with lock-condition
name "deadlock-condition"];
}
end;
implementation instance
AutoLock
{
<doc> The thread holding the lock, {nil} if none. </doc>
Thread owner;
}
<doc> Designated initializer. </doc>
id
init
{
= [super (RecursiveLock) init];
}
void
lock
{
Thread current_thread = [Thread current];
/* Check the simplest case: fallback to recursive lock. */
if (!owner || owner == current_thread)
{
[super lock];
owner = current_thread;
}
else if (
{/* First set the upward pointer in case some other thread is
scanning. This will make all the concurrent loop searches
fail for at least one thread. */
[current_thread setBlockedBy owner];
[owner isWaitingFor current_thread];
})
{
[current_thread setBlockedBy nil];
/* Must be raised, because this thread isn't going anywhere. */
[[Condition for self class deadlock-condition
message "deadlock detected"] raise];
}
else
{
[super lock];
owner = current_thread;
[current_thread setBlockedBy nil];
}
}
void
unlock
{
[super unlock];
owner = nil;
}
end;
|