diff --git a/README.md b/README.md index b46c37f..cc82421 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,20 @@ manugarg@hobbiton:~$ ./pactest wpad.dat http://www.google.com www.google.com PROXY proxy1.manugarg.com:3128; PROXY proxy2.manugarg.com:3128; DIRECT ``` +#### Thread safety +pacparser keeps all of its JavaScript engine state (the QuickJS runtime and +context, the parsed PAC script, and the last result) in process-global +variables, and the library creates no threads of its own. The API is therefore +**not thread-safe**: there is a single, shared parser instance per process. + +If you use pacparser from a multi-threaded program, you must serialize **all** +calls into the library (`pacparser_init`, `pacparser_parse_pac*`, +`pacparser_find_proxy`, `pacparser_setmyip`, `pacparser_cleanup`, ...) with your +own lock. In particular, never call `pacparser_cleanup()` while another thread +is inside `pacparser_find_proxy()` or `pacparser_parse_pac*()`: cleanup frees +the QuickJS runtime/context that the other thread is still using, which crashes +the process (and is a use-after-free in builds compiled with `-DNDEBUG`). + #### Platforms pacparser has been tested to work on Linux (all architectures supported by Debian), FreeBSD, Mac OS X and Win32 systems. diff --git a/src/pacparser.h b/src/pacparser.h index e7f9f14..6be45a1 100644 --- a/src/pacparser.h +++ b/src/pacparser.h @@ -33,6 +33,15 @@ extern "C" { /// files. See project homepage: http://github.com/pacparser/pacparser /// for more information. /// @author Manu Garg +/// +/// @note **Thread safety:** pacparser keeps all engine state in process-global +/// variables and creates no threads of its own. The API is not +/// thread-safe; there is a single, shared parser instance per process. +/// Callers in multi-threaded programs must serialize all pacparser_* +/// calls with their own lock. In particular, do not call +/// pacparser_cleanup() while another thread is executing +/// pacparser_find_proxy() or pacparser_parse_pac*(): doing so frees +/// state that is still in use and crashes the process. /// @brief Initializes pac parser. /// @returns 0 on failure and 1 on success.