Thanks to feedback and patches provided by Rodrigo Tobar Carrizo, as of release 5.18, WCSLIB is now completely thread-safe, with only a couple of minor provisos.

In particular, a number of new routines were introduced to preclude altering the global variables NPVMAX, NPSMAX, and NDPMAX, which determine how much memory to allocate for storing PVi_ma, PSi_ma, DPja, and DQia keyvalues: wcsinit(), lininit(), lindist(), and disinit(). Specifically, these new routines are now used by various WCSLIB routines, such as the header parsers, which previously temporarily altered the global variables, thus posing a thread hazard.

In addition, the Flex scanners were made reentrant and consequently should now be thread-safe. This was achieved by rewriting them as thin wrappers (with the same API) over scanners that were modified (with changed API), as required to use Flex's "reentrant" option.

For complete thread-safety, please observe the following provisos:

Note that diagnostic routines that print the contents of the various structs, namely celprt(), disprt(), linprt(), prjprt(), spcprt(), tabprt(), wcsprt(), and wcsperr() use printf() which is thread-safe by the POSIX requirement on stdio. However, this is only at the function level. Where multiple threads invoke these routines simultaneously their output is likely to be interleaved.