@@ -33,77 +33,94 @@ package maxminddb
3333import (
3434 "errors"
3535 "os"
36- "reflect"
3736 "sync"
3837 "unsafe"
3938
4039 "golang.org/x/sys/windows"
4140)
4241
43- type memoryMap []byte
44-
4542// Windows
4643var (
4744 handleLock sync.Mutex
4845 handleMap = map [uintptr ]windows.Handle {}
4946)
5047
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 )
48+ // mmap maps a file into memory and returns a memoryMap.
49+ func mmap (fd int , length int ) ([]byte , error ) {
50+ // Create a file mapping
51+ handle , err := windows .CreateFileMapping (
52+ windows .Handle (fd ),
53+ nil ,
54+ windows .PAGE_READONLY ,
55+ 0 ,
56+ uint32 (length ),
57+ nil ,
58+ )
59+ if err != nil {
60+ return nil , os .NewSyscallError ("CreateFileMapping" , err )
5661 }
5762
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 )
63+ // Map the file into memory
64+ addr , err := windows .MapViewOfFile (
65+ handle ,
66+ windows .FILE_MAP_READ ,
67+ 0 ,
68+ 0 ,
69+ uintptr (length ),
70+ )
71+ if err != nil {
72+ windows .CloseHandle (handle )
73+ return nil , os .NewSyscallError ("MapViewOfFile" , err )
6274 }
75+
76+ // Store the handle in the map
6377 handleLock .Lock ()
64- handleMap [addr ] = h
78+ handleMap [addr ] = handle
6579 handleLock .Unlock ()
6680
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
74- }
75-
76- func (m * memoryMap ) header () * reflect.SliceHeader {
77- return (* reflect .SliceHeader )(unsafe .Pointer (m ))
81+ data := unsafe .Slice ((* byte )(unsafe .Pointer (addr )), length )
82+ return data , nil
7883}
7984
80- func flush (addr , len uintptr ) error {
81- errno := windows .FlushViewOfFile (addr , len )
82- return os .NewSyscallError ("FlushViewOfFile" , errno )
85+ // flush ensures changes to a memory-mapped region are written to disk.
86+ func flush (addr , length uintptr ) error {
87+ err := windows .FlushViewOfFile (addr , length )
88+ if err != nil {
89+ return os .NewSyscallError ("FlushViewOfFile" , err )
90+ }
91+ return nil
8392}
8493
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 )
94+ // munmap unmaps a memory-mapped file and releases associated resources.
95+ func munmap ( b [] byte ) error {
96+ // Convert slice to base address and length
97+ data := unsafe . SliceData ( b )
98+ addr := uintptr ( unsafe . Pointer ( data ))
99+ length := uintptr (len ( b ) )
91100
92- flush (addr , length )
93- err = windows .UnmapViewOfFile (addr )
94- if err != nil {
101+ // Flush the memory region
102+ if err := flush (addr , length ); err != nil {
95103 return err
96104 }
97105
106+ // Unmap the memory
107+ if err := windows .UnmapViewOfFile (addr ); err != nil {
108+ return os .NewSyscallError ("UnmapViewOfFile" , err )
109+ }
110+
111+ // Remove the handle from the map and close it
98112 handleLock .Lock ()
99113 defer handleLock .Unlock ()
114+
100115 handle , ok := handleMap [addr ]
101116 if ! ok {
102117 // should be impossible; we would've errored above
103118 return errors .New ("unknown base address" )
104119 }
105120 delete (handleMap , addr )
106121
107- e := windows .CloseHandle (windows .Handle (handle ))
108- return os .NewSyscallError ("CloseHandle" , e )
122+ if err := windows .CloseHandle (handle ); err != nil {
123+ return os .NewSyscallError ("CloseHandle" , err )
124+ }
125+ return nil
109126}
0 commit comments