38 thread.start |
38 thread.start |
39 thread |
39 thread |
40 } |
40 } |
41 |
41 |
42 |
42 |
43 /* self */ |
43 /* self-thread */ |
44 |
44 |
45 def self: Isabelle_Thread = |
45 def self: Isabelle_Thread = |
46 Thread.currentThread match { |
46 Thread.currentThread match { |
47 case thread: Isabelle_Thread => thread |
47 case thread: Isabelle_Thread => thread |
48 case _ => error("Isabelle-specific thread required") |
48 case _ => error("Isabelle-specific thread required") |
49 } |
49 } |
50 |
50 |
51 |
51 |
52 /* interrupts */ |
52 /* interrupt handlers */ |
53 |
53 |
54 type Interrupt_Handler = Isabelle_Thread => Unit |
54 object Interrupt_Handler |
|
55 { |
|
56 def apply(handle: Isabelle_Thread => Unit, name: String = "handler"): Interrupt_Handler = |
|
57 new Interrupt_Handler(handle, name) |
|
58 |
|
59 val interruptible: Interrupt_Handler = |
|
60 Interrupt_Handler(_.raise_interrupt, name = "interruptible") |
|
61 |
|
62 val uninterruptible: Interrupt_Handler = |
|
63 Interrupt_Handler(_.postpone_interrupt, name = "uninterruptible") |
|
64 } |
|
65 |
|
66 class Interrupt_Handler private(handle: Isabelle_Thread => Unit, name: String) |
|
67 extends Function[Isabelle_Thread, Unit] |
|
68 { |
|
69 def apply(thread: Isabelle_Thread) { handle(thread) } |
|
70 override def toString: String = name |
|
71 } |
55 |
72 |
56 def interrupt_handler[A](handler: Interrupt_Handler)(body: => A): A = |
73 def interrupt_handler[A](handler: Interrupt_Handler)(body: => A): A = |
57 self.interrupt_handler(handler)(body) |
74 self.interrupt_handler(handler)(body) |
58 |
75 |
59 def interruptible[A](body: => A): A = interrupt_handler(_.raise_interrupt)(body) |
76 def interrupt_handler[A](handle: Isabelle_Thread => Unit)(body: => A): A = |
60 def uninterruptible[A](body: => A): A = interrupt_handler(_.postpone_interrupt)(body) |
77 self.interrupt_handler(Interrupt_Handler(handle))(body) |
61 |
78 |
62 |
79 def interruptible[A](body: => A): A = |
63 /* pool */ |
80 interrupt_handler(Interrupt_Handler.interruptible)(body) |
|
81 |
|
82 def uninterruptible[A](body: => A): A = |
|
83 interrupt_handler(Interrupt_Handler.uninterruptible)(body) |
|
84 |
|
85 |
|
86 /* thread pool */ |
64 |
87 |
65 lazy val pool: ThreadPoolExecutor = |
88 lazy val pool: ThreadPoolExecutor = |
66 { |
89 { |
67 val m = Value.Int.unapply(System.getProperty("isabelle.threads", "0")) getOrElse 0 |
90 val m = Value.Int.unapply(System.getProperty("isabelle.threads", "0")) getOrElse 0 |
68 val n = if (m > 0) m else (Runtime.getRuntime.availableProcessors max 1) min 8 |
91 val n = if (m > 0) m else (Runtime.getRuntime.availableProcessors max 1) min 8 |
147 thread.setPriority(pri) |
170 thread.setPriority(pri) |
148 thread.setDaemon(daemon) |
171 thread.setDaemon(daemon) |
149 |
172 |
150 override def run { main.run() } |
173 override def run { main.run() } |
151 |
174 |
|
175 def is_self: Boolean = Thread.currentThread == thread |
|
176 |
152 |
177 |
153 /* interrupt state */ |
178 /* interrupt state */ |
154 |
179 |
155 private var interrupt_pending: Boolean = false |
180 // synchronized, with concurrent changes |
|
181 private var interrupt_postponed: Boolean = false |
|
182 |
|
183 def clear_interrupt: Boolean = synchronized |
|
184 { |
|
185 val was_interrupted = isInterrupted || interrupt_postponed |
|
186 Exn.Interrupt.dispose() |
|
187 interrupt_postponed = false |
|
188 was_interrupted |
|
189 } |
156 |
190 |
157 def raise_interrupt: Unit = synchronized |
191 def raise_interrupt: Unit = synchronized |
158 { |
192 { |
159 interrupt_pending = false |
193 interrupt_postponed = false |
160 super.interrupt() |
194 super.interrupt() |
161 } |
195 } |
162 |
196 |
163 def postpone_interrupt: Unit = synchronized |
197 def postpone_interrupt: Unit = synchronized |
164 { |
198 { |
165 interrupt_pending = true |
199 interrupt_postponed = true |
166 Exn.Interrupt.dispose() |
200 Exn.Interrupt.dispose() |
167 } |
201 } |
168 |
202 |
169 |
203 |
170 /* interrupt handler */ |
204 /* interrupt handler */ |
171 |
205 |
172 private var handler: Isabelle_Thread.Interrupt_Handler = (_.raise_interrupt) |
206 // non-synchronized, only changed on self-thread |
173 |
207 @volatile private var handler = Isabelle_Thread.Interrupt_Handler.interruptible |
174 override def interrupt: Unit = (synchronized { handler })(thread) |
208 |
|
209 override def interrupt: Unit = handler(thread) |
175 |
210 |
176 def interrupt_handler[A](new_handler: Isabelle_Thread.Interrupt_Handler)(body: => A): A = |
211 def interrupt_handler[A](new_handler: Isabelle_Thread.Interrupt_Handler)(body: => A): A = |
177 { |
212 { |
178 require(Thread.currentThread == thread) |
213 require(is_self) |
179 |
214 |
180 val old_handler = handler |
215 val old_handler = handler |
181 handler = new_handler |
216 handler = new_handler |
182 try { body } |
217 try { |
|
218 if (clear_interrupt) interrupt |
|
219 body |
|
220 } |
183 finally { |
221 finally { |
184 synchronized { |
222 handler = old_handler |
185 handler = old_handler |
223 if (clear_interrupt) interrupt |
186 if (isInterrupted || interrupt_pending) thread.interrupt |
|
187 } |
|
188 Exn.Interrupt.expose() |
224 Exn.Interrupt.expose() |
189 } |
225 } |
190 } |
226 } |
191 } |
227 } |