Permalink
Browse files

Fixes for issue #9 for the meantime. Need to keep an eye on SI-4929 f…

…or future changes with regards to this issue
  • Loading branch information...
1 parent 6d88017 commit 2541904066a6be114be884a0c75b5f72cb00959a @theon theon committed Jan 27, 2013
Showing with 31 additions and 3 deletions.
  1. +31 −3 src/main/scala/com/github/theon/uri/UriParser.scala
@@ -32,6 +32,34 @@ class UriParser extends RegexParsers {
}
}
object UriParser {
- val parser = new UriParser()
- def parse(s: CharSequence) = parser.parseAll(parser.uri, s).get
-}
+ /**
+ * When thread safety issues mentioned in https://issues.scala-lang.org/browse/SI-4929 are fixed,
+ * we won't need to make a new UriParser for every parse, we can reuse a single UriParser for better
+ * performance.
+ * I was going to make reuse of a single UriParser for 2.10 (as the thread safety issues don't exist in 2.10),
+ * however there is talk of reintroducing these issues to avoid a memory leak... (so I will just keep and eye on the
+ * SI-4929 ticket for the meantime)
+ */
+ def parse(s: CharSequence) = {
+ val parser = new UriParser()
+ val res = parser.parseAll(parser.uri, s).get
+ cleanup
+ res
+ }
+
+ /**
+ * Cleanup to prevent memory leak mentioned in ticket https://issues.scala-lang.org/browse/SI-4929
+ */
+ def cleanup = {
+ try {
+ val field = getClass.getDeclaredField("scala$util$parsing$combinator$Parsers$$lastNoSuccessVar")
+ field.setAccessible(true)
+ val field2 = classOf[scala.util.DynamicVariable[_]].getDeclaredField("tl")
+ field2.setAccessible(true)
+ field2.get(field.get(this)).asInstanceOf[java.lang.ThreadLocal[_]].remove()
+ field.set(this, null)
+ } catch {
+ case e:NoSuchFieldException => //2.9.2 - no clean up required
+ }
+ }
+}

0 comments on commit 2541904

Please sign in to comment.