@ -23,6 +23,7 @@ import (
const (
const (
listenFDs = "LISTEN_FDS"
listenFDs = "LISTEN_FDS"
startFD = 3
startFD = 3
unlinkFDs = "GITEA_UNLINK_FDS"
)
)
// In order to keep the working directory the same as when we started we record
// In order to keep the working directory the same as when we started we record
@ -33,8 +34,10 @@ var (
once = sync . Once { }
once = sync . Once { }
mutex = sync . Mutex { }
mutex = sync . Mutex { }
providedListeners = [ ] net . Listener { }
providedListenersToUnlink = [ ] bool { }
activeListeners = [ ] net . Listener { }
activeListenersToUnlink = [ ] bool { }
providedListeners = [ ] net . Listener { }
activeListeners = [ ] net . Listener { }
)
)
func getProvidedFDs ( ) ( savedErr error ) {
func getProvidedFDs ( ) ( savedErr error ) {
@ -53,6 +56,16 @@ func getProvidedFDs() (savedErr error) {
return
return
}
}
fdsToUnlinkStr := strings . Split ( os . Getenv ( unlinkFDs ) , "," )
providedListenersToUnlink = make ( [ ] bool , n )
for _ , fdStr := range fdsToUnlinkStr {
i , err := strconv . Atoi ( fdStr )
if err != nil || i < 0 || i >= n {
continue
}
providedListenersToUnlink [ i ] = true
}
for i := startFD ; i < n + startFD ; i ++ {
for i := startFD ; i < n + startFD ; i ++ {
file := os . NewFile ( uintptr ( i ) , fmt . Sprintf ( "listener_FD%d" , i ) )
file := os . NewFile ( uintptr ( i ) , fmt . Sprintf ( "listener_FD%d" , i ) )
@ -136,8 +149,11 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err
for i , l := range providedListeners {
for i , l := range providedListeners {
if isSameAddr ( l . Addr ( ) , address ) {
if isSameAddr ( l . Addr ( ) , address ) {
providedListeners = append ( providedListeners [ : i ] , providedListeners [ i + 1 : ] ... )
providedListeners = append ( providedListeners [ : i ] , providedListeners [ i + 1 : ] ... )
needsUnlink := providedListenersToUnlink [ i ]
providedListenersToUnlink = append ( providedListenersToUnlink [ : i ] , providedListenersToUnlink [ i + 1 : ] ... )
activeListeners = append ( activeListeners , l )
activeListeners = append ( activeListeners , l )
activeListenersToUnlink = append ( activeListenersToUnlink , needsUnlink )
return l . ( * net . TCPListener ) , nil
return l . ( * net . TCPListener ) , nil
}
}
}
}
@ -148,6 +164,7 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err
return nil , err
return nil , err
}
}
activeListeners = append ( activeListeners , l )
activeListeners = append ( activeListeners , l )
activeListenersToUnlink = append ( activeListenersToUnlink , false )
return l , nil
return l , nil
}
}
@ -166,9 +183,15 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
for i , l := range providedListeners {
for i , l := range providedListeners {
if isSameAddr ( l . Addr ( ) , address ) {
if isSameAddr ( l . Addr ( ) , address ) {
providedListeners = append ( providedListeners [ : i ] , providedListeners [ i + 1 : ] ... )
providedListeners = append ( providedListeners [ : i ] , providedListeners [ i + 1 : ] ... )
needsUnlink := providedListenersToUnlink [ i ]
providedListenersToUnlink = append ( providedListenersToUnlink [ : i ] , providedListenersToUnlink [ i + 1 : ] ... )
activeListenersToUnlink = append ( activeListenersToUnlink , needsUnlink )
activeListeners = append ( activeListeners , l )
activeListeners = append ( activeListeners , l )
unixListener := l . ( * net . UnixListener )
unixListener := l . ( * net . UnixListener )
unixListener . SetUnlinkOnClose ( true )
if needsUnlink {
unixListener . SetUnlinkOnClose ( true )
}
return unixListener , nil
return unixListener , nil
}
}
}
}
@ -189,6 +212,7 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
}
}
activeListeners = append ( activeListeners , l )
activeListeners = append ( activeListeners , l )
activeListenersToUnlink = append ( activeListenersToUnlink , true )
return l , nil
return l , nil
}
}
@ -223,3 +247,11 @@ func getActiveListeners() []net.Listener {
copy ( listeners , activeListeners )
copy ( listeners , activeListeners )
return listeners
return listeners
}
}
func getActiveListenersToUnlink ( ) [ ] bool {
mutex . Lock ( )
defer mutex . Unlock ( )
listenersToUnlink := make ( [ ] bool , len ( activeListenersToUnlink ) )
copy ( listenersToUnlink , activeListenersToUnlink )
return listenersToUnlink
}