<commit_before>// SPDX-License-Identifier: Apache-2.0
// Copyright 2018-2020 Authors of Cilium

package cmd

import (
	"context"
	"os"
	"os/signal"
	"sync"

	gops "github.com/google/gops/agent"
	"golang.org/x/sys/unix"

	"github.com/cilium/cilium/pkg/lock"
	"github.com/cilium/cilium/pkg/pidfile"
)

var cleaner = &daemonCleanup{
	cleanUPSig: make(chan struct{}),
	cleanUPWg:  &sync.WaitGroup{},
	cleanupFuncs: &cleanupFuncList{
		funcs: make([]func(), 0),
	},
}

type daemonCleanup struct {
	lock.Mutex
	// cleanUPSig channel that is closed when the daemon agent should be
	// terminated.
	cleanUPSig chan struct{}
	// cleanUPWg all cleanup operations will be marked as Done() when completed.
	cleanUPWg *sync.WaitGroup

	cleanupFuncs *cleanupFuncList

	sigHandlerCancel context.CancelFunc
}

type cleanupFuncList struct {
	funcs []func()
	lock  lock.Mutex
}

func (c *cleanupFuncList) Add(newFunc func()) {
	c.lock.Lock()
	c.funcs = append(c.funcs, newFunc)
	c.lock.Unlock()
}

func (c *cleanupFuncList) Run() {
	c.lock.Lock()
	defer c.lock.Unlock()
	for k := range c.funcs {
		c.funcs[k]()
	}
}

func (d *daemonCleanup) registerSigHandler() <-chan struct{} {
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, unix.SIGQUIT, unix.SIGINT, unix.SIGHUP, unix.SIGTERM)
	interrupt := make(chan struct{})
	go func() {
		for s := range sig {
			log.WithField("signal", s).Info("Exiting due to signal")
			log.Debug("canceling context in signal handler")
			d.Lock()
			if d.sigHandlerCancel != nil {
				d.sigHandlerCancel()
			}
			d.Unlock()
			pidfile.Clean()
			d.Clean()
			d.cleanupFuncs.Run()
			// nolint<commit_msg>daemon: allow running pre-cleanup functions<commit_after>// SPDX-License-Identifier: Apache-2.0
// Copyright 2018-2020 Authors of Cilium

package cmd

import (
	"context"
	"os"
	"os/signal"
	"sync"

	gops "github.com/google/gops/agent"
	"golang.org/x/sys/unix"

	"github.com/cilium/cilium/pkg/lock"
	"github.com/cilium/cilium/pkg/pidfile"
)

var cleaner = &daemonCleanup{
	cleanUPSig: make(chan struct{}),
	cleanUPWg:  &sync.WaitGroup{},
	cleanupFuncs: &cleanupFuncList{
		funcs: make([]func(), 0),
	},
	preCleanupFuncs: &cleanupFuncList{
		funcs: make([]func(), 0),
	},
}

type daemonCleanup struct {
	lock.Mutex
	// cleanUPSig channel that is closed when the daemon agent should be
	// terminated.
	cleanUPSig chan struct{}
	// cleanUPWg all cleanup operations will be marked as Done() when completed.
	cleanUPWg *sync.WaitGroup

	preCleanupFuncs *cleanupFuncList

	cleanupFuncs *cleanupFuncList

	sigHandlerCancel context.CancelFunc
}

type cleanupFuncList struct {
	funcs []func()
	lock  lock.Mutex
}

func (c *cleanupFuncList) Add(newFunc func()) {
	c.lock.Lock()
	c.funcs = append(c.funcs, newFunc)
	c.lock.Unlock()
}

func (c *cleanupFuncList) Run() {
	c.lock.Lock()
	defer c.lock.Unlock()
	for k := range c.funcs {
		c.funcs[k]()
	}
}

func (d *daemonCleanup) registerSigHandler() <-chan struct{} {
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, unix.SIGQUIT, unix.SIGINT, unix.SIGHUP, unix.SIGTERM)
	interrupt := make(chan struct{})
	go func() {
		for s := range sig {
			log.WithField("signal", s).Info("Exiting due to signal")
			d.preCleanupFuncs.Run()
			log.Debug("canceling context in signal handler")
			d.Lock()
			if d.sigHandlerCancel != nil {
				d.sigHandlerCancel()
			}
			d.Unlock()
			pidfile.Clean()
			d.Clean()
			d.cleanupFuncs.Run()
			// nolint
{'fraction_non_alphanumeric': 0.14441176470588235, 'fraction_numerical': 0.007352941176470588, 'mean_word_length': 3.928985507246377, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1738841', 'n_tokens_mistral': 1366, 'n_tokens_neox': 1280, 'n_words': 295}