module Covered::Forks::Handler

def _fork

@returns [Integer | Nil] The process ID in the parent, and `0` or `nil` in the child depending on Ruby's fork semantics.
Intercept `Process.fork` and initialize coverage in the child.
def _fork
	pid = super
	
	if pid.zero?
		Handler.after_fork
	end
	
	return pid
end

def after_fork

Reset coverage in a forked child and save it at exit.
def after_fork
	return unless coverage = Handler.coverage
	pid = Process.pid
	
	# Any pre-existing coverage is being tracked by the parent process, so discard it.
	coverage.clear
	
	at_exit do
		# Don't break forked children:
		if Process.pid == pid
			coverage.finish
		end
	end
end

def coverage

@returns [Covered::Forks | Nil]
The currently registered coverage wrapper.
def coverage
	LOCK.synchronize do
		@coverages&.last
	end
end

def finish(coverage = nil)

Clear the registered coverage.
def finish(coverage = nil)
	LOCK.synchronize do
		if coverage
			@coverages&.delete(coverage)
		else
			@coverages&.pop
		end
	end
end

def start(coverage)

@parameter coverage [Covered::Forks] The coverage wrapper to use in forked children.
Register coverage for fork handling.
def start(coverage)
	LOCK.synchronize do
		(@coverages ||= []) << coverage
	end
end