func FetchNumThreads()

in metric/system/process/process_windows.go [105:146]


func FetchNumThreads(pid int) (int, error) {
	targetProcessHandle, err := syscall.OpenProcess(
		xsyswindows.PROCESS_QUERY_INFORMATION,
		false,
		uint32(pid))
	if err != nil {
		return 0, fmt.Errorf("OpenProcess failed for PID %d: %w", pid, err)
	}
	defer func() {
		_ = syscall.CloseHandle(targetProcessHandle)
	}()

	currentProcessHandle, err := syscall.GetCurrentProcess()
	if err != nil {
		return 0, fmt.Errorf("GetCurrentProcess failed for PID %d: %w", pid, err)
	}
	// The pseudo handle need not be closed when it is no longer
	// needed, calling CloseHandle has no effect.  Adding here to
	// remind us to close any handles we open.
	defer func() {
		_ = syscall.CloseHandle(currentProcessHandle)
	}()

	var snapshotHandle syscall.Handle
	err = PssCaptureSnapshot(targetProcessHandle, PSSCaptureThreads, 0, &snapshotHandle)
	if err != nil {
		return 0, fmt.Errorf("PssCaptureSnapshot failed for PID %d: %w", pid, err)
	}

	info := PssThreadInformation{}
	buffSize := unsafe.Sizeof(info)
	queryErr := PssQuerySnapshot(snapshotHandle, PssQueryThreadInformation, &info, uint32(buffSize))
	freeErr := PssFreeSnapshot(currentProcessHandle, snapshotHandle)
	if queryErr != nil || freeErr != nil {
		//Join discards any nil errors
		return 0, errors.Join(
			fmt.Errorf("PssQuerySnapshot failed: %w", queryErr),
			fmt.Errorf("PssFreeSnapshot failed: %w", freeErr))
	}

	return int(info.ThreadsCaptured), nil
}