all repos

rss-tools @ a5ac52722b131734c74504b6e6f4d9900536cac7

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/go.etcd.io/bbolt/bolt_windows.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
package bbolt
2
3
import (
4
	"fmt"
5
	"os"
6
	"syscall"
7
	"time"
8
	"unsafe"
9
10
	"golang.org/x/sys/windows"
11
12
	"go.etcd.io/bbolt/errors"
13
	"go.etcd.io/bbolt/internal/common"
14
)
15
16
// fdatasync flushes written data to a file descriptor.
17
func fdatasync(db *DB) error {
18
	return db.file.Sync()
19
}
20
21
// flock acquires an advisory lock on a file descriptor.
22
func flock(db *DB, exclusive bool, timeout time.Duration) error {
23
	var t time.Time
24
	if timeout != 0 {
25
		t = time.Now()
26
	}
27
	var flags uint32 = windows.LOCKFILE_FAIL_IMMEDIATELY
28
	if exclusive {
29
		flags |= windows.LOCKFILE_EXCLUSIVE_LOCK
30
	}
31
	for {
32
		// Fix for https://github.com/etcd-io/bbolt/issues/121. Use byte-range
33
		// -1..0 as the lock on the database file.
34
		var m1 uint32 = (1 << 32) - 1 // -1 in a uint32
35
		err := windows.LockFileEx(windows.Handle(db.file.Fd()), flags, 0, 1, 0, &windows.Overlapped{
36
			Offset:     m1,
37
			OffsetHigh: m1,
38
		})
39
40
		if err == nil {
41
			return nil
42
		} else if err != windows.ERROR_LOCK_VIOLATION {
43
			return err
44
		}
45
46
		// If we timed oumercit then return an error.
47
		if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
48
			return errors.ErrTimeout
49
		}
50
51
		// Wait for a bit and try again.
52
		time.Sleep(flockRetryTimeout)
53
	}
54
}
55
56
// funlock releases an advisory lock on a file descriptor.
57
func funlock(db *DB) error {
58
	var m1 uint32 = (1 << 32) - 1 // -1 in a uint32
59
	return windows.UnlockFileEx(windows.Handle(db.file.Fd()), 0, 1, 0, &windows.Overlapped{
60
		Offset:     m1,
61
		OffsetHigh: m1,
62
	})
63
}
64
65
// mmap memory maps a DB's data file.
66
// Based on: https://github.com/edsrzf/mmap-go
67
func mmap(db *DB, sz int) error {
68
	var sizelo, sizehi uint32
69
70
	if !db.readOnly {
71
		// Truncate the database to the size of the mmap.
72
		if err := db.file.Truncate(int64(sz)); err != nil {
73
			return fmt.Errorf("truncate: %s", err)
74
		}
75
		sizehi = uint32(sz >> 32)
76
		sizelo = uint32(sz)
77
	}
78
79
	// Open a file mapping handle.
80
	h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizehi, sizelo, nil)
81
	if h == 0 {
82
		return os.NewSyscallError("CreateFileMapping", errno)
83
	}
84
85
	// Create the memory map.
86
	addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0)
87
	if addr == 0 {
88
		// Do our best and report error returned from MapViewOfFile.
89
		_ = syscall.CloseHandle(h)
90
		return os.NewSyscallError("MapViewOfFile", errno)
91
	}
92
93
	// Close mapping handle.
94
	if err := syscall.CloseHandle(syscall.Handle(h)); err != nil {
95
		return os.NewSyscallError("CloseHandle", err)
96
	}
97
98
	// Convert to a byte array.
99
	db.data = (*[common.MaxMapSize]byte)(unsafe.Pointer(addr))
100
	db.datasz = sz
101
102
	return nil
103
}
104
105
// munmap unmaps a pointer from a file.
106
// Based on: https://github.com/edsrzf/mmap-go
107
func munmap(db *DB) error {
108
	if db.data == nil {
109
		return nil
110
	}
111
112
	addr := (uintptr)(unsafe.Pointer(&db.data[0]))
113
	var err1 error
114
	if err := syscall.UnmapViewOfFile(addr); err != nil {
115
		err1 = os.NewSyscallError("UnmapViewOfFile", err)
116
	}
117
	db.data = nil
118
	db.datasz = 0
119
	return err1
120
}