zhangmeng
2019-08-26 a0123f163eddcea3e6b9f9d36f1f3fb3aa2c835a
update
5个文件已删除
2个文件已添加
3个文件已修改
436 ■■■■ 已修改文件
create.go 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
net/addr.go 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
net/conn.go 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
net/dialer.go 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
net/listener.go 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open.go 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
readwriter.go 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sem.go 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm.go 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
unlink.go 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
create.go
@@ -6,13 +6,11 @@
package shm
import (
    "golang.org/x/sys/unix"
    "os"
    "sync/atomic"
    "unsafe"
    "github.com/tmthrgd/go-sem"
    "github.com/tmthrgd/go-shm"
    "golang.org/x/sys/unix"
)
func CreateSimplex(name string, perm os.FileMode, blockCount, blockSize int) (*ReadWriteCloser, error) {
@@ -20,7 +18,7 @@
        return nil, ErrNotMultipleOf64
    }
    file, err := shm.Open(name, unix.O_CREAT|unix.O_EXCL|unix.O_TRUNC|unix.O_RDWR, perm)
    file, err := Open(name, unix.O_CREAT|unix.O_EXCL|unix.O_TRUNC|unix.O_RDWR, perm)
    if err != nil {
        return nil, err
    }
@@ -50,11 +48,11 @@
     */
    *(*uint32)(&shared.BlockCount), *(*uint64)(&shared.BlockSize) = uint32(blockCount), uint64(blockSize)
    if err = ((*sem.Semaphore)(&shared.SemSignal)).Init(0); err != nil {
    if err = ((*Semaphore)(&shared.SemSignal)).Init(0); err != nil {
        return nil, err
    }
    if err = ((*sem.Semaphore)(&shared.SemAvail)).Init(0); err != nil {
    if err = ((*Semaphore)(&shared.SemAvail)).Init(0); err != nil {
        return nil, err
    }
@@ -91,7 +89,7 @@
        return nil, ErrNotMultipleOf64
    }
    file, err := shm.Open(name, unix.O_CREAT|unix.O_EXCL|unix.O_TRUNC|unix.O_RDWR, perm)
    file, err := Open(name, unix.O_CREAT|unix.O_EXCL|unix.O_TRUNC|unix.O_RDWR, perm)
    if err != nil {
        return nil, err
    }
@@ -123,11 +121,11 @@
         */
        *(*uint32)(&shared.BlockCount), *(*uint64)(&shared.BlockSize) = uint32(blockCount), uint64(blockSize)
        if err = ((*sem.Semaphore)(&shared.SemSignal)).Init(0); err != nil {
        if err = ((*Semaphore)(&shared.SemSignal)).Init(0); err != nil {
            return nil, err
        }
        if err = ((*sem.Semaphore)(&shared.SemAvail)).Init(0); err != nil {
        if err = ((*Semaphore)(&shared.SemAvail)).Init(0); err != nil {
            return nil, err
        }
net/addr.go
File was deleted
net/conn.go
File was deleted
net/dialer.go
File was deleted
net/listener.go
File was deleted
open.go
@@ -6,15 +6,14 @@
package shm
import (
    "golang.org/x/sys/unix"
    "sync/atomic"
    "unsafe"
    "github.com/tmthrgd/go-shm"
    "golang.org/x/sys/unix"
)
func OpenSimplex(name string) (*ReadWriteCloser, error) {
    file, err := shm.Open(name, unix.O_RDWR, 0)
    file, err := Open(name, unix.O_RDWR, 0)
    if err != nil {
        return nil, err
    }
@@ -60,7 +59,7 @@
}
func OpenDuplex(name string) (*ReadWriteCloser, error) {
    file, err := shm.Open(name, unix.O_RDWR, 0)
    file, err := Open(name, unix.O_RDWR, 0)
    if err != nil {
        return nil, err
    }
readwriter.go
@@ -6,12 +6,11 @@
package shm
import (
    "golang.org/x/sys/unix"
    "io"
    "sync/atomic"
    "unsafe"
    "github.com/tmthrgd/go-sem"
    "golang.org/x/sys/unix"
)
const (
@@ -55,22 +54,6 @@
// Name returns the name of the shared memory.
func (rw *ReadWriteCloser) Name() string {
    return rw.name
}
// Unlink removes the shared memory.
//
// It is the equivalent to calling Unlink(string) with
// the same name as Create* or Open*.
//
// Taken from shm_unlink(3):
//     The  operation  of shm_unlink() is analogous to unlink(2): it removes a
//     shared memory object name, and, once all processes  have  unmapped  the
//     object, de-allocates and destroys the contents of the associated memory
//     region.  After a successful shm_unlink(),  attempts  to  shm_open()  an
//     object  with  the same name will fail (unless O_CREAT was specified, in
//     which case a new, distinct object is created).
func (rw *ReadWriteCloser) Unlink() error {
    return Unlink(rw.name)
}
// Read
@@ -135,7 +118,7 @@
        block = (*sharedBlock)(unsafe.Pointer(blocks + uintptr(uint64(blockIndex)*rw.fullBlockSize)))
        if blockIndex == atomic.LoadUint32((*uint32)(&rw.readShared.WriteEnd)) {
            if err := ((*sem.Semaphore)(&rw.readShared.SemSignal)).Wait(); err != nil {
            if err := ((*Semaphore)(&rw.readShared.SemSignal)).Wait(); err != nil {
                return Buffer{}, err
            }
@@ -187,7 +170,7 @@
        atomic.CompareAndSwapUint32((*uint32)(&rw.readShared.ReadEnd), blockIndex, uint32(block.Next))
        if uint32(block.Prev) == atomic.LoadUint32((*uint32)(&rw.readShared.WriteStart)) {
            if err := ((*sem.Semaphore)(&rw.readShared.SemAvail)).Post(); err != nil {
            if err := ((*Semaphore)(&rw.readShared.SemAvail)).Post(); err != nil {
                return err
            }
        }
@@ -258,7 +241,7 @@
        block = (*sharedBlock)(unsafe.Pointer(blocks + uintptr(uint64(blockIndex)*rw.fullBlockSize)))
        if uint32(block.Next) == atomic.LoadUint32((*uint32)(&rw.writeShared.ReadEnd)) {
            if err := ((*sem.Semaphore)(&rw.writeShared.SemAvail)).Wait(); err != nil {
            if err := ((*Semaphore)(&rw.writeShared.SemAvail)).Wait(); err != nil {
                return Buffer{}, err
            }
@@ -313,7 +296,7 @@
        atomic.CompareAndSwapUint32((*uint32)(&rw.writeShared.WriteEnd), blockIndex, uint32(block.Next))
        if blockIndex == atomic.LoadUint32((*uint32)(&rw.writeShared.ReadStart)) {
            if err := ((*sem.Semaphore)(&rw.writeShared.SemSignal)).Post(); err != nil {
            if err := ((*Semaphore)(&rw.writeShared.SemSignal)).Post(); err != nil {
                return len(buf.Data), err
            }
        }
sem.go
New file
@@ -0,0 +1,114 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs sem_linux.go
package shm
import (
    "sync/atomic"
    "syscall"
    "unsafe"
    "golang.org/x/sys/unix"
)
type Semaphore [32]byte
type newSem struct {
    Value    uint32
    Private  int32
    NWaiters uint64
}
func New(value uint) (*Semaphore, error) {
    sem := new(Semaphore)
    if err := sem.Init(value); err != nil {
        return nil, err
    }
    return sem, nil
}
func atomicDecrementIfPositive(mem *uint32) uint32 {
    for {
        if old := atomic.LoadUint32(mem); old == 0 || atomic.CompareAndSwapUint32(mem, old, old-1) {
            return old
        }
    }
}
func (sem *Semaphore) Wait() error {
    isem := (*newSem)(unsafe.Pointer(sem))
    if atomicDecrementIfPositive(&isem.Value) > 0 {
        return nil
    }
    atomic.AddUint64(&isem.NWaiters, 1)
    for {
        t := syscall.Timeval{3 /*sec*/, 0 /*usec*/}
        if _, _, err := unix.Syscall6(unix.SYS_FUTEX, uintptr(unsafe.Pointer(&isem.Value)), uintptr(0x0), 0, uintptr(unsafe.Pointer(&t)), 0, 0); err != 0 && err != unix.EWOULDBLOCK {
            atomic.AddUint64(&isem.NWaiters, ^uint64(0))
            return err
        }
        if atomicDecrementIfPositive(&isem.Value) > 0 {
            atomic.AddUint64(&isem.NWaiters, ^uint64(0))
            return nil
        }
    }
}
func (sem *Semaphore) TryWait() error {
    isem := (*newSem)(unsafe.Pointer(sem))
    if atomicDecrementIfPositive(&isem.Value) > 0 {
        return nil
    }
    return unix.EAGAIN
}
func (sem *Semaphore) Post() error {
    isem := (*newSem)(unsafe.Pointer(sem))
    for {
        cur := atomic.LoadUint32(&isem.Value)
        if cur == 0x7fffffff {
            return unix.EOVERFLOW
        }
        if atomic.CompareAndSwapUint32(&isem.Value, cur, cur+1) {
            break
        }
    }
    if atomic.LoadUint64(&isem.NWaiters) <= 0 {
        return nil
    }
    if _, _, err := unix.Syscall6(unix.SYS_FUTEX, uintptr(unsafe.Pointer(&isem.Value)), uintptr(0x1), 1, 0, 0, 0); err != 0 {
        return err
    }
    return nil
}
func (sem *Semaphore) Init(value uint) error {
    if value > 0x7fffffff {
        return unix.EINVAL
    }
    isem := (*newSem)(unsafe.Pointer(sem))
    isem.Value = uint32(value)
    isem.Private = 0
    isem.NWaiters = 0
    return nil
}
func (sem *Semaphore) Destroy() error {
    return nil
}
shm.go
New file
@@ -0,0 +1,83 @@
// Copyright 2016 Tom Thorogood. All rights reserved.
// Use of this source code is governed by a
// Modified BSD License license that can be found in
// the LICENSE file.
// Package shm provides functions to open and unlink shared memory.
package shm
import (
    "os"
    "golang.org/x/sys/unix"
)
const devShm = "/dev/shm/"
// Taken from shm_open(3):
//     shm_open() creates and opens a new, or opens an existing, POSIX shared
//     memory object. A POSIX shared memory object is in effect a handle which
//     can be used by unrelated processes to mmap(2) the same region of shared
//     memory. The shm_unlink() function performs the converse operation,
//     removing an object previously created by shm_open().
//
//     The operation of shm_open() is analogous to that of open(2). name
//     specifies the shared memory object to be created or opened. For
//     portable use, a shared memory object should be identified by a name of
//     the form /somename; that is, a null-terminated string of up to NAME_MAX
//     (i.e., 255) characters consisting of an initial slash, followed by one
//     or more characters, none of which are slashes.
func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
    fileName := name
    for len(name) != 0 && name[0] == '/' {
        name = name[1:]
    }
    if len(name) == 0 {
        return nil, &os.PathError{Op: "open", Path: fileName, Err: unix.EINVAL}
    }
    o := uint32(perm.Perm())
    if perm&os.ModeSetuid != 0 {
        o |= unix.S_ISUID
    }
    if perm&os.ModeSetgid != 0 {
        o |= unix.S_ISGID
    }
    if perm&os.ModeSticky != 0 {
        o |= unix.S_ISVTX
    }
    fd, err := unix.Open(devShm+name, flag|unix.O_CLOEXEC, o)
    if err != nil {
        return nil, &os.PathError{Op: "open", Path: fileName, Err: err}
    }
    return os.NewFile(uintptr(fd), fileName), nil
}
// Taken from shm_unlink(3):
//     The  operation  of shm_unlink() is analogous to unlink(2): it removes a
//     shared memory object name, and, once all processes  have  unmapped  the
//     object, de-allocates and destroys the contents of the associated memory
//     region.  After a successful shm_unlink(),  attempts  to  shm_open()  an
//     object  with  the same name will fail (unless O_CREAT was specified, in
//     which case a new, distinct object is created).
func Unlink(name string) error {
    fileName := name
    for len(name) != 0 && name[0] == '/' {
        name = name[1:]
    }
    if len(name) == 0 {
        return &os.PathError{Op: "unlink", Path: fileName, Err: unix.EINVAL}
    }
    if err := unix.Unlink(devShm + name); err != nil {
        return &os.PathError{Op: "unlink", Path: fileName, Err: err}
    }
    return nil
}
unlink.go
File was deleted