text: 'use strict';
  
  const callbacks = new Set();
  let called = false;
  
  function exit(exit, signal) {
  	if (called) {
  		return;
  	}
  
  	called = true;
  
  	for (const callback of callbacks) {
  		callback();
  	}
  
  	if (exit === true) {
  		process.exit(128 + signal); // eslint-disable-line unicorn/no-process-exit
  	}
  }
  
  module.exports = callback => {
  	callbacks.add(callback);
  
  	if (callbacks.size === 1) {
  		process.once('exit', exit);
  		process.once('SIGINT', exit.bind(null, true, 2));
  		process.once('SIGTERM', exit.bind(null, true, 15));
  
  		// PM2 Cluster shutdown message. Caught to support async handlers with pm2, needed because
  		// explicitly calling process.exit() doesn't trigger the beforeExit event, and the exit
  		// event cannot support async handlers, since the event loop is never called after it.
  		process.on('message', message => {
  			if (message === 'shutdown') {
  				exit(true, -128);
  			}
  		});
  	}
  
  	return () => {
  		callbacks.delete(callback);
  	};
  };
  