|
43 | 43 | import java.math.BigInteger;
|
44 | 44 | import java.security.SecureRandom;
|
45 | 45 | import java.util.ArrayList;
|
| 46 | +import java.util.Arrays; |
46 | 47 | import java.util.Collections;
|
47 | 48 | import java.util.List;
|
48 | 49 | import java.util.Map;
|
|
133 | 134 | import com.oracle.graal.python.util.OverflowException;
|
134 | 135 | import com.oracle.truffle.api.CompilerDirectives;
|
135 | 136 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
| 137 | +import com.oracle.truffle.api.ThreadLocalAction; |
136 | 138 | import com.oracle.truffle.api.dsl.Bind;
|
137 | 139 | import com.oracle.truffle.api.dsl.Cached;
|
138 | 140 | import com.oracle.truffle.api.dsl.Cached.Exclusive;
|
@@ -2571,8 +2573,30 @@ public abstract static class ExitNode extends PythonUnaryBuiltinNode {
|
2571 | 2573 | @TruffleBoundary
|
2572 | 2574 | @Specialization
|
2573 | 2575 | Object exit(int status) {
|
2574 |
| - // TODO: use a safepoint action to throw this exception to all running threads |
2575 |
| - throw new PythonExitException(this, status); |
| 2576 | + PythonContext context = getContext(); |
| 2577 | + if (context.getOption(PythonOptions.RunViaLauncher)) { |
| 2578 | + Runtime.getRuntime().halt(status); |
| 2579 | + } |
| 2580 | + List<Thread> otherThreads = new ArrayList<>(Arrays.asList(context.getThreads())); |
| 2581 | + otherThreads.remove(context.getMainThread()); |
| 2582 | + otherThreads.remove(Thread.currentThread()); |
| 2583 | + context.getEnv().submitThreadLocal(otherThreads.toArray(new Thread[0]), new ThreadLocalAction(true, false) { |
| 2584 | + @Override |
| 2585 | + protected void perform(Access access) { |
| 2586 | + throw new ThreadDeath(); |
| 2587 | + } |
| 2588 | + }); |
| 2589 | + if (Thread.currentThread() == context.getMainThread()) { |
| 2590 | + throw new PythonExitException(this, status); |
| 2591 | + } else { |
| 2592 | + context.getEnv().submitThreadLocal(new Thread[]{context.getMainThread()}, new ThreadLocalAction(true, false) { |
| 2593 | + @Override |
| 2594 | + protected void perform(Access access) { |
| 2595 | + throw new PythonExitException(ExitNode.this, status); |
| 2596 | + } |
| 2597 | + }); |
| 2598 | + } |
| 2599 | + throw new ThreadDeath(); |
2576 | 2600 | }
|
2577 | 2601 | }
|
2578 | 2602 |
|
|
0 commit comments