Class: Winipc::SharedMemory
- Inherits:
-
Object
- Object
- Winipc::SharedMemory
- Defined in:
- lib/winipc.rb,
ext/winipc/winipc.c
Class Method Summary collapse
-
._create(wname, vsize, rw, access) ⇒ Object
SharedMemory._create(wname, size, readwrite, access) -> SharedMemory.
-
._open(wname, rw) ⇒ Object
SharedMemory._open(wname, readwrite) -> SharedMemory.
-
.create(name, size, access: :readwrite, scope: :local, security: :owner) ⇒ Object
Create a named, pagefile-backed shared-memory region of
sizebytes. -
.open(name, access: :readwrite, scope: :local) ⇒ Object
Open an existing named region.
Instance Method Summary collapse
- #_flush(voff, vlen) ⇒ Object
- #close ⇒ Object
- #closed? ⇒ Boolean
-
#flush(offset = 0, len = nil) ⇒ Object
Flush a range (default: whole region) to backing storage.
- #read(voff, vlen) ⇒ Object
- #size ⇒ Object
- #write(voff, data) ⇒ Object
Class Method Details
._create(wname, vsize, rw, access) ⇒ Object
SharedMemory._create(wname, size, readwrite, access) -> SharedMemory
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 |
# File 'ext/winipc/winipc.c', line 813
static VALUE
shm_create(VALUE klass, VALUE wname, VALUE vsize, VALUE rw, VALUE access)
{
VALUE obj = shm_alloc(cSharedMemory);
shm_t *s = shm_get(obj);
unsigned long long size = NUM2ULL(vsize);
int writable = RTEST(rw);
SECURITY_ATTRIBUTES sa;
PSECURITY_DESCRIPTOR psd = NULL;
DWORD prot = writable ? PAGE_READWRITE : PAGE_READONLY;
DWORD hi = (DWORD)(size >> 32), lo = (DWORD)(size & 0xFFFFFFFFull);
DWORD gle;
int use_sa;
WCHAR *name;
if (size == 0) rb_raise(rb_eArgError, "winipc: size must be > 0");
use_sa = build_sa(access, &sa, &psd); /* may raise; do before allocating name */
name = to_wide(wname);
s->map = CreateFileMappingW(INVALID_HANDLE_VALUE, use_sa ? &sa : NULL, prot, hi, lo, name);
gle = GetLastError();
xfree(name);
if (psd) LocalFree(psd);
if (!s->map) raise_gle("CreateFileMapping", gle);
if (gle == ERROR_ALREADY_EXISTS) {
/* a mapping of that name already exists with its OWN size — refuse */
CloseHandle(s->map); s->map = NULL;
raise_code(eExists, "CreateFileMapping", ERROR_ALREADY_EXISTS);
}
s->view = MapViewOfFile(s->map, writable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, 0, 0);
if (!s->view) raise_gle("MapViewOfFile", GetLastError());
s->size = size;
s->writable = writable;
return obj;
}
|
._open(wname, rw) ⇒ Object
SharedMemory._open(wname, readwrite) -> SharedMemory
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 |
# File 'ext/winipc/winipc.c', line 851
static VALUE
shm_open(VALUE klass, VALUE wname, VALUE rw)
{
VALUE obj = shm_alloc(cSharedMemory);
shm_t *s = shm_get(obj);
int writable = RTEST(rw);
WCHAR *name = to_wide(wname);
DWORD acc = writable ? FILE_MAP_WRITE : FILE_MAP_READ;
MEMORY_BASIC_INFORMATION mbi;
DWORD gle;
s->map = OpenFileMappingW(acc, FALSE, name);
gle = GetLastError();
xfree(name);
if (!s->map) raise_gle("OpenFileMapping", gle);
s->view = MapViewOfFile(s->map, acc, 0, 0, 0);
if (!s->view) raise_gle("MapViewOfFile", GetLastError());
/* Discover the mapped region size (the opener didn't specify it). */
if (VirtualQuery(s->view, &mbi, sizeof(mbi)) == 0)
raise_gle("VirtualQuery", GetLastError());
s->size = (unsigned long long)mbi.RegionSize;
s->writable = writable;
return obj;
}
|
.create(name, size, access: :readwrite, scope: :local, security: :owner) ⇒ Object
Create a named, pagefile-backed shared-memory region of size bytes.
226 227 228 |
# File 'lib/winipc.rb', line 226 def self.create(name, size, access: :readwrite, scope: :local, security: :owner) _create(Winipc.obj_path(name, scope), Integer(size), access != :readonly, security) end |
Instance Method Details
#_flush(voff, vlen) ⇒ Object
912 913 914 915 916 917 918 919 920 921 922 923 |
# File 'ext/winipc/winipc.c', line 912
static VALUE
shm_flush(VALUE self, VALUE voff, VALUE vlen)
{
shm_t *s = shm_live(self);
unsigned long long off = NUM2ULL(voff), len = NIL_P(vlen) ? 0 : NUM2ULL(vlen);
if (off > s->size) rb_raise(eRangeError, "winipc: flush offset out of bounds");
if (len) shm_bounds(s, off, len);
if (off >= s->size) return self; /* nothing past the end to flush (no-op) */
if (!FlushViewOfFile((char *)s->view + off, (SIZE_T)len))
raise_gle("FlushViewOfFile", GetLastError());
return self;
}
|
#close ⇒ Object
927 928 929 930 931 932 933 934 935 |
# File 'ext/winipc/winipc.c', line 927
static VALUE
shm_close(VALUE self)
{
shm_t *s = shm_get(self);
if (s->view) { UnmapViewOfFile(s->view); s->view = NULL; }
if (s->map) { CloseHandle(s->map); s->map = NULL; }
s->closed = 1;
return Qnil;
}
|
#closed? ⇒ Boolean
937 |
# File 'ext/winipc/winipc.c', line 937
static VALUE shm_closed_p(VALUE self) { return shm_get(self)->closed ? Qtrue : Qfalse; }
|
#flush(offset = 0, len = nil) ⇒ Object
Flush a range (default: whole region) to backing storage.
236 237 238 |
# File 'lib/winipc.rb', line 236 def flush(offset = 0, len = nil) _flush(offset, len) end |
#read(voff, vlen) ⇒ Object
885 886 887 888 889 890 891 892 893 894 895 896 897 |
# File 'ext/winipc/winipc.c', line 885
static VALUE
shm_read(VALUE self, VALUE voff, VALUE vlen)
{
shm_t *s = shm_live(self);
unsigned long long off = NUM2ULL(voff), len = NUM2ULL(vlen);
VALUE out;
shm_bounds(s, off, len);
if (len > (unsigned long long)LONG_MAX)
rb_raise(rb_eArgError, "winipc: read length too large");
out = rb_str_new((const char *)s->view + off, (long)len);
rb_enc_associate(out, rb_ascii8bit_encoding());
return out;
}
|
#size ⇒ Object
925 |
# File 'ext/winipc/winipc.c', line 925
static VALUE shm_size(VALUE self) { return ULL2NUM(shm_get(self)->size); }
|
#write(voff, data) ⇒ Object
899 900 901 902 903 904 905 906 907 908 909 910 |
# File 'ext/winipc/winipc.c', line 899
static VALUE
shm_write(VALUE self, VALUE voff, VALUE data)
{
shm_t *s = shm_live(self);
unsigned long long off = NUM2ULL(voff);
DWORD len;
if (!s->writable) rb_raise(eError, "winipc: shared memory is read-only");
len = dword_len(data);
shm_bounds(s, off, (unsigned long long)len);
memcpy((char *)s->view + off, RSTRING_PTR(data), len);
return ULONG2NUM(len);
}
|