This is an automated email from the git hooks/post-receive script.

henrich pushed a commit to branch debian/sid
in repository jruby-joni.

commit 5ac0601a748dac71e0a7697d085c92f41dad0f7f
Author: Thomas E. Enebo <[email protected]>
Date:   Fri May 10 16:06:03 2013 -0500

    Make interrupt check actually reset the interrupt state so the thread can 
work for more than one regexp.  Add some unit tests
---
 src/org/joni/ByteCodeMachine.java     |   8 ++-
 test/org/joni/test/Test.java          | 112 ++++++++++++++++++++++++++++++++--
 test/org/joni/test/TestInterrupt.java | 100 ++++++++++++++++++++++++++++++
 test/org/joni/test/TestJoni.java      |   6 ++
 4 files changed, 221 insertions(+), 5 deletions(-)

diff --git a/src/org/joni/ByteCodeMachine.java 
b/src/org/joni/ByteCodeMachine.java
index a9e0e08..d5b318c 100644
--- a/src/org/joni/ByteCodeMachine.java
+++ b/src/org/joni/ByteCodeMachine.java
@@ -37,6 +37,9 @@ import org.joni.exception.ErrorMessages;
 import org.joni.exception.InternalException;
 
 class ByteCodeMachine extends StackMachine {
+    private static final int INTERRUPT_CHECK_EVERY = 30000;
+    int interruptCheckCounter = 0; // we modulos this to occasionally check 
for interrupts
+    
     private int bestLen;          // return value
     private int s = 0;            // current char
 
@@ -183,12 +186,15 @@ class ByteCodeMachine extends StackMachine {
 
         bestLen = -1;
         s = sstart;
+        Thread currentThread = Thread.currentThread();
 
         final int[]code = this.code;
         while (true) {
-            if (Thread.interrupted()) {
+            if (interruptCheckCounter++ % INTERRUPT_CHECK_EVERY == 0 && 
currentThread.isInterrupted()) {
+                currentThread.interrupted();
                 throw new InterruptedException();
             }
+
             if (Config.DEBUG_MATCH) debugMatchLoop();
 
             sbegin = s;
diff --git a/test/org/joni/test/Test.java b/test/org/joni/test/Test.java
index 1010446..0887b60 100644
--- a/test/org/joni/test/Test.java
+++ b/test/org/joni/test/Test.java
@@ -49,12 +49,89 @@ public abstract class Test {
     protected int length(byte[]bytes) {
         return bytes.length;
     }
+    
+    protected void assertTrue(boolean expression, String... failMessage) {
+        if (expression) {
+            nsucc++;
+        } else {
+            Config.err.println(failMessage);
+            nfail++;
+        }
+    }
 
     public void xx(byte[]pattern, byte[]str, int from, int to, int mem, 
boolean not) {
         xx(pattern, str, from, to, mem, not, option());
     }
+    
+    public int xx(byte[]pattern, byte[]str, int from, int to, int mem, boolean 
not, int option) {
+        Regex reg;
+
+        try {
+            reg = new Regex(pattern, 0, length(pattern), option, encoding(), 
syntax());
+        } catch (JOniException je) {
+            Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
+            je.printStackTrace(Config.err);
+            Config.err.println("ERROR: " + je.getMessage());
+            nerror++;
+            return Matcher.FAILED;
+        } catch (Exception e) {
+            Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
+            e.printStackTrace(Config.err);
+            Config.err.println("SEVERE ERROR: " + e.getMessage());
+            nerror++;
+            return Matcher.FAILED;
+        }
+
+        Matcher m = reg.matcher(str, 0, length(str));
+        Region region;
 
-    public void xx(byte[]pattern, byte[]str, int from, int to, int mem, 
boolean not, int option) {
+        int r = 0;
+        try {
+            r = m.search(0, length(str), Option.NONE);
+            region = m.getEagerRegion();
+        } catch (JOniException je) {
+            Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
+            je.printStackTrace(Config.err);
+            Config.err.println("ERROR: " + je.getMessage());
+            nerror++;
+            return Matcher.FAILED;
+        } catch (Exception e) {
+            Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
+            e.printStackTrace(Config.err);
+            Config.err.println("SEVERE ERROR: " + e.getMessage());
+            nerror++;
+            return Matcher.FAILED;
+        }
+
+        if (r == -1) {
+            if (not) {
+                if (VERBOSE) Config.log.println("OK(N): /" + repr(pattern) + 
"/ '" + repr(str) + "'");
+                nsucc++;
+            } else {
+                Config.log.println("FAIL: /" + repr(pattern) + "/ '" + 
repr(str) + "'");
+                nfail++;
+            }
+        } else {
+            if (not) {
+                Config.log.println("FAIL(N): /" + repr(pattern) + "/ '" + 
repr(str) + "'");
+                nfail++;
+            } else {
+                if (region.beg[mem] == from && region.end[mem] == to) {
+                    if (VERBOSE)  Config.log.println("OK: /" + repr(pattern) + 
"/ '" +repr(str) + "'");
+                    nsucc++;
+                } else {
+                    Config.log.println("FAIL: /" + repr(pattern) + "/ '" + 
repr(str) + "' " +
+                            from + "-" + to + " : " + region.beg[mem] + "-" + 
region.end[mem]
+                            );
+                    nfail++;
+                }
+            }
+        }
+        
+        return r;
+    }
+    
+    public void xxi(byte[]pattern, byte[]str, int from, int to, int mem, 
boolean not, int option) throws InterruptedException {
         Regex reg;
 
         try {
@@ -78,7 +155,7 @@ public abstract class Test {
 
         int r = 0;
         try {
-            r = m.search(0, length(str), Option.NONE);
+            r = m.searchInterruptible(0, length(str), Option.NONE);
             region = m.getEagerRegion();
         } catch (JOniException je) {
             Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
@@ -86,6 +163,8 @@ public abstract class Test {
             Config.err.println("ERROR: " + je.getMessage());
             nerror++;
             return;
+        } catch (InterruptedException e) {
+            throw e;
         } catch (Exception e) {
             Config.err.println("Pattern: " + repr(pattern) + " Str: " + 
repr(str));
             e.printStackTrace(Config.err);
@@ -151,18 +230,43 @@ public abstract class Test {
             uee.printStackTrace();
         }
     }
+    
+    public void xxsi(String pattern, String str, int from, int to, int mem, 
boolean not) throws InterruptedException {
+        xxsi(pattern, str, from, to, mem, not, option());
+    }
+
+    public void xxsi(String pattern, String str, int from, int to, int mem, 
boolean not, int option) throws InterruptedException {
+        try{
+            xxi(pattern.getBytes(testEncoding()), 
str.getBytes(testEncoding()), from, to, mem, not, option);
+        } catch (UnsupportedEncodingException uee) {
+            uee.printStackTrace();
+        }
+    }    
 
     public void x2s(String pattern, String str, int from, int to) {
         x2s(pattern, str, from, to, option());
     }
 
-    public void x2s(String pattern, String str, int from, int to, int option) {
+    public int x2s(String pattern, String str, int from, int to, int option) {
         try{
-        xx(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), 
from, to, 0, false, option);
+            return xx(pattern.getBytes(testEncoding()), 
str.getBytes(testEncoding()), from, to, 0, false, option);
         } catch (UnsupportedEncodingException uee) {
             uee.printStackTrace();
+            return Matcher.FAILED;
         }
     }
+    
+    public void x2si(String pattern, String str, int from, int to) throws 
InterruptedException {
+        x2si(pattern, str, from, to, option());
+    }
+
+    public void x2si(String pattern, String str, int from, int to, int option) 
throws InterruptedException {
+        try{
+        xxi(pattern.getBytes(testEncoding()), str.getBytes(testEncoding()), 
from, to, 0, false, option);
+        } catch (UnsupportedEncodingException uee) {
+            uee.printStackTrace();
+        }
+    }    
 
     public void x3s(String pattern, String str, int from, int to, int mem) {
         x3s(pattern, str, from, to, mem, option());
diff --git a/test/org/joni/test/TestInterrupt.java 
b/test/org/joni/test/TestInterrupt.java
new file mode 100644
index 0000000..fab5b17
--- /dev/null
+++ b/test/org/joni/test/TestInterrupt.java
@@ -0,0 +1,100 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2013 enebo.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package org.joni.test;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import org.jcodings.Encoding;
+import org.jcodings.specific.ASCIIEncoding;
+import org.joni.Matcher;
+import org.joni.Option;
+import org.joni.Syntax;
+
+/**
+ * These are fairly long-running tests but we want a large time slice to 
reduce misfires
+ * on slow ci boxes.
+ */
+public class TestInterrupt extends Test {
+    interface InterruptibleRunnable {
+        public void run() throws InterruptedException;
+    }
+    public void test() throws InterruptedException {
+        interruptAfter(new InterruptibleRunnable() {
+            public void run() throws InterruptedException {
+                
x2si("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+                        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 0);
+            }
+        }, 1000, 15000);
+
+        /*
+        final int status[] = new int[1];
+        
+        interruptAfter(new InterruptibleRunnable() {
+            public void run() throws InterruptedException {
+                status[0] = 
x2s("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+                        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 0);
+            }
+        }, 1000, 15000);
+        
+        assertTrue(status[0] == Matcher.INTERRUPTED, "Status was not 
INTERRUPTED: " + status[0]);*/
+    }
+    
+    private void interruptAfter(InterruptibleRunnable block, int 
delayBeforeInterrupt, int acceptableMaximumTime) {
+        final long start[] = new long[1];
+        
+        final Thread currentThread = Thread.currentThread();
+        
+        new Timer().schedule(new TimerTask() {
+            @Override public void run() {
+                start[0] = System.currentTimeMillis();
+                System.out.println("INTERRUPTING at " + start[0]);
+                currentThread.interrupt();
+            }
+        }, delayBeforeInterrupt);
+        
+        try {
+            block.run();
+        } catch (InterruptedException e) {
+            long total = System.currentTimeMillis() - start[0];
+            System.out.println("Time taken: " + total);
+            assertTrue(total < acceptableMaximumTime, "Took too long to 
interrupt: " + total + " > " + acceptableMaximumTime);
+        }        
+    }
+        
+    public int option() {
+        return Option.DEFAULT;
+    }
+
+    public Encoding encoding() {
+        return ASCIIEncoding.INSTANCE;
+    }
+
+    public String testEncoding() {
+        return "iso-8859-2";
+    }
+
+    public Syntax syntax() {
+        return Syntax.DEFAULT;
+    }
+}
diff --git a/test/org/joni/test/TestJoni.java b/test/org/joni/test/TestJoni.java
index a94ed56..b7d5744 100644
--- a/test/org/joni/test/TestJoni.java
+++ b/test/org/joni/test/TestJoni.java
@@ -29,6 +29,7 @@ public class TestJoni extends TestCase {
     private Test testnsu8;
     private Test testLookBehind;
     private Test testu8;
+    private Test testInterrupt;
 
     protected void setUp() {
         testa = new TestA();
@@ -37,6 +38,7 @@ public class TestJoni extends TestCase {
         testnsu8 = new TestNSU8();
         testu8 = new TestU8();
         testLookBehind = new TestLookBehind();
+        testInterrupt = new TestInterrupt();
     }
 
     protected void tearDown() {
@@ -65,4 +67,8 @@ public class TestJoni extends TestCase {
     public void testLookBehind() {
        testJoniTest(testLookBehind);
     }
+    
+    public void testInterrupt() {
+        testJoniTest(testInterrupt);
+    }
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-java/jruby-joni.git

_______________________________________________
pkg-java-commits mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

Reply via email to