"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "vendor/github.com/edsrzf/mmap-go/mmap_windows.go" between
gitea-1.9.3.tar.gz and gitea-1.9.4.tar.gz

About: Gitea allows to set up a self-hosted code hosting Git service (a fork of Gogs).

mmap_windows.go  (gitea-1.9.3):mmap_windows.go  (gitea-1.9.4)
// Copyright 2011 Evan Shaw. All rights reserved. // Copyright 2011 Evan Shaw. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package mmap package mmap
import ( import (
"errors" "errors"
"os" "os"
"sync" "sync"
"syscall"
"golang.org/x/sys/windows"
) )
// mmap on Windows is a two-step process. // mmap on Windows is a two-step process.
// First, we call CreateFileMapping to get a handle. // First, we call CreateFileMapping to get a handle.
// Then, we call MapviewToFile to get an actual pointer into memory. // Then, we call MapviewToFile to get an actual pointer into memory.
// Because we want to emulate a POSIX-style mmap, we don't want to expose // Because we want to emulate a POSIX-style mmap, we don't want to expose
// the handle -- only the pointer. We also want to return only a byte slice, // the handle -- only the pointer. We also want to return only a byte slice,
// not a struct, so it's convenient to manipulate. // not a struct, so it's convenient to manipulate.
// We keep this map so that we can get back the original handle from the memory address. // We keep this map so that we can get back the original handle from the memory address.
type addrinfo struct {
file windows.Handle
mapview windows.Handle
}
var handleLock sync.Mutex var handleLock sync.Mutex
var handleMap = map[uintptr]syscall.Handle{} var handleMap = map[uintptr]*addrinfo{}
func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
flProtect := uint32(syscall.PAGE_READONLY) flProtect := uint32(windows.PAGE_READONLY)
dwDesiredAccess := uint32(syscall.FILE_MAP_READ) dwDesiredAccess := uint32(windows.FILE_MAP_READ)
switch { switch {
case prot&COPY != 0: case prot&COPY != 0:
flProtect = syscall.PAGE_WRITECOPY flProtect = windows.PAGE_WRITECOPY
dwDesiredAccess = syscall.FILE_MAP_COPY dwDesiredAccess = windows.FILE_MAP_COPY
case prot&RDWR != 0: case prot&RDWR != 0:
flProtect = syscall.PAGE_READWRITE flProtect = windows.PAGE_READWRITE
dwDesiredAccess = syscall.FILE_MAP_WRITE dwDesiredAccess = windows.FILE_MAP_WRITE
} }
if prot&EXEC != 0 { if prot&EXEC != 0 {
flProtect <<= 4 flProtect <<= 4
dwDesiredAccess |= syscall.FILE_MAP_EXECUTE dwDesiredAccess |= windows.FILE_MAP_EXECUTE
} }
// The maximum size is the area of the file, starting from 0, // The maximum size is the area of the file, starting from 0,
// that we wish to allow to be mappable. It is the sum of // that we wish to allow to be mappable. It is the sum of
// the length the user requested, plus the offset where that length // the length the user requested, plus the offset where that length
// is starting from. This does not map the data into memory. // is starting from. This does not map the data into memory.
maxSizeHigh := uint32((off + int64(len)) >> 32) maxSizeHigh := uint32((off + int64(len)) >> 32)
maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF)
// TODO: Do we need to set some security attributes? It might help portab ility. // TODO: Do we need to set some security attributes? It might help portab ility.
h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProte ct, maxSizeHigh, maxSizeLow, nil) h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProte ct, maxSizeHigh, maxSizeLow, nil)
if h == 0 { if h == 0 {
return nil, os.NewSyscallError("CreateFileMapping", errno) return nil, os.NewSyscallError("CreateFileMapping", errno)
} }
// Actually map a view of the data into memory. The view's size // Actually map a view of the data into memory. The view's size
// is the length the user requested. // is the length the user requested.
fileOffsetHigh := uint32(off >> 32) fileOffsetHigh := uint32(off >> 32)
fileOffsetLow := uint32(off & 0xFFFFFFFF) fileOffsetLow := uint32(off & 0xFFFFFFFF)
addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len))
if addr == 0 { if addr == 0 {
return nil, os.NewSyscallError("MapViewOfFile", errno) return nil, os.NewSyscallError("MapViewOfFile", errno)
} }
handleLock.Lock() handleLock.Lock()
handleMap[addr] = h handleMap[addr] = &addrinfo{
file: windows.Handle(hfile),
mapview: h,
}
handleLock.Unlock() handleLock.Unlock()
m := MMap{} m := MMap{}
dh := m.header() dh := m.header()
dh.Data = addr dh.Data = addr
dh.Len = len dh.Len = len
dh.Cap = dh.Len dh.Cap = dh.Len
return m, nil return m, nil
} }
func flush(addr, len uintptr) error { func (m MMap) flush() error {
errno := syscall.FlushViewOfFile(addr, len) addr, len := m.addrLen()
errno := windows.FlushViewOfFile(addr, len)
if errno != nil { if errno != nil {
return os.NewSyscallError("FlushViewOfFile", errno) return os.NewSyscallError("FlushViewOfFile", errno)
} }
handleLock.Lock() handleLock.Lock()
defer handleLock.Unlock() defer handleLock.Unlock()
handle, ok := handleMap[addr] handle, ok := handleMap[addr]
if !ok { if !ok {
// should be impossible; we would've errored above // should be impossible; we would've errored above
return errors.New("unknown base address") return errors.New("unknown base address")
} }
errno = syscall.FlushFileBuffers(handle) errno = windows.FlushFileBuffers(handle.file)
return os.NewSyscallError("FlushFileBuffers", errno) return os.NewSyscallError("FlushFileBuffers", errno)
} }
func lock(addr, len uintptr) error { func (m MMap) lock() error {
errno := syscall.VirtualLock(addr, len) addr, len := m.addrLen()
errno := windows.VirtualLock(addr, len)
return os.NewSyscallError("VirtualLock", errno) return os.NewSyscallError("VirtualLock", errno)
} }
func unlock(addr, len uintptr) error { func (m MMap) unlock() error {
errno := syscall.VirtualUnlock(addr, len) addr, len := m.addrLen()
errno := windows.VirtualUnlock(addr, len)
return os.NewSyscallError("VirtualUnlock", errno) return os.NewSyscallError("VirtualUnlock", errno)
} }
func unmap(addr, len uintptr) error { func (m MMap) unmap() error {
flush(addr, len) err := m.flush()
if err != nil {
return err
}
addr := m.header().Data
// Lock the UnmapViewOfFile along with the handleMap deletion. // Lock the UnmapViewOfFile along with the handleMap deletion.
// As soon as we unmap the view, the OS is free to give the // As soon as we unmap the view, the OS is free to give the
// same addr to another new map. We don't want another goroutine // same addr to another new map. We don't want another goroutine
// to insert and remove the same addr into handleMap while // to insert and remove the same addr into handleMap while
// we're trying to remove our old addr/handle pair. // we're trying to remove our old addr/handle pair.
handleLock.Lock() handleLock.Lock()
defer handleLock.Unlock() defer handleLock.Unlock()
err := syscall.UnmapViewOfFile(addr) err = windows.UnmapViewOfFile(addr)
if err != nil { if err != nil {
return err return err
} }
handle, ok := handleMap[addr] handle, ok := handleMap[addr]
if !ok { if !ok {
// should be impossible; we would've errored above // should be impossible; we would've errored above
return errors.New("unknown base address") return errors.New("unknown base address")
} }
delete(handleMap, addr) delete(handleMap, addr)
e := syscall.CloseHandle(syscall.Handle(handle)) e := windows.CloseHandle(windows.Handle(handle.mapview))
return os.NewSyscallError("CloseHandle", e) return os.NewSyscallError("CloseHandle", e)
} }
 End of changes. 17 change blocks. 
23 lines changed or deleted 41 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)