github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/syscall/rlimit.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build unix
     6  
     7  package syscall
     8  
     9  import (
    10  	"sync/atomic"
    11  )
    12  
    13  // origRlimitNofile, if not {0, 0}, is the original soft RLIMIT_NOFILE.
    14  // When we can assume that we are bootstrapping with Go 1.19,
    15  // this can be atomic.Pointer[Rlimit].
    16  var origRlimitNofile atomic.Value // of Rlimit
    17  
    18  // Some systems set an artificially low soft limit on open file count, for compatibility
    19  // with code that uses select and its hard-coded maximum file descriptor
    20  // (limited by the size of fd_set).
    21  //
    22  // Go does not use select, so it should not be subject to these limits.
    23  // On some systems the limit is 256, which is very easy to run into,
    24  // even in simple programs like gofmt when they parallelize walking
    25  // a file tree.
    26  //
    27  // After a long discussion on go.dev/issue/46279, we decided the
    28  // best approach was for Go to raise the limit unconditionally for itself,
    29  // and then leave old software to set the limit back as needed.
    30  // Code that really wants Go to leave the limit alone can set the hard limit,
    31  // which Go of course has no choice but to respect.
    32  func init() {
    33  	var lim Rlimit
    34  	if err := Getrlimit(RLIMIT_NOFILE, &lim); err == nil && lim.Cur != lim.Max {
    35  		origRlimitNofile.Store(lim)
    36  		lim.Cur = lim.Max
    37  		adjustFileLimit(&lim)
    38  		setrlimit(RLIMIT_NOFILE, &lim)
    39  	}
    40  }
    41  
    42  func Setrlimit(resource int, rlim *Rlimit) error {
    43  	err := setrlimit(resource, rlim)
    44  	if err == nil && resource == RLIMIT_NOFILE {
    45  		// Store zeroes in origRlimitNofile to tell StartProcess
    46  		// to not adjust the rlimit in the child process.
    47  		origRlimitNofile.Store(Rlimit{0, 0})
    48  	}
    49  	return err
    50  }