Class: ConcurrentSHM::Region
- Inherits:
-
Object
- Object
- ConcurrentSHM::Region
- Defined in:
- ext/concurrent-shm/posix.c,
ext/concurrent-shm/posix.c
Overview
A memory-mapped region of a file or shared memory space.
Class Method Summary collapse
-
.map(file, off, len) ⇒ Region
Memory-map a region of a file or shared memory space.
-
.unmap(region) ⇒ Object
Unmaps a memory-mapped region.
Instance Method Summary collapse
-
#[](*args) ⇒ Region
Get a subregion of the receiver.
-
#aligned?(bytes) ⇒ Boolean
Returns true if the region is aligned to the specified byte boundary.
-
#alignment(bytes) ⇒ Integer
The alignment of the region to the specified byte boundary.
-
#as_intptr ⇒ Value::IntPtr
Returns a pointer to the region as a signed integer pointer of the same width as the region.
-
#as_uintptr ⇒ Value::IntPtr
Returns a pointer to the region as an unsigned integer pointer of the same width as the region.
-
#from ⇒ IO|SharedMemory|Region
The file, shared memory space, or region the receiver was created from.
-
#read ⇒ String
Read data from the region.
-
#size ⇒ Integer
The width of the region.
-
#write(str) ⇒ nil
Write data to the region.
Class Method Details
.map(file, off, len) ⇒ Region
Memory-map a region of a file or shared memory space. The region is read/write and shared.
328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'ext/concurrent-shm/posix.c', line 328
static VALUE region_map(VALUE self, VALUE file, VALUE off, VALUE len)
{
UNUSED(self);
int fd = FIX2INT(rb_funcall(file, rb_intern("fileno"), 0));
void * data = mmap(NULL, FIX2INT(len), PROT_READ | PROT_WRITE, MAP_SHARED, fd, FIX2INT(off));
if (data == MAP_FAILED) {
rb_syserr_fail_strf(errno, "mmap(fd=%d, len=%d)", fd, FIX2INT(len));
}
return __new_region(data, FIX2INT(len), 1, file);
}
|
.unmap(region) ⇒ Object
Unmaps a memory-mapped region.
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'ext/concurrent-shm/posix.c', line 344
static VALUE region_unmap(VALUE self, VALUE region)
{
UNUSED(self);
region_t * r = value_as_region(region);
if (!r->mapped) {
rb_raise(rb_eArgError, "Not a memory mapped region");
}
if (!r->data) {
return Qnil;
}
chk_errno(munmap, (r->data, r->len), "");
r->data = NULL;
r->len = 0;
return Qnil;
}
|
Instance Method Details
#[](start) ⇒ Region #[](start...) ⇒ Region #[](start, length) ⇒ Region #[](start..end) ⇒ Region #[](start...end) ⇒ Region
Get a subregion of the receiver.
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'ext/concurrent-shm/posix.c', line 412
static VALUE region_at(int argc, VALUE * argv, VALUE self)
{
VALUE at, len;
rb_scan_args(argc, argv, "11", &at, &len);
if (RB_TYPE_P(at, T_FIXNUM) && RB_TYPE_P(len, T_FIXNUM)) {
return __region_at_len(self, FIX2INT(at), FIX2INT(len));
} else if (RB_TYPE_P(at, T_FIXNUM) && NIL_P(len)) {
return __region_at_len(self, FIX2INT(at), 1);
} else if (rb_obj_is_kind_of(at, rb_cRange) && NIL_P(len)) {
// continue
} else {
rb_raise(rb_eArgError, "Region#[at, len] accepts [int,int], [int], [int...nil], or [int...int]");
}
VALUE begin = rb_funcall(at, rb_intern("begin"), 0);
VALUE end = rb_funcall(at, rb_intern("end"), 0);
VALUE excl = rb_funcall(at, rb_intern("exclude_end?"), 0);
if (!RB_TYPE_P(begin, T_FIXNUM)) {
rb_raise(rb_eArgError, "Region#[at, len] accepts [int,int], [int], [int...nil], or [int...int]");
}
if (NIL_P(end)) {
region_t * r = value_as_region(self);
return __region_at(self, FIX2INT(begin), r->len, Qtrue);
}
if (!RB_TYPE_P(end, T_FIXNUM)) {
rb_raise(rb_eArgError, "Region#[at, len] accepts [int,int], [int], [int...nil], or [int...int]");
}
return __region_at(self, FIX2INT(begin), FIX2INT(end), excl);
}
|
#aligned?(bytes) ⇒ Boolean
Returns true if the region is aligned to the specified byte boundary. Equivalent to ‘addr % bytes == 0`.
500 501 502 503 504 |
# File 'ext/concurrent-shm/posix.c', line 500
static VALUE region_aligned_q(VALUE self, VALUE bytes)
{
region_t * r = value_as_region(self);
return ralign(r, FIX2INT(bytes)) == 0 ? Qtrue : Qfalse;
}
|
#alignment(bytes) ⇒ Integer
The alignment of the region to the specified byte boundary. Equivalent to ‘addr % bytes`.
490 491 492 493 494 |
# File 'ext/concurrent-shm/posix.c', line 490
static VALUE region_alignment(VALUE self, VALUE bytes)
{
region_t * r = value_as_region(self);
return INT2FIX(ralign(r, FIX2INT(bytes)));
}
|
#as_intptr ⇒ Value::IntPtr
Returns a pointer to the region as a signed integer pointer of the same width as the region.
455 456 457 458 459 460 461 462 463 464 465 |
# File 'ext/concurrent-shm/posix.c', line 455
static VALUE region_as_intptr(VALUE self)
{
region_t * r = value_as_region(self);
switch (r->len) {
case 1: return Int8Ptr2Value ((int8_t *) r->data);
case 2: return Int16Ptr2Value((int16_t *)r->data);
case 4: return Int32Ptr2Value((int32_t *)r->data);
case 8: return Int64Ptr2Value((int64_t *)r->data);
default: rb_raise(rb_eRangeError, "Region length must be 1, 2, 4, or 8 bytes to use as an integer pointer");
}
}
|
#as_uintptr ⇒ Value::IntPtr
Returns a pointer to the region as an unsigned integer pointer of the same width as the region.
472 473 474 475 476 477 478 479 480 481 482 |
# File 'ext/concurrent-shm/posix.c', line 472
static VALUE region_as_uintptr(VALUE self)
{
region_t * r = value_as_region(self);
switch (r->len) {
case 1: return UInt8Ptr2Value ((uint8_t *) r->data);
case 2: return UInt16Ptr2Value((uint16_t *)r->data);
case 4: return UInt32Ptr2Value((uint32_t *)r->data);
case 8: return UInt64Ptr2Value((uint64_t *)r->data);
default: rb_raise(rb_eRangeError, "Region length must be 1, 2, 4, or 8 bytes to use as an integer pointer");
}
}
|
#from ⇒ IO|SharedMemory|Region
The file, shared memory space, or region the receiver was created from.
509 510 511 512 513 |
# File 'ext/concurrent-shm/posix.c', line 509
static VALUE region_from(VALUE self)
{
region_t * r = value_as_region(self);
return r->from;
}
|
#read ⇒ String
Read data from the region.
527 528 529 530 531 |
# File 'ext/concurrent-shm/posix.c', line 527
static VALUE region_read(VALUE self)
{
region_t * r = value_as_region(self);
return rb_str_new((const char *)r->data, r->len);
}
|
#size ⇒ Integer
The width of the region.
518 519 520 521 522 |
# File 'ext/concurrent-shm/posix.c', line 518
static VALUE region_size(VALUE self)
{
region_t * r = value_as_region(self);
return INT2FIX(r->len);
}
|
#write(str) ⇒ nil
Write data to the region.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'ext/concurrent-shm/posix.c', line 537
static VALUE region_write(VALUE self, VALUE str)
{
if (!RB_TYPE_P(str, T_STRING)) {
str = rb_funcall(str, rb_intern("to_s"), 0);
if (!RB_TYPE_P(str, T_STRING)) {
rb_raise(rb_eArgError, "str.to_s is not a string");
}
}
region_t * r = value_as_region(self);
size_t len = RSTRING_LEN(str);
if (len > r->len) {
rb_raise(rb_eRangeError, "string is longer than region");
}
memcpy(r->data, StringValuePtr(str), len);
return Qnil;
}
|