Skip to content

Commit

Permalink
Apply segfault workaround to image optimizer as well
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed Dec 17, 2021
1 parent 84847ed commit 8660c23
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/optimizers/image/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@parcel/diagnostic": "^2.0.1",
"@parcel/plugin": "^2.0.1",
"@parcel/utils": "^2.0.1",
"@parcel/workers": "^2.0.1",
"detect-libc": "^1.0.3"
},
"devDependencies": {
Expand Down
26 changes: 26 additions & 0 deletions packages/optimizers/image/src/ImageOptimizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import {Optimizer} from '@parcel/plugin';
import {blobToBuffer} from '@parcel/utils';
import {md} from '@parcel/diagnostic';
import {optimize} from '../native';
import WorkerFarm from '@parcel/workers';

export default (new Optimizer({
async optimize({bundle, contents, logger}) {
if (!bundle.env.shouldOptimize) {
return {contents};
}

await loadOnMainThreadIfNeeded();
let buffer = await blobToBuffer(contents);

// Attempt to optimize it, if the optimize fails we log a warning...
Expand All @@ -34,3 +36,27 @@ export default (new Optimizer({
return {contents: buffer};
},
}): Optimizer);

// 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 in Rust. 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;
}
}
}
6 changes: 6 additions & 0 deletions packages/optimizers/image/src/loadNative.js
Original file line number Diff line number Diff line change
@@ -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');
};

0 comments on commit 8660c23

Please sign in to comment.