Skip to content

Commit 51b7de2

Browse files
committed
Modernize Windows mmap code
1 parent 5f9867c commit 51b7de2

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

mmap_windows.go

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ package maxminddb
3333
import (
3434
"errors"
3535
"os"
36-
"reflect"
3736
"sync"
3837
"unsafe"
3938

@@ -48,62 +47,83 @@ var (
4847
handleMap = map[uintptr]windows.Handle{}
4948
)
5049

51-
func mmap(fd int, length int) (data []byte, err error) {
52-
h, errno := windows.CreateFileMapping(windows.Handle(fd), nil,
53-
uint32(windows.PAGE_READONLY), 0, uint32(length), nil)
54-
if h == 0 {
55-
return nil, os.NewSyscallError("CreateFileMapping", errno)
50+
// mmap maps a file into memory and returns a memoryMap.
51+
func mmap(fd int, length int) ([]byte, error) {
52+
// Create a file mapping
53+
handle, err := windows.CreateFileMapping(
54+
windows.Handle(fd),
55+
nil,
56+
windows.PAGE_READONLY,
57+
0,
58+
uint32(length),
59+
nil,
60+
)
61+
if err != nil {
62+
return nil, os.NewSyscallError("CreateFileMapping", err)
5663
}
5764

58-
addr, errno := windows.MapViewOfFile(h, uint32(windows.FILE_MAP_READ), 0,
59-
0, uintptr(length))
60-
if addr == 0 {
61-
return nil, os.NewSyscallError("MapViewOfFile", errno)
65+
// Map the file into memory
66+
addr, err := windows.MapViewOfFile(
67+
handle,
68+
windows.FILE_MAP_READ,
69+
0,
70+
0,
71+
uintptr(length),
72+
)
73+
if err != nil {
74+
windows.CloseHandle(handle)
75+
return nil, os.NewSyscallError("MapViewOfFile", err)
6276
}
77+
78+
// Store the handle in the map
6379
handleLock.Lock()
64-
handleMap[addr] = h
80+
handleMap[addr] = handle
6581
handleLock.Unlock()
6682

67-
m := memoryMap{}
68-
dh := m.header()
69-
dh.Data = addr
70-
dh.Len = length
71-
dh.Cap = dh.Len
72-
73-
return m, nil
83+
// Convert addr to a slice without triggering warnings
84+
data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
85+
return data, nil
7486
}
7587

76-
func (m *memoryMap) header() *reflect.SliceHeader {
77-
return (*reflect.SliceHeader)(unsafe.Pointer(m))
78-
}
79-
80-
func flush(addr, len uintptr) error {
81-
errno := windows.FlushViewOfFile(addr, len)
82-
return os.NewSyscallError("FlushViewOfFile", errno)
88+
// flush ensures changes to a memory-mapped region are written to disk.
89+
func flush(addr, length uintptr) error {
90+
err := windows.FlushViewOfFile(addr, length)
91+
if err != nil {
92+
return os.NewSyscallError("FlushViewOfFile", err)
93+
}
94+
return nil
8395
}
8496

85-
func munmap(b []byte) (err error) {
86-
m := memoryMap(b)
87-
dh := m.header()
88-
89-
addr := dh.Data
90-
length := uintptr(dh.Len)
97+
// munmap unmaps a memory-mapped file and releases associated resources.
98+
func munmap(b []byte) error {
99+
// Convert slice to base address and length
100+
data := unsafe.SliceData(b)
101+
addr := uintptr(unsafe.Pointer(data))
102+
length := uintptr(len(b))
91103

92-
flush(addr, length)
93-
err = windows.UnmapViewOfFile(addr)
94-
if err != nil {
104+
// Flush the memory region
105+
if err := flush(addr, length); err != nil {
95106
return err
96107
}
97108

109+
// Unmap the memory
110+
if err := windows.UnmapViewOfFile(addr); err != nil {
111+
return os.NewSyscallError("UnmapViewOfFile", err)
112+
}
113+
114+
// Remove the handle from the map and close it
98115
handleLock.Lock()
99116
defer handleLock.Unlock()
117+
100118
handle, ok := handleMap[addr]
101119
if !ok {
102120
// should be impossible; we would've errored above
103121
return errors.New("unknown base address")
104122
}
105123
delete(handleMap, addr)
106124

107-
e := windows.CloseHandle(windows.Handle(handle))
108-
return os.NewSyscallError("CloseHandle", e)
125+
if err := windows.CloseHandle(handle); err != nil {
126+
return os.NewSyscallError("CloseHandle", err)
127+
}
128+
return nil
109129
}

0 commit comments

Comments
 (0)