diff --git a/packages/transformers/js/package.json b/packages/transformers/js/package.json index 98d85f46781..ef5b7a6d5b0 100644 --- a/packages/transformers/js/package.json +++ b/packages/transformers/js/package.json @@ -34,6 +34,7 @@ "@parcel/plugin": "^2.0.1", "@parcel/source-map": "^2.0.0", "@parcel/utils": "^2.0.1", + "@parcel/workers": "^2.0.1", "@swc/helpers": "^0.2.11", "browserslist": "^4.6.6", "detect-libc": "^1.0.3", diff --git a/packages/transformers/js/src/JSTransformer.js b/packages/transformers/js/src/JSTransformer.js index 08a758971c0..a51365bd11c 100644 --- a/packages/transformers/js/src/JSTransformer.js +++ b/packages/transformers/js/src/JSTransformer.js @@ -12,6 +12,7 @@ import nullthrows from 'nullthrows'; import ThrowableDiagnostic, {encodeJSONKeyComponent} from '@parcel/diagnostic'; import {validateSchema, remapSourceLocation} from '@parcel/utils'; import {isMatch} from 'micromatch'; +import WorkerFarm from '@parcel/workers'; const JSX_EXTENSIONS = { jsx: true, @@ -278,6 +279,7 @@ export default (new Transformer({ asset.getBuffer(), asset.getMap(), init, + loadOnMainThreadIfNeeded(), ]); let targets; @@ -840,3 +842,27 @@ export default (new Transformer({ return [asset]; }, }): Transformer); + +// On linux with older versions of glibc (e.g. CentOS 7), we encounter a segmentation fault +// when worker threads exit due to thread local variables used by SWC. A workaround is to +// also load the native module on the main thread, so that it is not unloaded until process exit. +// See https://github.com/rust-lang/rust/issues/91979. +let isLoadedOnMainThread = false; +async function loadOnMainThreadIfNeeded() { + if ( + !isLoadedOnMainThread && + process.platform === 'linux' && + WorkerFarm.isWorker() + ) { + let {family, version} = require('detect-libc'); + if (family === 'glibc' && parseFloat(version) <= 2.17) { + let api = WorkerFarm.getWorkerApi(); + await api.callMaster({ + location: __dirname + '/loadNative.js', + args: [], + }); + + isLoadedOnMainThread = true; + } + } +} diff --git a/packages/transformers/js/src/loadNative.js b/packages/transformers/js/src/loadNative.js new file mode 100644 index 00000000000..d0795719bef --- /dev/null +++ b/packages/transformers/js/src/loadNative.js @@ -0,0 +1,6 @@ +// This function is called from the main thread to prevent unloading the module +// until the main thread exits. This avoids a segfault in older glibc versions. +// See https://github.com/rust-lang/rust/issues/91979 +module.exports = () => { + require('../native'); +};