-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Entire SysV::Integer code and associated shared libraries
- Loading branch information
Showing
10 changed files
with
761 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include <sys/types.h> | ||
#include <sys/ipc.h> | ||
#include <sys/sem.h> | ||
#include <sys/time.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
#include <ruby.h> | ||
#include <ruby/util.h> | ||
#include <ruby/io.h> | ||
|
||
#include <openssl/sha.h> | ||
|
||
#include <stdio.h> | ||
|
||
#include <sys/shm.h> | ||
#include <unistd.h> | ||
|
||
#include <math.h> | ||
|
||
union semun { | ||
int val; /* Value for SETVAL */ | ||
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ | ||
unsigned short *array; /* Array for GETALL, SETALL */ | ||
struct seminfo *__buf; /* Buffer for IPC_INFO | ||
(Linux-specific) */ | ||
}; | ||
|
||
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && defined(HAVE_RUBY_THREAD_H) | ||
// 2.0 | ||
#include <ruby/thread.h> | ||
#define WITHOUT_GVL(fn,a,ubf,b) rb_thread_call_without_gvl((fn),(a),(ubf),(b)) | ||
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION) | ||
// 1.9 | ||
typedef VALUE (*my_blocking_fn_t)(void*); | ||
#define WITHOUT_GVL(fn,a,ubf,b) rb_thread_blocking_region((my_blocking_fn_t)(fn),(a),(ubf),(b)) | ||
#endif | ||
|
||
VALUE eSyscall, eTimeout, eInternal; | ||
|
||
key_t | ||
generate_key(const char *name); | ||
|
||
void | ||
raise_semian_syscall_error(const char *syscall, int error_num); | ||
|
||
|
||
void | ||
set_semaphore_permissions(int sem_id, int permissions); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "semian_shared_memory_object.h" | ||
|
||
typedef struct { | ||
int value; | ||
} semian_int; | ||
|
||
static void semian_integer_initialize_memory (size_t byte_size, void *dest, void *prev_data, size_t prev_data_byte_size); | ||
static VALUE semian_integer_bind_initialize_memory_callback(VALUE self); | ||
static VALUE semian_integer_get_value(VALUE self); | ||
static VALUE semian_integer_set_value(VALUE self, VALUE num); | ||
static VALUE semian_integer_increment(int argc, VALUE *argv, VALUE self); | ||
|
||
static void | ||
semian_integer_initialize_memory (size_t byte_size, void *dest, void *prev_data, size_t prev_data_byte_size) | ||
{ | ||
semian_int *ptr = dest; | ||
semian_int *old = prev_data; | ||
if (prev_data){ | ||
ptr->value = old->value; | ||
} else { | ||
ptr->value=0; | ||
} | ||
} | ||
|
||
static VALUE | ||
semian_integer_bind_initialize_memory_callback(VALUE self) | ||
{ | ||
semian_shm_object *ptr; | ||
TypedData_Get_Struct(self, semian_shm_object, &semian_shm_object_type, ptr); | ||
ptr->initialize_memory = &semian_integer_initialize_memory; | ||
return self; | ||
} | ||
|
||
static VALUE | ||
semian_integer_get_value(VALUE self) | ||
{ | ||
semian_shm_object *ptr; | ||
TypedData_Get_Struct(self, semian_shm_object, &semian_shm_object_type, ptr); | ||
|
||
// check shared memory for NULL | ||
if (0 == ptr->shm_address) | ||
return Qnil; | ||
|
||
int value = ((semian_int *)(ptr->shm_address))->value; | ||
return INT2NUM(value); | ||
} | ||
|
||
static VALUE | ||
semian_integer_set_value(VALUE self, VALUE num) | ||
{ | ||
semian_shm_object *ptr; | ||
TypedData_Get_Struct(self, semian_shm_object, &semian_shm_object_type, ptr); | ||
|
||
if (0 == ptr->shm_address) | ||
return Qnil; | ||
|
||
if (TYPE(num) != T_FIXNUM && TYPE(num) != T_FLOAT) | ||
return Qnil; | ||
|
||
((semian_int *)(ptr->shm_address))->value = NUM2INT(num); | ||
|
||
return num; | ||
} | ||
|
||
static VALUE | ||
semian_integer_reset(VALUE self) | ||
{ | ||
return semian_integer_set_value(self, INT2NUM(0)); | ||
} | ||
|
||
static VALUE | ||
semian_integer_increment(int argc, VALUE *argv, VALUE self) | ||
{ | ||
VALUE num; | ||
rb_scan_args(argc, argv, "01", &num); | ||
if (num == Qnil) | ||
num = INT2NUM(1); | ||
|
||
semian_shm_object *ptr; | ||
TypedData_Get_Struct(self, semian_shm_object, &semian_shm_object_type, ptr); | ||
|
||
if (0 == ptr->shm_address) | ||
return Qnil; | ||
|
||
if (TYPE(num) != T_FIXNUM && TYPE(num) != T_FLOAT) | ||
return Qnil; | ||
|
||
((semian_int *)(ptr->shm_address))->value += NUM2INT(num); | ||
|
||
return self; | ||
} | ||
|
||
void | ||
Init_semian_integer (void) | ||
{ | ||
// Bind methods to Integer | ||
VALUE cSemianModule = rb_const_get(rb_cObject, rb_intern("Semian")); | ||
VALUE cSysVSharedMemory = rb_const_get(cSemianModule, rb_intern("SysVSharedMemory")); | ||
VALUE cSysVModule = rb_const_get(cSemianModule, rb_intern("SysV")); | ||
VALUE cInteger = rb_const_get(cSysVModule, rb_intern("Integer")); | ||
|
||
semian_shm_object_replace_alloc(cSysVSharedMemory, cInteger); | ||
|
||
rb_define_private_method(cInteger, "bind_initialize_memory_callback", semian_integer_bind_initialize_memory_callback, 0); | ||
define_method_with_synchronize(cInteger, "value", semian_integer_get_value, 0); | ||
define_method_with_synchronize(cInteger, "value=", semian_integer_set_value, 1); | ||
define_method_with_synchronize(cInteger, "reset", semian_integer_reset, 0); | ||
define_method_with_synchronize(cInteger, "increment", semian_integer_increment, -1); | ||
} |
Oops, something went wrong.