Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CompileJIT is not threadsafe #2

Open
d4l3k opened this issue Dec 14, 2016 · 2 comments
Open

CompileJIT is not threadsafe #2

d4l3k opened this issue Dec 14, 2016 · 2 comments

Comments

@d4l3k
Copy link

d4l3k commented Dec 14, 2016

pcrejit requires a separate thread specific stack. This leads to some very weird issues when using this library with multiple threads. I naively called CompileJIT in one part of the program and then used it in other parts without realizing that per thread stacks were required. This isn't featured in the documentation, nor is there a way to handle it in the current Go API.

http://www.pcre.org/original/doc/html/pcrejit.html#SEC9

http://www.pcre.org/original/doc/html/pcreapi.html#SEC8

https://stackoverflow.com/questions/28738674/is-the-pcre-library-thread-safe-if-not-which-do-you-recommend

package main

import (
	"log"

	pcre "github.com/gijsbers/go-pcre"
)

func findIndex(a pcre.Regexp) {
	for {
		// Compile a new function with JIT. Since this is running in a goroutine and
		// probably a different thread the JIT stack will be violated.
		b := pcre.MustCompileJIT("[^\\/><\\s]+", 0, 0)
		if b.FindIndex([]byte(" <p>"), 0) == nil {
			log.Fatal("b.FindIndex(...) should never equal nil")
		}

		if a.FindIndex([]byte(" <p>"), 0) == nil {
			log.Fatal("a.FindIndex(...) should never equal nil")
		}
	}
}

func main() {
	a := pcre.MustCompileJIT("[^\\/><\\s]+", 0, 0)
	for i := 0; i < 4; i++ {
		go findIndex(a)
	}
	findIndex(a)
}
@d4l3k
Copy link
Author

d4l3k commented Dec 14, 2016

FYI in the above example it fails with "a.FindIndex(...) should never equal nil"

@gijsbers
Copy link
Owner

gijsbers commented Jan 2, 2017

Very well researched!

Likely using pcre JIT in go requires the use of LockOSThread, such that it is guaranteed that findIndex is executing on the same OS thread as MustCompileJIT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants