File: AutoLock.t

package info (click to toggle)
tom 1.1.1-2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 6,340 kB
  • ctags: 2,244
  • sloc: objc: 27,863; ansic: 9,804; sh: 7,411; yacc: 3,377; lex: 966; asm: 208; makefile: 62; cpp: 10
file content (125 lines) | stat: -rw-r--r-- 2,684 bytes parent folder | download
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 &copy; 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;