aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_windows.go
blob: 1a6e83dad9b20fe721f3f5729bb2d8fc88515fb7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package azblob

import (
    "os"
    "reflect"
    "syscall"
    "unsafe"
)

type mmf []byte

func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
    prot, access := uint32(syscall.PAGE_READONLY), uint32(syscall.FILE_MAP_READ) // Assume read-only
    if writable {
        prot, access = uint32(syscall.PAGE_READWRITE), uint32(syscall.FILE_MAP_WRITE)
    }
    hMMF, errno := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, prot, uint32(int64(length)>>32), uint32(int64(length)&0xffffffff), nil)
    if hMMF == 0 {
        return nil, os.NewSyscallError("CreateFileMapping", errno)
    }
    defer syscall.CloseHandle(hMMF)
    addr, errno := syscall.MapViewOfFile(hMMF, access, uint32(offset>>32), uint32(offset&0xffffffff), uintptr(length))
    m := mmf{}
    h := (*reflect.SliceHeader)(unsafe.Pointer(&m))
    h.Data = addr
    h.Len = length
    h.Cap = h.Len
    return m, nil
}

func (m *mmf) unmap() {
    addr := uintptr(unsafe.Pointer(&(([]byte)(*m)[0])))
    *m = mmf{}
    err := syscall.UnmapViewOfFile(addr)
    if err != nil {
        panic(err)
    }
}