0001: /*
0002: * JaclSetInterrupted.java --
0003: *
0004: * This file contains loads classes needed by the Jacl
0005: * test suite.
0006: *
0007: * Copyright (c) 2006 Mo DeJong.
0008: *
0009: * See the file "license.terms" for information on usage and
0010: * redistribution of this file, and for a DISCLAIMER OF ALL
0011: * WARRANTIES.
0012: *
0013: * RCS: @(#) $Id: JaclSetInterrupted.java,v 1.2 2006/05/17 01:59:11 mdejong Exp $
0014: *
0015: */
0016:
0017: package tcl.lang;
0018:
0019: import java.util.*;
0020:
0021: public class JaclSetInterrupted {
0022:
0023: // Test method that will create an Interp in a new thread
0024: // and eval some code in the interp.
0025:
0026: public static boolean ThreadInterrupt1() throws Exception {
0027: ThreadInterrupt1Runner r = new ThreadInterrupt1Runner();
0028: Thread thr = new Thread(r);
0029: thr.start();
0030: thr.join(); // Wait for thread to die
0031: return r.passed;
0032: }
0033:
0034: static class ThreadInterrupt1Runner implements Runnable {
0035: Interp interp;
0036: boolean passed = false;
0037:
0038: public void run() {
0039: try {
0040: interp = new Interp();
0041:
0042: // Load util Tcl commands and setup interp.
0043:
0044: interp.eval("source SetInterrupted.tcl", 0);
0045: interp.eval("setup", 0);
0046: } catch (TclException te) {
0047: // Should never be reached
0048: te.printStackTrace(System.err);
0049: return;
0050: }
0051:
0052: // Invoke command, this invocation should be interrupted
0053: // at loop 50.
0054:
0055: try {
0056: interp.eval("set loop 0", 0);
0057: interp.eval("ti1_cmd2", 0);
0058: } catch (TclException te) {
0059: // Should never get here
0060: te.printStackTrace(System.err);
0061: } catch (TclInterruptedException te) {
0062: passed = true;
0063: } finally {
0064: interp.dispose();
0065: }
0066: return;
0067: }
0068: }
0069:
0070: // Test method that will create an Interp in a new thread
0071: // and start a loop that should be interrupted.
0072:
0073: public static boolean ThreadInterrupt2() throws Exception {
0074: ThreadInterrupt2Runner r = new ThreadInterrupt2Runner();
0075: Thread thr = new Thread(r);
0076: thr.start();
0077:
0078: // Wait for other thread to enter while loop, then set
0079: // interrupt in the interp.
0080:
0081: while (!r.isRunning()) {
0082: try {
0083: Thread.sleep(50);
0084: } catch (InterruptedException e) {
0085: }
0086: }
0087: r.interp.setInterrupted();
0088:
0089: thr.join(); // Wait for other thread to die
0090: return r.passed;
0091: }
0092:
0093: static class ThreadInterrupt2Runner implements Runnable {
0094: Interp interp;
0095: boolean passed = false;
0096: boolean running = false;
0097:
0098: public void run() {
0099: try {
0100: interp = new Interp();
0101:
0102: // Load util Tcl commands and setup interp.
0103:
0104: interp.eval("source SetInterrupted.tcl", 0);
0105: interp.eval("setup", 0);
0106: } catch (TclException te) {
0107: // Should never be reached
0108: te.printStackTrace(System.err);
0109: return;
0110: }
0111:
0112: // Invoke command, this invocation should be interrupted
0113: // at some point during the while loop. The other thread
0114: // will set the interrupt flag by invoking interp.setInterrupt().
0115:
0116: try {
0117: interp.eval("set loop 0", 0);
0118: running = true;
0119: interp.eval("ti2_cmd2", 0);
0120: } catch (TclException te) {
0121: // Should never get here
0122: te.printStackTrace(System.err);
0123: } catch (TclInterruptedException te) {
0124: passed = true;
0125: } finally {
0126: interp.dispose();
0127: }
0128: return;
0129: }
0130:
0131: // Return true when Tcl code has entered while loop
0132:
0133: public boolean isRunning() {
0134: return running;
0135: }
0136: }
0137:
0138: // Test method that will create an Interp in a new thread
0139: // and then process events from the Tcl event queue.
0140:
0141: public static boolean ThreadInterrupt3() throws Exception {
0142: ThreadInterrupt3Runner r = new ThreadInterrupt3Runner();
0143: Thread thr = new Thread(r);
0144: thr.start();
0145:
0146: // Wait for other thread to enter event processing loop
0147: // and then set the interrupt in the interp.
0148:
0149: while (!r.isRunning()) {
0150: try {
0151: Thread.sleep(50);
0152: } catch (InterruptedException e) {
0153: }
0154: }
0155: r.interp.setInterrupted();
0156:
0157: thr.join(); // Wait for thread to die
0158: return r.passed;
0159: }
0160:
0161: static class ThreadInterrupt3Runner implements Runnable {
0162: Interp interp;
0163: boolean passed = false;
0164: boolean running = false;
0165: final boolean debug = false;
0166:
0167: public void run() {
0168: try {
0169: interp = new Interp();
0170:
0171: // Load util Tcl commands and setup interp.
0172:
0173: interp.eval("source SetInterrupted.tcl", 0);
0174: interp.eval("setup", 0);
0175: } catch (TclException te) {
0176: // Should never be reached
0177: te.printStackTrace(System.err);
0178: return;
0179: }
0180: if (debug) {
0181: System.out.println("interp was setup");
0182: }
0183:
0184: // Process events from the Tcl event queue, if execution
0185: // is interrupted then stop processing events. Since
0186: // there should be no events to process, this loop
0187: // should just wait in the doOneEvent call.
0188:
0189: Notifier notifier = interp.getNotifier();
0190: try {
0191: while (true) {
0192: if (debug) {
0193: System.out
0194: .println("invoking notifier.doOneEvent()");
0195: }
0196:
0197: running = true;
0198: notifier.doOneEvent(TCL.ALL_EVENTS);
0199: }
0200: } catch (TclInterruptedException te) {
0201: if (debug) {
0202: System.out
0203: .println("caught TclInterruptedException");
0204: te.printStackTrace(System.out);
0205: }
0206:
0207: passed = true;
0208:
0209: // Note that this method does not attempt to remove
0210: // events from the event queue.
0211:
0212: } finally {
0213: if (debug) {
0214: System.out.println("Interp.dispose()");
0215: }
0216:
0217: interp.dispose();
0218: }
0219:
0220: return;
0221: }
0222:
0223: public boolean isRunning() {
0224: return running;
0225: }
0226:
0227: }
0228:
0229: // Test method that will create an Interp in a new thread
0230: // and then process events from the Tcl event queue.
0231:
0232: public static boolean ThreadInterrupt4() throws Exception {
0233: ThreadInterrupt4Runner r = new ThreadInterrupt4Runner();
0234: Thread thr = new Thread(r);
0235: thr.start();
0236:
0237: // Wait for other thread to enter event processing loop
0238: // and then set the interrupt in the interp.
0239:
0240: while (!r.isRunning()) {
0241: try {
0242: Thread.sleep(50);
0243: } catch (InterruptedException e) {
0244: }
0245: }
0246: r.interp.setInterrupted();
0247:
0248: thr.join(); // Wait for thread to die
0249: return r.passed;
0250: }
0251:
0252: static class ThreadInterrupt4Runner implements Runnable {
0253: Interp interp;
0254: boolean passed = false;
0255: boolean running = false;
0256: final boolean debug = false;
0257:
0258: public void run() {
0259: try {
0260: interp = new Interp();
0261:
0262: // Load util Tcl commands and setup interp.
0263:
0264: interp.eval("source SetInterrupted.tcl", 0);
0265: interp.eval("setup", 0);
0266: interp.eval("ti4_cmd3", 0);
0267: } catch (TclException te) {
0268: // Should never be reached
0269: te.printStackTrace(System.err);
0270: return;
0271: }
0272: if (debug) {
0273: System.out.println("interp was setup");
0274: }
0275:
0276: // Process events from the Tcl event queue, if execution
0277: // is interrupted then stop processing events. This
0278: // method should process an event that was added to
0279: // the event queue by ti4_cmd3.
0280:
0281: Notifier notifier = interp.getNotifier();
0282: if (debug) {
0283: if (notifier == null) {
0284: System.out
0285: .println("interp.getNotifier() returned null");
0286: } else {
0287: System.out
0288: .println("interp.getNotifier() returned non-null");
0289: }
0290: }
0291: try {
0292: while (true) {
0293: if (debug) {
0294: System.out
0295: .println("invoking notifier.doOneEvent()");
0296: }
0297:
0298: running = true;
0299: notifier.doOneEvent(TCL.ALL_EVENTS);
0300: }
0301: } catch (TclInterruptedException te) {
0302: if (debug) {
0303: System.out
0304: .println("caught TclInterruptedException");
0305: te.printStackTrace(System.out);
0306: }
0307:
0308: passed = true;
0309:
0310: // Note that this method does not attempt to remove
0311: // events from the event queue.
0312:
0313: } catch (Exception e) {
0314: e.printStackTrace(System.err);
0315: } finally {
0316: if (debug) {
0317: System.out.println("Interp.dispose()");
0318: }
0319:
0320: interp.dispose();
0321: }
0322:
0323: return;
0324: }
0325:
0326: public boolean isRunning() {
0327: return running;
0328: }
0329:
0330: }
0331:
0332: // Test method that will create an Interp in a new thread
0333: // and then process events from the Tcl event queue.
0334: // This test will enter a loop and then invoke vwait.
0335:
0336: public static boolean ThreadInterrupt5() throws Exception {
0337: ThreadInterrupt5Runner r = new ThreadInterrupt5Runner();
0338: Thread thr = new Thread(r);
0339: thr.start();
0340:
0341: // Wait for other thread to enter event processing loop
0342: // and then set the interrupt in the interp.
0343:
0344: while (!r.isRunning()) {
0345: try {
0346: Thread.sleep(50);
0347: } catch (InterruptedException e) {
0348: }
0349: }
0350: r.interp.setInterrupted();
0351:
0352: thr.join(); // Wait for thread to die
0353: return r.passed;
0354: }
0355:
0356: static class ThreadInterrupt5Runner implements Runnable {
0357: Interp interp;
0358: boolean passed = false;
0359: boolean running = false;
0360: final boolean debug = false;
0361:
0362: public void run() {
0363: try {
0364: interp = new Interp();
0365:
0366: // Load util Tcl commands and setup interp.
0367:
0368: interp.eval("source SetInterrupted.tcl", 0);
0369: interp.eval("setup", 0);
0370: interp.eval("ti5_cmd3", 0);
0371: } catch (TclException te) {
0372: // Should never be reached
0373: te.printStackTrace(System.err);
0374: return;
0375: }
0376: if (debug) {
0377: System.out.println("interp was setup");
0378: }
0379:
0380: // Process events from the Tcl event queue, if execution
0381: // is interrupted then stop processing events. This
0382: // method should process an event that was added to
0383: // the event queue by ti5_cmd3.
0384:
0385: Notifier notifier = interp.getNotifier();
0386: try {
0387: while (true) {
0388: if (debug) {
0389: System.out
0390: .println("invoking notifier.doOneEvent()");
0391: }
0392:
0393: running = true;
0394: notifier.doOneEvent(TCL.ALL_EVENTS);
0395: }
0396: } catch (TclInterruptedException te) {
0397: if (debug) {
0398: System.out
0399: .println("caught TclInterruptedException");
0400: te.printStackTrace(System.out);
0401: }
0402:
0403: passed = true;
0404:
0405: // Note that this method does not attempt to remove
0406: // events from the event queue.
0407:
0408: } finally {
0409: if (debug) {
0410: System.out.println("Interp.dispose()");
0411: }
0412:
0413: interp.dispose();
0414: }
0415:
0416: return;
0417: }
0418:
0419: public boolean isRunning() {
0420: return running;
0421: }
0422:
0423: }
0424:
0425: // Test method that will create an Interp in a new thread
0426: // and then process events from the Tcl event queue.
0427: // The event that will be processed will also process
0428: // events in a vwait. One of the events it will process
0429: // should interrupt the interp, so the vwait will never
0430: // finish.
0431:
0432: public static boolean ThreadInterrupt6() throws Exception {
0433: ThreadInterrupt6Runner r = new ThreadInterrupt6Runner();
0434: Thread thr = new Thread(r);
0435: thr.start();
0436:
0437: // Wait for other thread to enter event processing loop
0438: // and then set the interrupt in the interp.
0439:
0440: try {
0441: Thread.sleep(1000);
0442: } catch (InterruptedException e) {
0443: }
0444:
0445: while (!r.isRunning()) {
0446: try {
0447: Thread.sleep(1000);
0448: } catch (InterruptedException e) {
0449: }
0450: }
0451: r.interp.setInterrupted();
0452:
0453: thr.join(); // Wait for thread to die
0454: return r.passed;
0455: }
0456:
0457: static class ThreadInterrupt6Runner implements Runnable {
0458: Interp interp;
0459: boolean passed = false;
0460: boolean running = false;
0461: final boolean debug = false;
0462:
0463: public void run() {
0464: try {
0465: interp = new Interp();
0466:
0467: // Load util Tcl commands and setup interp.
0468:
0469: interp.eval("source SetInterrupted.tcl", 0);
0470: interp.eval("setup", 0);
0471: interp.eval("ti6_cmd2", 0);
0472: } catch (TclException te) {
0473: // Should never be reached
0474: te.printStackTrace(System.err);
0475: return;
0476: }
0477: if (debug) {
0478: System.out.println("interp was setup");
0479: }
0480:
0481: // Process events from the Tcl event queue, if execution
0482: // is interrupted then stop processing events. This
0483: // method should process an event that was added to
0484: // the event queue by ti6_cmd2.
0485:
0486: Notifier notifier = interp.getNotifier();
0487: try {
0488: while (true) {
0489: if (debug) {
0490: System.out
0491: .println("invoking notifier.doOneEvent()");
0492: }
0493:
0494: running = true;
0495: notifier.doOneEvent(TCL.ALL_EVENTS);
0496: }
0497: } catch (TclInterruptedException te) {
0498: if (debug) {
0499: System.out
0500: .println("caught TclInterruptedException");
0501: te.printStackTrace(System.out);
0502: }
0503:
0504: passed = true;
0505:
0506: // Note that this method does not attempt to remove
0507: // events from the event queue.
0508:
0509: } finally {
0510: if (debug) {
0511: System.out.println("Interp.dispose()");
0512: }
0513:
0514: interp.dispose();
0515: }
0516:
0517: return;
0518: }
0519:
0520: public boolean isRunning() {
0521: return running;
0522: }
0523:
0524: }
0525:
0526: // Test method that will create an Interp in a new thread
0527: // and then process events from the Tcl event queue.
0528: // The event will enter a loop and then be interrupted
0529: // from the other thread. This method tests the
0530: // TclInterruptedException class because it gets the
0531: // interp that generated the interrupted exception
0532: // and it then invokes the Interp.disposeInterrupted()
0533: // method to cleanup and dispose of the interp.
0534:
0535: public static boolean ThreadInterrupt7() throws Exception {
0536: ThreadInterrupt7Runner r = null;
0537:
0538: try {
0539: r = new ThreadInterrupt7Runner();
0540: Thread thr = new Thread(r);
0541: thr.start();
0542:
0543: // Wait for other thread to enter event processing loop
0544: // and then set the interrupt in the interp.
0545:
0546: while (!r.isRunning()) {
0547: try {
0548: Thread.sleep(50);
0549: } catch (InterruptedException e) {
0550: }
0551: }
0552: r.interp.setInterrupted();
0553:
0554: thr.join(); // Wait for thread to die
0555: } catch (NullPointerException e) {
0556: // Don't know why this would be generated
0557: e.printStackTrace(System.err);
0558: }
0559:
0560: return r.passed;
0561: }
0562:
0563: static class ThreadInterrupt7Runner implements Runnable {
0564: Interp interp;
0565: boolean passed = false;
0566: boolean running = false;
0567: final boolean debug = false;
0568:
0569: public void run() {
0570: try {
0571: interp = new Interp();
0572:
0573: // Load util Tcl commands and setup interp.
0574:
0575: interp.eval("source SetInterrupted.tcl", 0);
0576: interp.eval("setup", 0);
0577: interp.eval("ti7_cmd3", 0);
0578: } catch (TclException te) {
0579: // Should never be reached
0580: te.printStackTrace(System.err);
0581: return;
0582: } catch (Exception e) {
0583: e.printStackTrace(System.err);
0584: return;
0585: }
0586:
0587: if (debug) {
0588: System.out.println("interp was setup");
0589: }
0590:
0591: // Process events from the Tcl event queue, if execution
0592: // is interrupted then stop processing events. This
0593: // method should process an event that was added to
0594: // the event queue by ti7_cmd3. This implementation
0595: // will query the Interp object that was interrupted
0596: // from the TclInterruptedException.
0597:
0598: Notifier notifier = interp.getNotifier();
0599: while (true) {
0600: if (debug) {
0601: System.out
0602: .println("invoking notifier.doOneEvent()");
0603: }
0604:
0605: running = true;
0606:
0607: try {
0608: notifier.doOneEvent(TCL.ALL_EVENTS);
0609: } catch (TclInterruptedException te) {
0610: if (debug) {
0611: System.out
0612: .println("caught TclInterruptedException");
0613: te.printStackTrace(System.out);
0614: }
0615:
0616: passed = true;
0617:
0618: te.disposeInterruptedInterp();
0619:
0620: // Break out of the event processing loop
0621: // since this thread has only one interp.
0622: break;
0623: } catch (Exception e) {
0624: e.printStackTrace(System.err);
0625: return;
0626: }
0627:
0628: }
0629:
0630: // Note that there is no way to exit the loop above
0631: // without catching a TclInterruptedException and
0632: // disposing of the interp.
0633:
0634: return;
0635: }
0636:
0637: public boolean isRunning() {
0638: return running;
0639: }
0640:
0641: }
0642:
0643: // Test method that will create 2 interps in a thread
0644: // and then process events in the Tcl event queue.
0645: // This will test interruption of one of the Interps
0646: // while the other continues to run.
0647:
0648: public static boolean ThreadInterrupt20() throws Exception {
0649: ThreadInterrupt20Runner r = new ThreadInterrupt20Runner();
0650: Thread thr = new Thread(r);
0651: thr.start();
0652:
0653: // Wait for other thread to enter event processing loop
0654: // and then set the interrupt in the interp.
0655:
0656: try {
0657: Thread.sleep(50);
0658: } catch (InterruptedException e) {
0659: }
0660:
0661: while (!r.isRunning()) {
0662: try {
0663: Thread.sleep(50);
0664: } catch (InterruptedException e) {
0665: }
0666: }
0667: r.interp1.setInterrupted();
0668:
0669: thr.join(); // Wait for thread to die
0670: return r.passed;
0671: }
0672:
0673: static class ThreadInterrupt20Runner implements Runnable {
0674: Interp interp1;
0675: Interp interp2;
0676: boolean passed = false;
0677: boolean running = false;
0678: final boolean debug = false;
0679:
0680: public void run() {
0681: try {
0682: interp1 = new Interp();
0683: interp2 = new Interp();
0684:
0685: // Load util Tcl commands and setup interps.
0686:
0687: interp1.eval("source SetInterrupted.tcl", 0);
0688: interp1.eval("setup", 0);
0689: interp1.eval("ti20_cmd3 " + "ONE", 0);
0690:
0691: interp2.eval("source SetInterrupted.tcl", 0);
0692: interp2.eval("setup", 0);
0693: interp2.eval("ti20_cmd3 " + "TWO", 0);
0694:
0695: } catch (TclException te) {
0696: // Should never be reached
0697: te.printStackTrace(System.err);
0698: return;
0699: }
0700: if (debug) {
0701: System.out.println("interps were setup");
0702: }
0703:
0704: // Both interps use the same Notifier since there
0705: // is one Notifier for each thread.
0706:
0707: Notifier notifier = interp1.getNotifier();
0708: if (debug) {
0709: boolean nmatch = (notifier == interp2.getNotifier());
0710: System.out.println("Notifier match is " + nmatch);
0711: }
0712:
0713: while (true) {
0714: if (debug) {
0715: System.out
0716: .println("invoking notifier.doOneEvent()");
0717: }
0718:
0719: running = true;
0720:
0721: try {
0722: notifier.doOneEvent(TCL.ALL_EVENTS);
0723: } catch (TclInterruptedException te) {
0724: if (debug) {
0725: System.out
0726: .println("caught TclInterruptedException");
0727: te.printStackTrace(System.out);
0728: }
0729:
0730: // Double check that the interrupted interp is
0731: // the correct one.
0732:
0733: if (te.interp == interp1) {
0734: if (debug) {
0735: System.out.println("interp1 interrupted");
0736: }
0737:
0738: if (passed == true) {
0739: // Interp should not be interrupted a second time.
0740: // This might happen if events were not removed
0741: // from the event queue.
0742:
0743: throw new TclRuntimeError(
0744: "TclInterruptedException was "
0745: + "raised more than once for the same interp");
0746: }
0747: passed = true;
0748: } else if (te.interp == interp2) {
0749: if (debug) {
0750: System.out.println("interp2 interrupted");
0751: }
0752: }
0753:
0754: // Cleanup and then dispose of Interp object.
0755: // This method is invoked after the stack
0756: // has been fully unwound and any cleanup
0757: // logic in each stack frame has been run.
0758:
0759: te.disposeInterruptedInterp();
0760: } catch (Exception e) {
0761: e.printStackTrace(System.err);
0762: return;
0763: }
0764:
0765: // Break out of the event processing loop
0766: // when the last Interp object in this
0767: // thread has been disposed of. This call
0768: // should really be done in the while
0769: // condition, it is only here so that
0770: // debug output can print the condition.
0771:
0772: if (debug) {
0773: System.out
0774: .println("notifier.hasActiveInterps() is "
0775: + notifier.hasActiveInterps());
0776: System.out.println("notifier.refCount is "
0777: + notifier.refCount);
0778: }
0779:
0780: if (!notifier.hasActiveInterps()) {
0781: break;
0782: }
0783: }
0784:
0785: return;
0786: }
0787:
0788: public boolean isRunning() {
0789: return running;
0790: }
0791:
0792: }
0793:
0794: // Test method that will create 2 interps in a thread
0795: // and then process events in the Tcl event queue.
0796: // This will test interruption of one of the Interps
0797: // while the other continues to run.
0798:
0799: public static String ThreadInterrupt21() throws Exception {
0800: ThreadInterrupt21Runner r = new ThreadInterrupt21Runner();
0801: Thread thr = new Thread(r);
0802: thr.start();
0803:
0804: // Wait for other thread to enter event processing loop
0805: // and then set the interrupt in the interp.
0806:
0807: try {
0808: Thread.sleep(150);
0809: } catch (InterruptedException e) {
0810: }
0811:
0812: while (!r.isRunning()) {
0813: try {
0814: Thread.sleep(50);
0815: } catch (InterruptedException e) {
0816: }
0817: }
0818: r.interp1.setInterrupted();
0819:
0820: thr.join(); // Wait for thread to die
0821:
0822: return r.results.toString();
0823: }
0824:
0825: static class ThreadInterrupt21Runner implements Runnable {
0826: Interp interp1;
0827: Interp interp2;
0828: boolean interrupted_one = false;
0829: boolean interrupted_two = false;
0830: StringBuffer results = new StringBuffer();
0831: boolean running = false;
0832: final boolean debug = false;
0833:
0834: public void run() {
0835: try {
0836: interp1 = new Interp();
0837: interp2 = new Interp();
0838:
0839: // Load util Tcl commands and setup interps.
0840:
0841: interp1.eval("source SetInterrupted.tcl", 0);
0842: interp1.eval("setup", 0);
0843: interp1.eval("ti21_cmd3 " + "ONE", 0);
0844: results.append("SETUP_ONE ");
0845:
0846: interp2.eval("source SetInterrupted.tcl", 0);
0847: interp2.eval("setup", 0);
0848: interp2.eval("ti21_cmd3 " + "TWO", 0);
0849: results.append("SETUP_TWO ");
0850:
0851: if (debug) {
0852: System.out.println("interps were setup");
0853: }
0854:
0855: // Both interps use the same Notifier since there
0856: // is one Notifier for each thread.
0857:
0858: Notifier notifier = interp1.getNotifier();
0859:
0860: while (true) {
0861: if (debug) {
0862: System.out
0863: .println("invoking notifier.doOneEvent()");
0864: }
0865:
0866: running = true;
0867:
0868: try {
0869: notifier.doOneEvent(TCL.ALL_EVENTS);
0870: } catch (TclInterruptedException te) {
0871: if (debug) {
0872: System.out
0873: .println("caught TclInterruptedException");
0874: te.printStackTrace(System.out);
0875: }
0876:
0877: // Double check that the interrupted interp is
0878: // the correct one.
0879:
0880: if (te.interp == interp1) {
0881: if (debug) {
0882: System.out
0883: .println("interp1 interrupted");
0884: }
0885:
0886: if (interrupted_one == true) {
0887: // Interp should not be interrupted a second time.
0888: // This might happen if events were not removed
0889: // from the event queue.
0890:
0891: throw new TclRuntimeError(
0892: "TclInterruptedException was "
0893: + "raised more than once for the same interp");
0894: }
0895:
0896: interrupted_one = true;
0897: results.append("INTERRUPTED_ONE ");
0898: } else if (te.interp == interp2) {
0899: if (debug) {
0900: System.out
0901: .println("interp2 interrupted");
0902: }
0903:
0904: if (interrupted_two == true) {
0905: // Interp should not be interrupted a second time.
0906: // This might happen if events were not removed
0907: // from the event queue.
0908:
0909: throw new TclRuntimeError(
0910: "TclInterruptedException was "
0911: + "raised more than once for the same interp");
0912: }
0913:
0914: interrupted_two = true;
0915: results.append("INTERRUPTED_TWO ");
0916: }
0917:
0918: // Cleanup and then dispose of Interp object.
0919: // This method is invoked after the stack
0920: // has been fully unwound and any cleanup
0921: // logic in each stack frame has been run.
0922:
0923: te.disposeInterruptedInterp();
0924: }
0925:
0926: // Break out of the event processing loop
0927: // when the last Interp object in this
0928: // thread has been disposed of.
0929:
0930: if (debug) {
0931: System.out
0932: .println("notifier.hasActiveInterps() is "
0933: + notifier.hasActiveInterps());
0934: }
0935:
0936: if (!notifier.hasActiveInterps()) {
0937: results.append("END_EVENT_LOOP");
0938: break;
0939: }
0940: }
0941:
0942: } catch (Exception e) {
0943: // Should never be reached
0944: e.printStackTrace(System.err);
0945: }
0946:
0947: if (debug) {
0948: System.out.println("end results are : "
0949: + results.toString());
0950: }
0951:
0952: return;
0953: }
0954:
0955: public boolean isRunning() {
0956: return running;
0957: }
0958:
0959: }
0960:
0961: // Test method that will create 2 interps in a thread
0962: // and then process events in the Tcl event queue.
0963: // This will test interruption of one of the Interps
0964: // while the other continues to run. While the
0965: // first stack is being unwound, additional Tcl
0966: // code will be executed.
0967:
0968: public static String ThreadInterrupt22() throws Exception {
0969: ThreadInterrupt22Runner r = new ThreadInterrupt22Runner();
0970: Thread thr = new Thread(r);
0971: thr.start();
0972:
0973: // Wait for other thread to enter event processing loop
0974: // and then set the interrupt in the interp.
0975:
0976: try {
0977: Thread.sleep(500);
0978: } catch (InterruptedException e) {
0979: }
0980:
0981: while (!r.isRunning()) {
0982: try {
0983: Thread.sleep(50);
0984: } catch (InterruptedException e) {
0985: }
0986: }
0987: r.interp1.setInterrupted();
0988:
0989: thr.join(); // Wait for thread to die
0990:
0991: return r.results.toString();
0992: }
0993:
0994: static class ThreadInterrupt22Runner implements Runnable {
0995: Interp interp1;
0996: Interp interp2;
0997: boolean interrupted_one = false;
0998: boolean interrupted_two = false;
0999: StringBuffer results = new StringBuffer();
1000: boolean running = false;
1001: final boolean debug = false;
1002:
1003: public void run() {
1004: try {
1005: interp1 = new Interp();
1006: interp2 = new Interp();
1007:
1008: // Load util Tcl commands and setup interps.
1009:
1010: interp1.eval("source SetInterrupted.tcl", 0);
1011: interp1.eval("setup", 0);
1012: interp1.eval("ti22_cmd3 " + "ONE", 0);
1013: results.append("SETUP_ONE ");
1014:
1015: interp2.eval("source SetInterrupted.tcl", 0);
1016: interp2.eval("setup", 0);
1017: interp2.eval("ti22_cmd3 " + "TWO", 0);
1018: results.append("SETUP_TWO ");
1019:
1020: if (debug) {
1021: System.out.println("interps were setup");
1022: }
1023:
1024: // Both interps use the same Notifier since there
1025: // is one Notifier for each thread.
1026:
1027: Notifier notifier = interp1.getNotifier();
1028:
1029: while (true) {
1030: if (debug) {
1031: System.out
1032: .println("invoking notifier.doOneEvent()");
1033: }
1034:
1035: running = true;
1036:
1037: try {
1038: notifier.doOneEvent(TCL.ALL_EVENTS);
1039: } catch (TclInterruptedException te) {
1040: if (debug) {
1041: System.out
1042: .println("caught TclInterruptedException");
1043: te.printStackTrace(System.out);
1044: }
1045:
1046: // Double check that the interrupted interp is
1047: // the correct one.
1048:
1049: if (te.interp == interp1) {
1050: if (debug) {
1051: System.out
1052: .println("interp1 interrupted");
1053: }
1054:
1055: if (interrupted_one == true) {
1056: // Interp should not be interrupted a second time.
1057: // This might happen if events were not removed
1058: // from the event queue.
1059:
1060: throw new TclRuntimeError(
1061: "TclInterruptedException was "
1062: + "raised more than once for the same interp");
1063: }
1064:
1065: interrupted_one = true;
1066: results.append("INTERRUPTED_ONE ");
1067:
1068: // Query the "results" variable.
1069:
1070: TclObject tobj = interp1.getVar("results",
1071: null, 0);
1072: results.append("{");
1073: results.append(tobj.toString());
1074: results.append("} ");
1075: } else if (te.interp == interp2) {
1076: if (debug) {
1077: System.out
1078: .println("interp2 interrupted");
1079: }
1080:
1081: if (interrupted_two == true) {
1082: // Interp should not be interrupted a second time.
1083: // This might happen if events were not removed
1084: // from the event queue.
1085:
1086: throw new TclRuntimeError(
1087: "TclInterruptedException was "
1088: + "raised more than once for the same interp");
1089: }
1090:
1091: interrupted_two = true;
1092: results.append("INTERRUPTED_TWO ");
1093:
1094: // Query the "results" variable.
1095:
1096: TclObject tobj = interp2.getVar("results",
1097: null, 0);
1098: results.append("{");
1099: results.append(tobj.toString());
1100: results.append("} ");
1101: }
1102:
1103: // Cleanup and then dispose of Interp object.
1104: // This method is invoked after the stack
1105: // has been fully unwound and any cleanup
1106: // logic in each stack frame has been run.
1107:
1108: te.disposeInterruptedInterp();
1109: }
1110:
1111: // Break out of the event processing loop
1112: // when the last Interp object in this
1113: // thread has been disposed of.
1114:
1115: if (debug) {
1116: System.out
1117: .println("notifier.hasActiveInterps() is "
1118: + notifier.hasActiveInterps());
1119: }
1120:
1121: if (!notifier.hasActiveInterps()) {
1122: results.append("END_EVENT_LOOP");
1123: break;
1124: }
1125: }
1126:
1127: } catch (Exception e) {
1128: // Should never be reached
1129: e.printStackTrace(System.err);
1130: }
1131:
1132: if (debug) {
1133: System.out.println("end results are : "
1134: + results.toString());
1135: }
1136:
1137: return;
1138: }
1139:
1140: public boolean isRunning() {
1141: return running;
1142: }
1143:
1144: }
1145:
1146: // Test method that will create 2 interps in a thread
1147: // and then process events in the Tcl event queue.
1148: // This will test interruption of one of the Interps
1149: // while the other continues to run. While the
1150: // first stack is being unwound, additional Tcl
1151: // code will be executed.
1152:
1153: public static String ThreadInterrupt23() throws Exception {
1154: ThreadInterrupt23Runner r = new ThreadInterrupt23Runner();
1155: Thread thr = new Thread(r);
1156: thr.start();
1157:
1158: // No need to interrupt here since both interps
1159: // will interrupt themselves.
1160:
1161: thr.join(); // Wait for thread to die
1162:
1163: return r.results.toString();
1164: }
1165:
1166: static class ThreadInterrupt23Runner implements Runnable {
1167: Interp interp1;
1168: Interp interp2;
1169: boolean interrupted_one = false;
1170: boolean interrupted_two = false;
1171: StringBuffer results = new StringBuffer();
1172: boolean running = false;
1173: final boolean debug = false;
1174:
1175: public void run() {
1176: try {
1177: interp1 = new Interp();
1178: interp2 = new Interp();
1179:
1180: // Load util Tcl commands and setup interps.
1181:
1182: interp1.eval("source SetInterrupted.tcl", 0);
1183: interp1.eval("setup", 0);
1184: interp1.eval("ti23_cmd3 " + "ONE", 0);
1185: results.append("SETUP_ONE ");
1186:
1187: interp2.eval("source SetInterrupted.tcl", 0);
1188: interp2.eval("setup", 0);
1189: interp2.eval("ti23_cmd3 " + "TWO", 0);
1190: results.append("SETUP_TWO ");
1191:
1192: if (debug) {
1193: System.out.println("interps were setup");
1194: }
1195:
1196: // Both interps use the same Notifier since there
1197: // is one Notifier for each thread.
1198:
1199: Notifier notifier = interp1.getNotifier();
1200:
1201: while (true) {
1202: if (debug) {
1203: System.out
1204: .println("invoking notifier.doOneEvent()");
1205: }
1206:
1207: running = true;
1208:
1209: try {
1210: notifier.doOneEvent(TCL.ALL_EVENTS);
1211: } catch (TclInterruptedException te) {
1212: if (debug) {
1213: System.out
1214: .println("caught TclInterruptedException");
1215: te.printStackTrace(System.out);
1216: }
1217:
1218: // Double check that the interrupted interp is
1219: // the correct one.
1220:
1221: if (te.interp == interp1) {
1222: if (debug) {
1223: System.out
1224: .println("interp1 interrupted");
1225: }
1226:
1227: if (interrupted_one == true) {
1228: // Interp should not be interrupted a second time.
1229: // This might happen if events were not removed
1230: // from the event queue.
1231:
1232: throw new TclRuntimeError(
1233: "TclInterruptedException was "
1234: + "raised more than once for the same interp");
1235: }
1236:
1237: interrupted_one = true;
1238: results.append("INTERRUPTED_ONE ");
1239:
1240: // Query the "results" variable.
1241:
1242: TclObject tobj = interp1.getVar("results",
1243: null, 0);
1244: results.append("{");
1245: results.append(tobj.toString());
1246: results.append("} ");
1247: } else if (te.interp == interp2) {
1248: if (debug) {
1249: System.out
1250: .println("interp2 interrupted");
1251: }
1252:
1253: if (interrupted_two == true) {
1254: // Interp should not be interrupted a second time.
1255: // This might happen if events were not removed
1256: // from the event queue.
1257:
1258: throw new TclRuntimeError(
1259: "TclInterruptedException was "
1260: + "raised more than once for the same interp");
1261: }
1262:
1263: interrupted_two = true;
1264: results.append("INTERRUPTED_TWO ");
1265:
1266: // Query the "results" variable.
1267:
1268: TclObject tobj = interp2.getVar("results",
1269: null, 0);
1270: results.append("{");
1271: results.append(tobj.toString());
1272: results.append("} ");
1273: }
1274:
1275: // Cleanup and then dispose of Interp object.
1276: // This method is invoked after the stack
1277: // has been fully unwound and any cleanup
1278: // logic in each stack frame has been run.
1279:
1280: te.disposeInterruptedInterp();
1281: }
1282:
1283: // Break out of the event processing loop
1284: // when the last Interp object in this
1285: // thread has been disposed of.
1286:
1287: if (debug) {
1288: System.out
1289: .println("notifier.hasActiveInterps() is "
1290: + notifier.hasActiveInterps());
1291: }
1292:
1293: if (!notifier.hasActiveInterps()) {
1294: results.append("END_EVENT_LOOP");
1295: break;
1296: }
1297: }
1298:
1299: } catch (Exception e) {
1300: // Should never be reached
1301: e.printStackTrace(System.err);
1302: }
1303:
1304: if (debug) {
1305: System.out.println("end results are : "
1306: + results.toString());
1307: }
1308:
1309: return;
1310: }
1311:
1312: public boolean isRunning() {
1313: return running;
1314: }
1315:
1316: }
1317:
1318: // Test method that will create 2 interps in a thread
1319: // and then process events in the Tcl event queue.
1320: // This will test interruption of one of the Interps
1321: // while the other continues to run. While the
1322: // first stack is being unwound multiple finally
1323: // blocks should be executed.
1324:
1325: public static String ThreadInterrupt24() throws Exception {
1326: ThreadInterrupt24Runner r = new ThreadInterrupt24Runner();
1327: Thread thr = new Thread(r);
1328: thr.start();
1329:
1330: // No need to interrupt here since both interps
1331: // will interrupt themselves.
1332:
1333: thr.join(); // Wait for thread to die
1334:
1335: return r.results.toString();
1336: }
1337:
1338: static class ThreadInterrupt24Runner implements Runnable {
1339: Interp interp1;
1340: Interp interp2;
1341: boolean interrupted_one = false;
1342: boolean interrupted_two = false;
1343: StringBuffer results = new StringBuffer();
1344: boolean running = false;
1345: final boolean debug = false;
1346:
1347: public void run() {
1348: try {
1349: interp1 = new Interp();
1350: interp2 = new Interp();
1351:
1352: // Load util Tcl commands and setup interps.
1353:
1354: interp1.eval("source SetInterrupted.tcl", 0);
1355: interp1.eval("setup", 0);
1356: interp1.eval("ti24_cmd5 " + "ONE", 0);
1357: results.append("SETUP_ONE ");
1358:
1359: interp2.eval("source SetInterrupted.tcl", 0);
1360: interp2.eval("setup", 0);
1361: interp2.eval("ti24_cmd5 " + "TWO", 0);
1362: results.append("SETUP_TWO ");
1363:
1364: if (debug) {
1365: System.out.println("interps were setup");
1366: }
1367:
1368: // Both interps use the same Notifier since there
1369: // is one Notifier for each thread.
1370:
1371: Notifier notifier = interp1.getNotifier();
1372:
1373: while (true) {
1374: if (debug) {
1375: System.out
1376: .println("invoking notifier.doOneEvent()");
1377: }
1378:
1379: running = true;
1380:
1381: try {
1382: notifier.doOneEvent(TCL.ALL_EVENTS);
1383: } catch (TclInterruptedException te) {
1384: if (debug) {
1385: System.out
1386: .println("caught TclInterruptedException");
1387: te.printStackTrace(System.out);
1388: }
1389:
1390: // Double check that the interrupted interp is
1391: // the correct one.
1392:
1393: if (te.interp == interp1) {
1394: if (debug) {
1395: System.out
1396: .println("interp1 interrupted");
1397: }
1398:
1399: if (interrupted_one == true) {
1400: // Interp should not be interrupted a second time.
1401: // This might happen if events were not removed
1402: // from the event queue.
1403:
1404: throw new TclRuntimeError(
1405: "TclInterruptedException was "
1406: + "raised more than once for the same interp");
1407: }
1408:
1409: interrupted_one = true;
1410: results.append("INTERRUPTED_ONE ");
1411:
1412: // Query the "results" variable.
1413:
1414: TclObject tobj = interp1.getVar("results",
1415: null, 0);
1416: results.append("{");
1417: results.append(tobj.toString());
1418: results.append("} ");
1419: } else if (te.interp == interp2) {
1420: if (debug) {
1421: System.out
1422: .println("interp2 interrupted");
1423: }
1424:
1425: if (interrupted_two == true) {
1426: // Interp should not be interrupted a second time.
1427: // This might happen if events were not removed
1428: // from the event queue.
1429:
1430: throw new TclRuntimeError(
1431: "TclInterruptedException was "
1432: + "raised more than once for the same interp");
1433: }
1434:
1435: interrupted_two = true;
1436: results.append("INTERRUPTED_TWO ");
1437:
1438: // Query the "results" variable.
1439:
1440: TclObject tobj = interp2.getVar("results",
1441: null, 0);
1442: results.append("{");
1443: results.append(tobj.toString());
1444: results.append("} ");
1445: }
1446:
1447: // Cleanup and then dispose of Interp object.
1448: // This method is invoked after the stack
1449: // has been fully unwound and any cleanup
1450: // logic in each stack frame has been run.
1451:
1452: te.disposeInterruptedInterp();
1453:
1454: } catch (Throwable te) {
1455: if (debug) {
1456: System.out.println("caught Throwable");
1457: te.printStackTrace(System.out);
1458: }
1459: }
1460:
1461: // Break out of the event processing loop
1462: // when the last Interp object in this
1463: // thread has been disposed of.
1464:
1465: if (debug) {
1466: System.out
1467: .println("notifier.hasActiveInterps() is "
1468: + notifier.hasActiveInterps());
1469: }
1470:
1471: if (!notifier.hasActiveInterps()) {
1472: results.append("END_EVENT_LOOP");
1473: break;
1474: }
1475: }
1476:
1477: } catch (Exception e) {
1478: // Should never be reached
1479: e.printStackTrace(System.err);
1480: }
1481:
1482: if (debug) {
1483: System.out.println("end results are : "
1484: + results.toString());
1485: }
1486:
1487: return;
1488: }
1489:
1490: public boolean isRunning() {
1491: return running;
1492: }
1493:
1494: }
1495:
1496: // Test method that will create 2 interps in a thread
1497: // and then process events in the Tcl event queue.
1498: // This test checks that a catch can't catch a
1499: // TclInterrupted exception and it adds a couple
1500: // of after commands that should be canceled.
1501:
1502: public static String ThreadInterrupt25() throws Exception {
1503: ThreadInterrupt25Runner r = new ThreadInterrupt25Runner();
1504: Thread thr = new Thread(r);
1505: thr.start();
1506:
1507: // No need to interrupt here since both interps
1508: // will interrupt themselves.
1509:
1510: thr.join(); // Wait for thread to die
1511:
1512: return r.results.toString();
1513: }
1514:
1515: static class ThreadInterrupt25Runner implements Runnable {
1516: Interp interp1;
1517: Interp interp2;
1518: boolean interrupted_one = false;
1519: boolean interrupted_two = false;
1520: StringBuffer results = new StringBuffer();
1521: boolean running = false;
1522: final boolean debug = false;
1523:
1524: public void run() {
1525: try {
1526: interp1 = new Interp();
1527: interp2 = new Interp();
1528:
1529: // Load util Tcl commands and setup interps.
1530:
1531: interp1.eval("source SetInterrupted.tcl", 0);
1532: interp1.eval("setup", 0);
1533: interp1.eval("ti25_cmd3 " + "ONE", 0);
1534: results.append("SETUP_ONE ");
1535:
1536: interp2.eval("source SetInterrupted.tcl", 0);
1537: interp2.eval("setup", 0);
1538: interp2.eval("ti25_cmd3 " + "TWO", 0);
1539: results.append("SETUP_TWO ");
1540:
1541: if (debug) {
1542: System.out.println("interps were setup");
1543: }
1544:
1545: // Both interps use the same Notifier since there
1546: // is one Notifier for each thread.
1547:
1548: Notifier notifier = interp1.getNotifier();
1549:
1550: while (true) {
1551: if (debug) {
1552: System.out
1553: .println("invoking notifier.doOneEvent()");
1554: }
1555:
1556: running = true;
1557:
1558: try {
1559: notifier.doOneEvent(TCL.ALL_EVENTS);
1560: } catch (TclInterruptedException te) {
1561: if (debug) {
1562: System.out
1563: .println("caught TclInterruptedException");
1564: te.printStackTrace(System.out);
1565: }
1566:
1567: // Double check that the interrupted interp is
1568: // the correct one.
1569:
1570: if (te.interp == interp1) {
1571: if (debug) {
1572: System.out
1573: .println("interp1 interrupted");
1574: }
1575:
1576: if (interrupted_one == true) {
1577: // Interp should not be interrupted a second time.
1578: // This might happen if events were not removed
1579: // from the event queue.
1580:
1581: throw new TclRuntimeError(
1582: "TclInterruptedException was "
1583: + "raised more than once for the same interp");
1584: }
1585:
1586: interrupted_one = true;
1587: results.append("INTERRUPTED_ONE ");
1588:
1589: // Query the "results" variable.
1590:
1591: TclObject tobj = interp1.getVar("results",
1592: null, 0);
1593: results.append("{");
1594: results.append(tobj.toString());
1595: results.append("} ");
1596: } else if (te.interp == interp2) {
1597: if (debug) {
1598: System.out
1599: .println("interp2 interrupted");
1600: }
1601:
1602: if (interrupted_two == true) {
1603: // Interp should not be interrupted a second time.
1604: // This might happen if events were not removed
1605: // from the event queue.
1606:
1607: throw new TclRuntimeError(
1608: "TclInterruptedException was "
1609: + "raised more than once for the same interp");
1610: }
1611:
1612: interrupted_two = true;
1613: results.append("INTERRUPTED_TWO ");
1614:
1615: // Query the "results" variable.
1616:
1617: TclObject tobj = interp2.getVar("results",
1618: null, 0);
1619: results.append("{");
1620: results.append(tobj.toString());
1621: results.append("} ");
1622: }
1623:
1624: // Cleanup and then dispose of Interp object.
1625: // This method is invoked after the stack
1626: // has been fully unwound and any cleanup
1627: // logic in each stack frame has been run.
1628:
1629: te.disposeInterruptedInterp();
1630:
1631: } catch (Throwable te) {
1632: if (debug) {
1633: System.out.println("caught Throwable");
1634: te.printStackTrace(System.out);
1635: }
1636: }
1637:
1638: // Break out of the event processing loop
1639: // when the last Interp object in this
1640: // thread has been disposed of.
1641:
1642: if (debug) {
1643: System.out
1644: .println("notifier.hasActiveInterps() is "
1645: + notifier.hasActiveInterps());
1646: }
1647:
1648: if (!notifier.hasActiveInterps()) {
1649: results.append("END_EVENT_LOOP");
1650: break;
1651: }
1652: }
1653:
1654: } catch (Exception e) {
1655: // Should never be reached
1656: e.printStackTrace(System.err);
1657: }
1658:
1659: if (debug) {
1660: System.out.println("end results are : "
1661: + results.toString());
1662: }
1663:
1664: return;
1665: }
1666:
1667: public boolean isRunning() {
1668: return running;
1669: }
1670:
1671: }
1672:
1673: // Test method that will create 2 interps in a thread
1674: // and then process events in the Tcl event queue.
1675: // This test checks that a catch can't catch a
1676: // TclInterrupted exception and it adds a couple
1677: // of after commands that should be canceled.
1678:
1679: public static String ThreadInterrupt26() throws Exception {
1680: ThreadInterrupt26Runner r = new ThreadInterrupt26Runner();
1681: Thread thr = new Thread(r);
1682: thr.start();
1683:
1684: // No need to interrupt here since both interps
1685: // will interrupt themselves.
1686:
1687: thr.join(); // Wait for thread to die
1688:
1689: return r.results.toString();
1690: }
1691:
1692: static class ThreadInterrupt26Runner implements Runnable {
1693: Interp interp1;
1694: Interp interp2;
1695: boolean interrupted_one = false;
1696: boolean interrupted_two = false;
1697: StringBuffer results = new StringBuffer();
1698: boolean running = false;
1699: final boolean debug = false;
1700:
1701: public void run() {
1702: try {
1703: interp1 = new Interp();
1704: interp2 = new Interp();
1705:
1706: // Load util Tcl commands and setup interps.
1707:
1708: interp1.eval("source SetInterrupted.tcl", 0);
1709: interp1.eval("setup", 0);
1710: interp1.eval("ti26_cmd3 " + "ONE", 0);
1711: results.append("SETUP_ONE ");
1712:
1713: interp2.eval("source SetInterrupted.tcl", 0);
1714: interp2.eval("setup", 0);
1715: interp2.eval("ti26_cmd3 " + "TWO", 0);
1716: results.append("SETUP_TWO ");
1717:
1718: if (debug) {
1719: System.out.println("interps were setup");
1720: }
1721:
1722: // Both interps use the same Notifier since there
1723: // is one Notifier for each thread.
1724:
1725: Notifier notifier = interp1.getNotifier();
1726:
1727: while (true) {
1728: if (debug) {
1729: System.out
1730: .println("invoking notifier.doOneEvent()");
1731: }
1732:
1733: running = true;
1734:
1735: try {
1736: notifier.doOneEvent(TCL.ALL_EVENTS);
1737: } catch (TclInterruptedException te) {
1738: if (debug) {
1739: System.out
1740: .println("caught TclInterruptedException");
1741: te.printStackTrace(System.out);
1742: }
1743:
1744: // Double check that the interrupted interp is
1745: // the correct one.
1746:
1747: if (te.interp == interp1) {
1748: if (debug) {
1749: System.out
1750: .println("interp1 interrupted");
1751: }
1752:
1753: if (interrupted_one == true) {
1754: // Interp should not be interrupted a second time.
1755: // This might happen if events were not removed
1756: // from the event queue.
1757:
1758: throw new TclRuntimeError(
1759: "TclInterruptedException was "
1760: + "raised more than once for the same interp");
1761: }
1762:
1763: interrupted_one = true;
1764: results.append("INTERRUPTED_ONE ");
1765:
1766: // Query the "results" variable.
1767:
1768: TclObject tobj = interp1.getVar("results",
1769: null, 0);
1770: results.append("{");
1771: results.append(tobj.toString());
1772: results.append("} ");
1773: } else if (te.interp == interp2) {
1774: if (debug) {
1775: System.out
1776: .println("interp2 interrupted");
1777: }
1778:
1779: if (interrupted_two == true) {
1780: // Interp should not be interrupted a second time.
1781: // This might happen if events were not removed
1782: // from the event queue.
1783:
1784: throw new TclRuntimeError(
1785: "TclInterruptedException was "
1786: + "raised more than once for the same interp");
1787: }
1788:
1789: interrupted_two = true;
1790: results.append("INTERRUPTED_TWO ");
1791:
1792: // Query the "results" variable.
1793:
1794: TclObject tobj = interp2.getVar("results",
1795: null, 0);
1796: results.append("{");
1797: results.append(tobj.toString());
1798: results.append("} ");
1799: }
1800:
1801: // Cleanup and then dispose of Interp object.
1802: // This method is invoked after the stack
1803: // has been fully unwound and any cleanup
1804: // logic in each stack frame has been run.
1805:
1806: te.disposeInterruptedInterp();
1807:
1808: } catch (Throwable te) {
1809: if (debug) {
1810: System.out.println("caught Throwable");
1811: te.printStackTrace(System.out);
1812: }
1813: }
1814:
1815: // Break out of the event processing loop
1816: // when the last Interp object in this
1817: // thread has been disposed of.
1818:
1819: if (debug) {
1820: System.out
1821: .println("notifier.hasActiveInterps() is "
1822: + notifier.hasActiveInterps());
1823: }
1824:
1825: if (!notifier.hasActiveInterps()) {
1826: results.append("END_EVENT_LOOP");
1827: break;
1828: }
1829: }
1830:
1831: } catch (Exception e) {
1832: // Should never be reached
1833: e.printStackTrace(System.err);
1834: }
1835:
1836: if (debug) {
1837: System.out.println("end results are : "
1838: + results.toString());
1839: }
1840:
1841: return;
1842: }
1843:
1844: public boolean isRunning() {
1845: return running;
1846: }
1847:
1848: }
1849:
1850: // Test method that will create 2 interps in a thread
1851: // and then process events in the Tcl event queue.
1852: // This test checks that a TJC compiled proc can
1853: // be interrupted.
1854:
1855: public static String ThreadInterrupt30() throws Exception {
1856: ThreadInterrupt30Runner r = new ThreadInterrupt30Runner();
1857: Thread thr = new Thread(r);
1858: thr.start();
1859:
1860: // No need to interrupt here since both interps
1861: // will interrupt themselves.
1862:
1863: thr.join(); // Wait for thread to die
1864:
1865: return r.results.toString();
1866: }
1867:
1868: static class ThreadInterrupt30Runner implements Runnable {
1869: Interp interp1;
1870: Interp interp2;
1871: boolean interrupted_one = false;
1872: boolean interrupted_two = false;
1873: StringBuffer results = new StringBuffer();
1874: boolean running = false;
1875: final boolean debug = false;
1876:
1877: public void run() {
1878: try {
1879: interp1 = new Interp();
1880: interp2 = new Interp();
1881:
1882: // Load util Tcl commands and setup interps.
1883:
1884: if (debug) {
1885: System.out.println("starting interp setup");
1886: }
1887:
1888: interp1.eval("source SetInterrupted.tcl", 0);
1889: interp1.eval("setup", 0);
1890: interp1.eval("ti30_setup " + "ONE", 0);
1891: results.append("SETUP_ONE ");
1892:
1893: if (debug) {
1894: System.out.println("interp ONE was setup");
1895: }
1896:
1897: interp2.eval("source SetInterrupted.tcl", 0);
1898: interp2.eval("setup", 0);
1899: interp2.eval("ti30_setup " + "TWO", 0);
1900: results.append("SETUP_TWO ");
1901:
1902: if (debug) {
1903: System.out.println("interps were setup");
1904: }
1905:
1906: interp1.eval("ti30_start " + "ONE", 0);
1907: interp2.eval("ti30_start " + "TWO", 0);
1908:
1909: if (debug) {
1910: System.out.println("interps were started");
1911: }
1912:
1913: // Both interps use the same Notifier since there
1914: // is one Notifier for each thread.
1915:
1916: Notifier notifier = interp1.getNotifier();
1917:
1918: while (true) {
1919: if (debug) {
1920: System.out
1921: .println("invoking notifier.doOneEvent()");
1922: }
1923:
1924: running = true;
1925:
1926: try {
1927: notifier.doOneEvent(TCL.ALL_EVENTS);
1928: } catch (TclInterruptedException te) {
1929: if (debug) {
1930: System.out
1931: .println("caught TclInterruptedException");
1932: te.printStackTrace(System.out);
1933: }
1934:
1935: // Double check that the interrupted interp is
1936: // the correct one.
1937:
1938: if (te.interp == interp1) {
1939: if (debug) {
1940: System.out
1941: .println("interp1 interrupted");
1942: }
1943:
1944: if (interrupted_one == true) {
1945: // Interp should not be interrupted a second time.
1946: // This might happen if events were not removed
1947: // from the event queue.
1948:
1949: throw new TclRuntimeError(
1950: "TclInterruptedException was "
1951: + "raised more than once for the same interp");
1952: }
1953:
1954: interrupted_one = true;
1955: results.append("INTERRUPTED_ONE ");
1956:
1957: // Query the "results" variable.
1958:
1959: TclObject tobj = interp1.getVar("results",
1960: null, 0);
1961: results.append("{");
1962: results.append(tobj.toString());
1963: results.append("} ");
1964: } else if (te.interp == interp2) {
1965: if (debug) {
1966: System.out
1967: .println("interp2 interrupted");
1968: }
1969:
1970: if (interrupted_two == true) {
1971: // Interp should not be interrupted a second time.
1972: // This might happen if events were not removed
1973: // from the event queue.
1974:
1975: throw new TclRuntimeError(
1976: "TclInterruptedException was "
1977: + "raised more than once for the same interp");
1978: }
1979:
1980: interrupted_two = true;
1981: results.append("INTERRUPTED_TWO ");
1982:
1983: // Query the "results" variable.
1984:
1985: TclObject tobj = interp2.getVar("results",
1986: null, 0);
1987: results.append("{");
1988: results.append(tobj.toString());
1989: results.append("} ");
1990: }
1991:
1992: // Cleanup and then dispose of Interp object.
1993: // This method is invoked after the stack
1994: // has been fully unwound and any cleanup
1995: // logic in each stack frame has been run.
1996:
1997: te.disposeInterruptedInterp();
1998:
1999: } catch (Throwable te) {
2000: if (debug) {
2001: System.out.println("caught Throwable");
2002: te.printStackTrace(System.out);
2003: }
2004: }
2005:
2006: // Break out of the event processing loop
2007: // when the last Interp object in this
2008: // thread has been disposed of.
2009:
2010: if (debug) {
2011: System.out
2012: .println("notifier.hasActiveInterps() is "
2013: + notifier.hasActiveInterps());
2014: }
2015:
2016: if (!notifier.hasActiveInterps()) {
2017: results.append("END_EVENT_LOOP");
2018: break;
2019: }
2020: }
2021:
2022: } catch (Exception e) {
2023: // Should never be reached
2024: e.printStackTrace(System.err);
2025: }
2026:
2027: if (debug) {
2028: System.out.println("end results are : "
2029: + results.toString());
2030: }
2031:
2032: return;
2033: }
2034:
2035: public boolean isRunning() {
2036: return running;
2037: }
2038:
2039: }
2040:
2041: } // end class JaclSetInterrupted
|