mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Windows: Win32 event for sigusr1 linux equivalence
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
		
							parent
							
								
									c7492126ef
								
							
						
					
					
						commit
						f4b08c7f5e
					
				
					 5 changed files with 119 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -568,8 +568,9 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
 | 
			
		|||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// set up SIGUSR1 handler to dump Go routine stacks
 | 
			
		||||
	setupSigusr1Trap()
 | 
			
		||||
	// set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
 | 
			
		||||
	// on Windows to dump Go routine stacks
 | 
			
		||||
	setupDumpStackTrap()
 | 
			
		||||
 | 
			
		||||
	// get the canonical path to the Docker root directory
 | 
			
		||||
	var realRoot string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ import (
 | 
			
		|||
	psignal "github.com/docker/docker/pkg/signal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func setupSigusr1Trap() {
 | 
			
		||||
func setupDumpStackTrap() {
 | 
			
		||||
	c := make(chan os.Signal, 1)
 | 
			
		||||
	signal.Notify(c, syscall.SIGUSR1)
 | 
			
		||||
	go func() {
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
// +build !linux,!darwin,!freebsd
 | 
			
		||||
// +build !linux,!darwin,!freebsd,!windows
 | 
			
		||||
 | 
			
		||||
package daemon
 | 
			
		||||
 | 
			
		||||
func setupSigusr1Trap() {
 | 
			
		||||
func setupDumpStackTrap() {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								daemon/debugtrap_windows.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								daemon/debugtrap_windows.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
package daemon
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	psignal "github.com/docker/docker/pkg/signal"
 | 
			
		||||
	"github.com/docker/docker/pkg/system"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func setupDumpStackTrap() {
 | 
			
		||||
	// Windows does not support signals like *nix systems. So instead of
 | 
			
		||||
	// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
 | 
			
		||||
	// signalled.
 | 
			
		||||
	go func() {
 | 
			
		||||
		sa := syscall.SecurityAttributes{
 | 
			
		||||
			Length: 0,
 | 
			
		||||
		}
 | 
			
		||||
		ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid())
 | 
			
		||||
		if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 {
 | 
			
		||||
			logrus.Debugf("Stackdump - waiting signal at %s", ev)
 | 
			
		||||
			for {
 | 
			
		||||
				syscall.WaitForSingleObject(h, syscall.INFINITE)
 | 
			
		||||
				psignal.DumpStacks()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								pkg/system/events_windows.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								pkg/system/events_windows.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
package system
 | 
			
		||||
 | 
			
		||||
// This file implements syscalls for Win32 events which are not implemented
 | 
			
		||||
// in golang.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	EVENT_ALL_ACCESS    = 0x1F0003
 | 
			
		||||
	EVENT_MODIFY_STATUS = 0x0002
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	procCreateEvent = modkernel32.NewProc("CreateEventW")
 | 
			
		||||
	procOpenEvent   = modkernel32.NewProc("OpenEventW")
 | 
			
		||||
	procSetEvent    = modkernel32.NewProc("SetEvent")
 | 
			
		||||
	procResetEvent  = modkernel32.NewProc("ResetEvent")
 | 
			
		||||
	procPulseEvent  = modkernel32.NewProc("PulseEvent")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func CreateEvent(eventAttributes *syscall.SecurityAttributes, manualReset bool, initialState bool, name string) (handle syscall.Handle, err error) {
 | 
			
		||||
	namep, _ := syscall.UTF16PtrFromString(name)
 | 
			
		||||
	var _p1 uint32 = 0
 | 
			
		||||
	if manualReset {
 | 
			
		||||
		_p1 = 1
 | 
			
		||||
	}
 | 
			
		||||
	var _p2 uint32 = 0
 | 
			
		||||
	if initialState {
 | 
			
		||||
		_p2 = 1
 | 
			
		||||
	}
 | 
			
		||||
	r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
 | 
			
		||||
	use(unsafe.Pointer(namep))
 | 
			
		||||
	handle = syscall.Handle(r0)
 | 
			
		||||
	if handle == syscall.InvalidHandle {
 | 
			
		||||
		err = e1
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle syscall.Handle, err error) {
 | 
			
		||||
	namep, _ := syscall.UTF16PtrFromString(name)
 | 
			
		||||
	var _p1 uint32 = 0
 | 
			
		||||
	if inheritHandle {
 | 
			
		||||
		_p1 = 1
 | 
			
		||||
	}
 | 
			
		||||
	r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep)))
 | 
			
		||||
	use(unsafe.Pointer(namep))
 | 
			
		||||
	handle = syscall.Handle(r0)
 | 
			
		||||
	if handle == syscall.InvalidHandle {
 | 
			
		||||
		err = e1
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetEvent(handle syscall.Handle) (err error) {
 | 
			
		||||
	return setResetPulse(handle, procSetEvent)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ResetEvent(handle syscall.Handle) (err error) {
 | 
			
		||||
	return setResetPulse(handle, procResetEvent)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PulseEvent(handle syscall.Handle) (err error) {
 | 
			
		||||
	return setResetPulse(handle, procPulseEvent)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setResetPulse(handle syscall.Handle, proc *syscall.LazyProc) (err error) {
 | 
			
		||||
	r0, _, _ := proc.Call(uintptr(handle))
 | 
			
		||||
	if r0 != 0 {
 | 
			
		||||
		err = syscall.Errno(r0)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var temp unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// use ensures a variable is kept alive without the GC freeing while still needed
 | 
			
		||||
func use(p unsafe.Pointer) {
 | 
			
		||||
	temp = p
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue