Rolled back some stuff here like the package stuff
This will add support to view live data
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package sharedMem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Memory is shared memory struct
|
||||
type Memory struct {
|
||||
m *shmi
|
||||
pos int64
|
||||
}
|
||||
|
||||
// Create is create shared memory
|
||||
func Create(name string, size uint32) (*Memory, error) {
|
||||
m, err := create(name, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Memory{m, 0}, nil
|
||||
}
|
||||
|
||||
// Open is open exist shared memory
|
||||
func Open(name string, size uint32) (*Memory, error) {
|
||||
m, err := open(name, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Memory{m, 0}, nil
|
||||
}
|
||||
|
||||
// Close is close & discard shared memory
|
||||
func (o *Memory) Close() (err error) {
|
||||
if o.m != nil {
|
||||
err = o.m.close()
|
||||
if err == nil {
|
||||
o.m = nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Read is read shared memory (current position)
|
||||
func (o *Memory) Read(p []byte) (n int, err error) {
|
||||
n, err = o.ReadAt(p, o.pos)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o.pos += int64(n)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// ReadAt is read shared memory (offset)
|
||||
func (o *Memory) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
return o.m.readAt(p, off)
|
||||
}
|
||||
|
||||
// Seek is move read/write position at shared memory
|
||||
func (o *Memory) Seek(offset int64, whence int) (int64, error) {
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
offset += int64(0)
|
||||
case io.SeekCurrent:
|
||||
offset += o.pos
|
||||
case io.SeekEnd:
|
||||
offset += int64(o.m.size)
|
||||
}
|
||||
if offset < 0 || offset >= int64(o.m.size) {
|
||||
return 0, fmt.Errorf("invalid offset")
|
||||
}
|
||||
o.pos = offset
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// Write is write shared memory (current position)
|
||||
func (o *Memory) Write(p []byte) (n int, err error) {
|
||||
n, err = o.WriteAt(p, o.pos)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o.pos += int64(n)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteAt is write shared memory (offset)
|
||||
func (o *Memory) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
return o.m.writeAt(p, off)
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
//go:build darwin && cgo
|
||||
// +build darwin,cgo
|
||||
|
||||
package sharedMem
|
||||
|
||||
/*
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
int _create(const char* name, int size, int flag) {
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
|
||||
int fd = shm_open(name, flag, mode);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stat mapstat;
|
||||
int ret = fstat(fd, &mapstat);
|
||||
if (ret != -1 && mapstat.st_size == 0) {
|
||||
if (ftruncate(fd, size) != 0) {
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
} else if (ret == -1) {
|
||||
close(fd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int Create(const char* name, int size) {
|
||||
int flag = O_RDWR | O_CREAT;
|
||||
return _create(name, size, flag);
|
||||
}
|
||||
|
||||
int Open(const char* name, int size) {
|
||||
int flag = O_RDWR;
|
||||
return _create(name, size, flag);
|
||||
}
|
||||
|
||||
void* Map(int fd, int size) {
|
||||
void* p = mmap(
|
||||
NULL, size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Close(int fd, void* p, int size) {
|
||||
if (p != NULL) {
|
||||
munmap(p, size);
|
||||
}
|
||||
if (fd != 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Delete(const char* name) {
|
||||
shm_unlink(name);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type shmi struct {
|
||||
name string
|
||||
fd C.int
|
||||
v unsafe.Pointer
|
||||
size int32
|
||||
parent bool
|
||||
}
|
||||
|
||||
// create shared memory. return shmi object.
|
||||
// name should not be more than 31 bytes.
|
||||
func create(name string, size int32) (*shmi, error) {
|
||||
name = "/" + name
|
||||
|
||||
fd := C.Create(C.CString(name), C.int(size))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("create")
|
||||
}
|
||||
|
||||
v := C.Map(fd, C.int(size))
|
||||
if v == nil {
|
||||
C.Close(fd, nil, C.int(size))
|
||||
C.Delete(C.CString(name))
|
||||
}
|
||||
|
||||
return &shmi{name, fd, v, size, true}, nil
|
||||
}
|
||||
|
||||
// open shared memory. return shmi object.
|
||||
// name should not be more than 31 bytes.
|
||||
func open(name string, size int32) (*shmi, error) {
|
||||
name = "/" + name
|
||||
|
||||
fd := C.Open(C.CString(name), C.int(size))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("open")
|
||||
}
|
||||
|
||||
v := C.Map(fd, C.int(size))
|
||||
if v == nil {
|
||||
C.Close(fd, nil, C.int(size))
|
||||
C.Delete(C.CString(name))
|
||||
}
|
||||
|
||||
return &shmi{name, fd, v, size, false}, nil
|
||||
}
|
||||
|
||||
func (o *shmi) close() error {
|
||||
if o.v != nil {
|
||||
C.Close(o.fd, o.v, C.int(o.size))
|
||||
o.v = nil
|
||||
}
|
||||
if o.parent {
|
||||
C.Delete(C.CString(o.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// read shared memory. return read size.
|
||||
func (o *shmi) readAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copyPtr2Slice(uintptr(o.v), p, off, o.size), nil
|
||||
}
|
||||
|
||||
// write shared memory. return write size.
|
||||
func (o *shmi) writeAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copySlice2Ptr(p, uintptr(o.v), off, o.size), nil
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
//go:build linux && cgo
|
||||
// +build linux,cgo
|
||||
|
||||
package sharedMem
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -lrt
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int _create(const char* name, int size, int flag) {
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
|
||||
int fd = shm_open(name, flag, mode);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, size) != 0) {
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int Create(const char* name, int size) {
|
||||
int flag = O_RDWR | O_CREAT;
|
||||
return _create(name, size, flag);
|
||||
}
|
||||
|
||||
int Open(const char* name, int size) {
|
||||
int flag = O_RDWR;
|
||||
return _create(name, size, flag);
|
||||
}
|
||||
|
||||
void* Map(int fd, int size) {
|
||||
void* p = mmap(
|
||||
NULL, size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Close(int fd, void* p, int size) {
|
||||
if (p != NULL) {
|
||||
munmap(p, size);
|
||||
}
|
||||
if (fd != 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Delete(const char* name) {
|
||||
shm_unlink(name);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type shmi struct {
|
||||
name string
|
||||
fd C.int
|
||||
v unsafe.Pointer
|
||||
size int32
|
||||
parent bool
|
||||
}
|
||||
|
||||
// create shared memory. return shmi object.
|
||||
func create(name string, size int32) (*shmi, error) {
|
||||
name = "/" + name
|
||||
|
||||
fd := C.Create(C.CString(name), C.int(size))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("create")
|
||||
}
|
||||
|
||||
v := C.Map(fd, C.int(size))
|
||||
if v == nil {
|
||||
C.Close(fd, nil, C.int(size))
|
||||
C.Delete(C.CString(name))
|
||||
}
|
||||
|
||||
return &shmi{name, fd, v, size, true}, nil
|
||||
}
|
||||
|
||||
// open shared memory. return shmi object.
|
||||
func open(name string, size int32) (*shmi, error) {
|
||||
name = "/" + name
|
||||
|
||||
fd := C.Open(C.CString(name), C.int(size))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("open")
|
||||
}
|
||||
|
||||
v := C.Map(fd, C.int(size))
|
||||
if v == nil {
|
||||
C.Close(fd, nil, C.int(size))
|
||||
C.Delete(C.CString(name))
|
||||
}
|
||||
|
||||
return &shmi{name, fd, v, size, false}, nil
|
||||
}
|
||||
|
||||
func (o *shmi) close() error {
|
||||
if o.v != nil {
|
||||
C.Close(o.fd, o.v, C.int(o.size))
|
||||
o.v = nil
|
||||
}
|
||||
if o.parent {
|
||||
C.Delete(C.CString(o.name))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// read shared memory. return read size.
|
||||
func (o *shmi) readAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copyPtr2Slice(uintptr(o.v), p, off, o.size), nil
|
||||
}
|
||||
|
||||
// write shared memory. return write size.
|
||||
func (o *shmi) writeAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copySlice2Ptr(p, uintptr(o.v), off, o.size), nil
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package sharedMem
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type shmi struct {
|
||||
h windows.Handle
|
||||
v uintptr
|
||||
size uint32
|
||||
}
|
||||
|
||||
// create shared memory. return shmi object.
|
||||
func create(name string, size uint32) (*shmi, error) {
|
||||
fnPtr, _ := windows.UTF16PtrFromString(name)
|
||||
|
||||
flProtect := uint32(windows.PAGE_READONLY)
|
||||
|
||||
h, errno := windows.CreateFileMapping(
|
||||
windows.InvalidHandle,
|
||||
nil,
|
||||
flProtect,
|
||||
0,
|
||||
size,
|
||||
fnPtr)
|
||||
if h == 0 {
|
||||
log.Fatal("could not open memmap file: ", errno)
|
||||
}
|
||||
|
||||
addr, errno := windows.MapViewOfFile(h,
|
||||
windows.FILE_MAP_READ,
|
||||
0,
|
||||
0,
|
||||
uintptr(size))
|
||||
if addr == 0 {
|
||||
log.Printf("error in MapViewOfFile: %v", errno)
|
||||
}
|
||||
|
||||
return &shmi{h, addr, size}, nil
|
||||
}
|
||||
|
||||
// open shared memory. return shmi object.
|
||||
func open(name string, size uint32) (*shmi, error) {
|
||||
return create(name, size)
|
||||
}
|
||||
|
||||
func (o *shmi) close() error {
|
||||
if o.v != uintptr(0) {
|
||||
windows.UnmapViewOfFile(o.v)
|
||||
o.v = uintptr(0)
|
||||
}
|
||||
if o.h != windows.InvalidHandle {
|
||||
windows.CloseHandle(o.h)
|
||||
o.h = windows.InvalidHandle
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// read shared memory. return read size.
|
||||
func (o *shmi) readAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copyPtr2Slice(o.v, p, off, o.size), nil
|
||||
}
|
||||
|
||||
// write shared memory. return write size.
|
||||
func (o *shmi) writeAt(p []byte, off int64) (n int, err error) {
|
||||
if off >= int64(o.size) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if max := int64(o.size) - off; int64(len(p)) > max {
|
||||
p = p[:max]
|
||||
}
|
||||
return copySlice2Ptr(p, o.v, off, o.size), nil
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package sharedMem
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func copySlice2Ptr(b []byte, p uintptr, off int64, size uint32) int {
|
||||
bb := unsafe.Slice((*byte)(*(*unsafe.Pointer)(unsafe.Pointer(&p))), int(size))
|
||||
return copy(bb[off:], b)
|
||||
}
|
||||
|
||||
func copyPtr2Slice(p uintptr, b []byte, off int64, size uint32) int {
|
||||
bb := unsafe.Slice((*byte)(*(*unsafe.Pointer)(unsafe.Pointer(&p))), int(size))
|
||||
return copy(b, bb[off:size])
|
||||
}
|
||||
Reference in New Issue
Block a user