concurrent-ruby 0.7.0.rc1-x64-mingw32 → 0.7.0.rc2-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/README.md +3 -2
- data/ext/concurrent_ruby_ext/atomic_boolean.c +48 -0
- data/ext/concurrent_ruby_ext/atomic_boolean.h +16 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.c +50 -0
- data/ext/concurrent_ruby_ext/atomic_fixnum.h +13 -0
- data/ext/concurrent_ruby_ext/atomic_reference.c +44 -44
- data/ext/concurrent_ruby_ext/atomic_reference.h +8 -0
- data/ext/concurrent_ruby_ext/rb_concurrent.c +32 -3
- data/ext/concurrent_ruby_ext/ruby_193_compatible.h +28 -0
- data/lib/2.0/concurrent_ruby_ext.so +0 -0
- data/lib/concurrent.rb +2 -1
- data/lib/concurrent/actor.rb +104 -0
- data/lib/concurrent/{actress → actor}/ad_hoc.rb +2 -3
- data/lib/concurrent/actor/behaviour.rb +70 -0
- data/lib/concurrent/actor/behaviour/abstract.rb +48 -0
- data/lib/concurrent/actor/behaviour/awaits.rb +21 -0
- data/lib/concurrent/actor/behaviour/buffer.rb +54 -0
- data/lib/concurrent/actor/behaviour/errors_on_unknown_message.rb +12 -0
- data/lib/concurrent/actor/behaviour/executes_context.rb +18 -0
- data/lib/concurrent/actor/behaviour/linking.rb +42 -0
- data/lib/concurrent/actor/behaviour/pausing.rb +77 -0
- data/lib/concurrent/actor/behaviour/removes_child.rb +16 -0
- data/lib/concurrent/actor/behaviour/sets_results.rb +36 -0
- data/lib/concurrent/actor/behaviour/supervised.rb +58 -0
- data/lib/concurrent/actor/behaviour/supervising.rb +34 -0
- data/lib/concurrent/actor/behaviour/terminates_children.rb +13 -0
- data/lib/concurrent/actor/behaviour/termination.rb +54 -0
- data/lib/concurrent/actor/context.rb +153 -0
- data/lib/concurrent/actor/core.rb +213 -0
- data/lib/concurrent/actor/default_dead_letter_handler.rb +9 -0
- data/lib/concurrent/{actress → actor}/envelope.rb +1 -1
- data/lib/concurrent/actor/errors.rb +27 -0
- data/lib/concurrent/actor/internal_delegations.rb +49 -0
- data/lib/concurrent/{actress/core_delegations.rb → actor/public_delegations.rb} +11 -13
- data/lib/concurrent/{actress → actor}/reference.rb +25 -8
- data/lib/concurrent/actor/root.rb +37 -0
- data/lib/concurrent/{actress → actor}/type_check.rb +1 -1
- data/lib/concurrent/actor/utills.rb +7 -0
- data/lib/concurrent/actor/utils/broadcast.rb +36 -0
- data/lib/concurrent/actress.rb +2 -224
- data/lib/concurrent/agent.rb +10 -12
- data/lib/concurrent/atomic.rb +32 -1
- data/lib/concurrent/atomic/atomic_boolean.rb +55 -13
- data/lib/concurrent/atomic/atomic_fixnum.rb +54 -16
- data/lib/concurrent/atomic/synchronization.rb +51 -0
- data/lib/concurrent/atomic/thread_local_var.rb +15 -50
- data/lib/concurrent/atomic_reference/mutex_atomic.rb +1 -1
- data/lib/concurrent/atomic_reference/ruby.rb +15 -0
- data/lib/concurrent/atomics.rb +1 -0
- data/lib/concurrent/channel/unbuffered_channel.rb +2 -1
- data/lib/concurrent/configuration.rb +6 -3
- data/lib/concurrent/dataflow.rb +20 -3
- data/lib/concurrent/delay.rb +23 -31
- data/lib/concurrent/executor/executor.rb +7 -2
- data/lib/concurrent/executor/timer_set.rb +1 -1
- data/lib/concurrent/future.rb +2 -1
- data/lib/concurrent/lazy_register.rb +58 -0
- data/lib/concurrent/options_parser.rb +4 -2
- data/lib/concurrent/promise.rb +2 -1
- data/lib/concurrent/scheduled_task.rb +6 -5
- data/lib/concurrent/tvar.rb +6 -10
- data/lib/concurrent/utility/processor_count.rb +4 -2
- data/lib/concurrent/version.rb +1 -1
- data/lib/concurrent_ruby_ext.so +0 -0
- metadata +37 -10
- data/lib/concurrent/actress/context.rb +0 -98
- data/lib/concurrent/actress/core.rb +0 -228
- data/lib/concurrent/actress/errors.rb +0 -14
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZWMzOTY0NWI3OTIzNTkwNTFmMjU5MzcxZmMzMjI0YTViZDA5OGI4NQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZGY1YzlhYzJhMmE4NzAyZmJkNDdmNDU1OTE4ODJjM2I5NDdmMGQwYg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MmNhNmQwODRkMWNmNmY2MmNjNWE2YzA1NDcxYzFlYjIzNjQ0YTY1NjRjODhi
|
10
|
+
MjE0NTRhYmI4YWRhYjQwMjFlNDc5YWJlMjk4YmRlYjk5YjU5NDkwN2RjYzBj
|
11
|
+
N2JiYjRhYjdhODA5MjEwZTUzMzQyN2FiZjExNjFlYmE1MTRjYzU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTQ4ODQ0YzE3Mjg1OTU1ZjY2MjcxNzlmYTMxOTNmNmEyNjY2NmFjMzliZTk2
|
14
|
+
OGZiMzY3MDkzNzRmYjk4Njc4YmNiN2MzNTNjOGI2NjBhZmE3YTU2MzMxNDlm
|
15
|
+
MDcyNjM0YTdmMzZmNmMyODE4NDFkOTgyN2M2MTNlYTU2MmJmNDQ=
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Concurrent Ruby
|
2
|
-
[](http://badge.fury.io/rb/concurrent-ruby) [](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [](https://coveralls.io/r/ruby-concurrency/concurrent-ruby) [](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [](https://gemnasium.com/ruby-concurrency/concurrent-ruby) [](https://gitter.im/ruby-concurrency)
|
2
|
+
[](http://badge.fury.io/rb/concurrent-ruby) [](https://travis-ci.org/ruby-concurrency/concurrent-ruby) [](https://coveralls.io/r/ruby-concurrency/concurrent-ruby) [](https://codeclimate.com/github/ruby-concurrency/concurrent-ruby) [](http://inch-ci.org/github/ruby-concurrency/concurrent-ruby) [](https://gemnasium.com/ruby-concurrency/concurrent-ruby) [](https://gitter.im/ruby-concurrency/concurrent-ruby)
|
3
3
|
|
4
4
|
<table>
|
5
5
|
<tr>
|
@@ -54,7 +54,7 @@ _NOTE: There is an old gem from 2007 called "concurrent" that does not appear to
|
|
54
54
|
## Features & Documentation
|
55
55
|
|
56
56
|
Please see the [Concurrent Ruby Wiki](https://github.com/ruby-concurrency/concurrent-ruby/wiki)
|
57
|
-
or the [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
|
57
|
+
or the [API documentation](http://ruby-concurrency.github.io/concurrent-ruby/frames.html)
|
58
58
|
for more information or join our [mailing list](http://groups.google.com/group/concurrent-ruby).
|
59
59
|
|
60
60
|
There are many concurrency abstractions in this library. These abstractions can be broadly categorized
|
@@ -146,6 +146,7 @@ task.value #=> 25.96
|
|
146
146
|
* [Chip Miller](https://github.com/chip-miller)
|
147
147
|
* [Giuseppe Capizzi](https://github.com/gcapizzi)
|
148
148
|
* [Jamie Hodge](https://github.com/jamiehodge)
|
149
|
+
* [Justin Lambert](https://github.com/mastfish)
|
149
150
|
* [Larry Lv](https://github.com/larrylv)
|
150
151
|
* [Maxim Chechel](https://github.com/maximchick)
|
151
152
|
* [Ravil Bayramgalin](https://github.com/brainopia)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#include "atomic_boolean.h"
|
4
|
+
#include "atomic_reference.h"
|
5
|
+
#include "ruby_193_compatible.h"
|
6
|
+
|
7
|
+
void atomic_boolean_mark(void *value) {
|
8
|
+
rb_gc_mark_maybe((VALUE) value);
|
9
|
+
}
|
10
|
+
|
11
|
+
VALUE atomic_boolean_allocate(VALUE klass) {
|
12
|
+
return rb_data_object_alloc(klass, (void *) Qfalse, atomic_boolean_mark, NULL);
|
13
|
+
}
|
14
|
+
|
15
|
+
VALUE method_atomic_boolean_initialize(int argc, VALUE* argv, VALUE self) {
|
16
|
+
VALUE value = Qfalse;
|
17
|
+
rb_check_arity(argc, 0, 1);
|
18
|
+
if (argc == 1) value = TRUTHY(argv[0]);
|
19
|
+
DATA_PTR(self) = (void *) value;
|
20
|
+
return(self);
|
21
|
+
}
|
22
|
+
|
23
|
+
VALUE method_atomic_boolean_value(VALUE self) {
|
24
|
+
return (VALUE) DATA_PTR(self);
|
25
|
+
}
|
26
|
+
|
27
|
+
VALUE method_atomic_boolean_value_set(VALUE self, VALUE value) {
|
28
|
+
VALUE new_value = TRUTHY(value);
|
29
|
+
DATA_PTR(self) = (void *) new_value;
|
30
|
+
return(new_value);
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE method_atomic_boolean_true_question(VALUE self) {
|
34
|
+
return(method_atomic_boolean_value(self));
|
35
|
+
}
|
36
|
+
|
37
|
+
VALUE method_atomic_boolean_false_question(VALUE self) {
|
38
|
+
VALUE current = method_atomic_boolean_value(self);
|
39
|
+
return(current == Qfalse ? Qtrue : Qfalse);
|
40
|
+
}
|
41
|
+
|
42
|
+
VALUE method_atomic_boolean_make_true(VALUE self) {
|
43
|
+
return(ir_compare_and_set(self, Qfalse, Qtrue));
|
44
|
+
}
|
45
|
+
|
46
|
+
VALUE method_atomic_boolean_make_false(VALUE self) {
|
47
|
+
return(ir_compare_and_set(self, Qtrue, Qfalse));
|
48
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#ifndef __ATOMIC_BOOLEAN_H__
|
2
|
+
#define __ATOMIC_BOOLEAN_H__
|
3
|
+
|
4
|
+
#define TRUTHY(value)(value == Qfalse || value == Qnil ? Qfalse : Qtrue)
|
5
|
+
|
6
|
+
void atomic_boolean_mark(void*);
|
7
|
+
VALUE atomic_boolean_allocate(VALUE);
|
8
|
+
VALUE method_atomic_boolean_initialize(int, VALUE*, VALUE);
|
9
|
+
VALUE method_atomic_boolean_value(VALUE);
|
10
|
+
VALUE method_atomic_boolean_value_set(VALUE, VALUE);
|
11
|
+
VALUE method_atomic_boolean_true_question(VALUE);
|
12
|
+
VALUE method_atomic_boolean_false_question(VALUE);
|
13
|
+
VALUE method_atomic_boolean_make_true(VALUE);
|
14
|
+
VALUE method_atomic_boolean_make_false(VALUE);
|
15
|
+
|
16
|
+
#endif
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#include "atomic_fixnum.h"
|
4
|
+
#include "atomic_reference.h"
|
5
|
+
#include "ruby_193_compatible.h"
|
6
|
+
|
7
|
+
void atomic_fixnum_mark(void *value) {
|
8
|
+
rb_gc_mark_maybe((VALUE) value);
|
9
|
+
}
|
10
|
+
|
11
|
+
VALUE atomic_fixnum_allocate(VALUE klass) {
|
12
|
+
return rb_data_object_alloc(klass, (void *) Qnil, atomic_fixnum_mark, NULL);
|
13
|
+
}
|
14
|
+
|
15
|
+
VALUE method_atomic_fixnum_initialize(int argc, VALUE* argv, VALUE self) {
|
16
|
+
VALUE value = LL2NUM(0);
|
17
|
+
rb_check_arity(argc, 0, 1);
|
18
|
+
if (argc == 1) {
|
19
|
+
Check_Type(argv[0], T_FIXNUM);
|
20
|
+
value = argv[0];
|
21
|
+
}
|
22
|
+
DATA_PTR(self) = (void *) value;
|
23
|
+
return(self);
|
24
|
+
}
|
25
|
+
|
26
|
+
VALUE method_atomic_fixnum_value(VALUE self) {
|
27
|
+
return (VALUE) DATA_PTR(self);
|
28
|
+
}
|
29
|
+
|
30
|
+
VALUE method_atomic_fixnum_value_set(VALUE self, VALUE value) {
|
31
|
+
Check_Type(value, T_FIXNUM);
|
32
|
+
DATA_PTR(self) = (void *) value;
|
33
|
+
return(value);
|
34
|
+
}
|
35
|
+
|
36
|
+
VALUE method_atomic_fixnum_increment(VALUE self) {
|
37
|
+
long long value = NUM2LL((VALUE) DATA_PTR(self));
|
38
|
+
return method_atomic_fixnum_value_set(self, LL2NUM(value + 1));
|
39
|
+
}
|
40
|
+
|
41
|
+
VALUE method_atomic_fixnum_decrement(VALUE self) {
|
42
|
+
long long value = NUM2LL((VALUE) DATA_PTR(self));
|
43
|
+
return method_atomic_fixnum_value_set(self, LL2NUM(value - 1));
|
44
|
+
}
|
45
|
+
|
46
|
+
VALUE method_atomic_fixnum_compare_and_set(VALUE self, VALUE rb_expect, VALUE rb_update) {
|
47
|
+
Check_Type(rb_expect, T_FIXNUM);
|
48
|
+
Check_Type(rb_update, T_FIXNUM);
|
49
|
+
return ir_compare_and_set(self, rb_expect, rb_update);
|
50
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef __ATOMIC_FIXNUM_H__
|
2
|
+
#define __ATOMIC_FIXNUM_H__
|
3
|
+
|
4
|
+
void atomic_fixnum_mark(void*);
|
5
|
+
VALUE atomic_fixnum_allocate(VALUE);
|
6
|
+
VALUE method_atomic_fixnum_initialize(int, VALUE*, VALUE);
|
7
|
+
VALUE method_atomic_fixnum_value(VALUE);
|
8
|
+
VALUE method_atomic_fixnum_value_set(VALUE, VALUE);
|
9
|
+
VALUE method_atomic_fixnum_increment(VALUE);
|
10
|
+
VALUE method_atomic_fixnum_decrement(VALUE);
|
11
|
+
VALUE method_atomic_fixnum_compare_and_set(VALUE, VALUE, VALUE);
|
12
|
+
|
13
|
+
#endif
|
@@ -1,78 +1,78 @@
|
|
1
1
|
#include <ruby.h>
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
/*#if defined(__sun)*/
|
3
|
+
/*#include <atomic.h>*/
|
4
|
+
/*#endif*/
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
/*#ifdef HAVE_LIBKERN_OSATOMIC_H*/
|
7
|
+
/*#include <libkern/OSAtomic.h>*/
|
8
|
+
/*#endif*/
|
9
9
|
|
10
10
|
#include "atomic_reference.h"
|
11
11
|
|
12
12
|
void ir_mark(void *value) {
|
13
|
-
|
13
|
+
rb_gc_mark_maybe((VALUE) value);
|
14
14
|
}
|
15
15
|
|
16
16
|
VALUE ir_alloc(VALUE klass) {
|
17
|
-
|
17
|
+
return rb_data_object_alloc(klass, (void *) Qnil, ir_mark, NULL);
|
18
18
|
}
|
19
19
|
|
20
20
|
VALUE ir_initialize(int argc, VALUE* argv, VALUE self) {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
VALUE value = Qnil;
|
22
|
+
if (rb_scan_args(argc, argv, "01", &value) == 1) {
|
23
|
+
value = argv[0];
|
24
|
+
}
|
25
|
+
DATA_PTR(self) = (void *) value;
|
26
|
+
return Qnil;
|
27
27
|
}
|
28
28
|
|
29
29
|
VALUE ir_get(VALUE self) {
|
30
|
-
|
30
|
+
return (VALUE) DATA_PTR(self);
|
31
31
|
}
|
32
32
|
|
33
33
|
VALUE ir_set(VALUE self, VALUE new_value) {
|
34
|
-
|
35
|
-
|
34
|
+
DATA_PTR(self) = (void *) new_value;
|
35
|
+
return new_value;
|
36
36
|
}
|
37
37
|
|
38
38
|
VALUE ir_get_and_set(VALUE self, VALUE new_value) {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
VALUE old_value;
|
40
|
+
old_value = (VALUE) DATA_PTR(self);
|
41
|
+
DATA_PTR(self) = (void *) new_value;
|
42
|
+
return old_value;
|
43
43
|
}
|
44
44
|
|
45
45
|
VALUE ir_compare_and_set(volatile VALUE self, VALUE expect_value, VALUE new_value) {
|
46
46
|
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
if (OSAtomicCompareAndSwap64(expect_value, new_value, &DATA_PTR(self))) {
|
48
|
+
return Qtrue;
|
49
|
+
}
|
50
50
|
#elif defined(__sun)
|
51
|
-
/* Assuming VALUE is uintptr_t */
|
52
|
-
/* Based on the definition of uintptr_t from /usr/include/sys/int_types.h */
|
51
|
+
/* Assuming VALUE is uintptr_t */
|
52
|
+
/* Based on the definition of uintptr_t from /usr/include/sys/int_types.h */
|
53
53
|
#if defined(_LP64) || defined(_I32LPx)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
/* 64-bit: uintptr_t === unsigned long */
|
55
|
+
if (atomic_cas_ulong((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
|
56
|
+
return Qtrue;
|
57
|
+
}
|
58
58
|
#else
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
/* 32-bit: uintptr_t === unsigned int */
|
60
|
+
if (atomic_cas_uint((uintptr_t *) &DATA_PTR(self), expect_value, new_value)) {
|
61
|
+
return Qtrue;
|
62
|
+
}
|
63
63
|
#endif
|
64
64
|
#elif defined _MSC_VER && defined _M_AMD64
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
if (InterlockedCompareExchange64((LONGLONG*)&DATA_PTR(self), new_value, expect_value)) {
|
66
|
+
return Qtrue;
|
67
|
+
}
|
68
68
|
#elif defined _MSC_VER && defined _M_IX86
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
if (InterlockedCompareExchange((LONG*)&DATA_PTR(self), new_value, expect_value)) {
|
70
|
+
return Qtrue;
|
71
|
+
}
|
72
72
|
#else
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
if (__sync_bool_compare_and_swap(&DATA_PTR(self), expect_value, new_value)) {
|
74
|
+
return Qtrue;
|
75
|
+
}
|
76
76
|
#endif
|
77
|
-
|
77
|
+
return Qfalse;
|
78
78
|
}
|
@@ -1,6 +1,14 @@
|
|
1
1
|
#ifndef __ATOMIC_REFERENCE_H__
|
2
2
|
#define __ATOMIC_REFERENCE_H__
|
3
3
|
|
4
|
+
#if defined(__sun)
|
5
|
+
#include <atomic.h>
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#ifdef HAVE_LIBKERN_OSATOMIC_H
|
9
|
+
#include <libkern/OSAtomic.h>
|
10
|
+
#endif
|
11
|
+
|
4
12
|
void ir_mark(void*);
|
5
13
|
VALUE ir_alloc(VALUE);
|
6
14
|
VALUE ir_initialize(int, VALUE*, VALUE);
|
@@ -1,11 +1,15 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
|
3
3
|
#include "atomic_reference.h"
|
4
|
+
#include "atomic_boolean.h"
|
5
|
+
#include "atomic_fixnum.h"
|
4
6
|
|
5
7
|
// module and class definitions
|
6
8
|
|
7
9
|
static VALUE rb_mConcurrent;
|
8
10
|
static VALUE rb_cAtomic;
|
11
|
+
static VALUE rb_cAtomicBoolean;
|
12
|
+
static VALUE rb_cAtomicFixnum;
|
9
13
|
|
10
14
|
// Init_concurrent_ruby_ext
|
11
15
|
|
@@ -14,15 +18,40 @@ void Init_concurrent_ruby_ext() {
|
|
14
18
|
// define modules and classes
|
15
19
|
rb_mConcurrent = rb_define_module("Concurrent");
|
16
20
|
rb_cAtomic = rb_define_class_under(rb_mConcurrent, "CAtomic", rb_cObject);
|
21
|
+
rb_cAtomicBoolean = rb_define_class_under(rb_mConcurrent, "CAtomicBoolean", rb_cObject);
|
22
|
+
rb_cAtomicFixnum = rb_define_class_under(rb_mConcurrent, "CAtomicFixnum", rb_cObject);
|
17
23
|
|
18
24
|
// CAtomic
|
19
25
|
rb_define_alloc_func(rb_cAtomic, ir_alloc);
|
20
26
|
rb_define_method(rb_cAtomic, "initialize", ir_initialize, -1);
|
21
27
|
rb_define_method(rb_cAtomic, "get", ir_get, 0);
|
22
|
-
rb_define_method(rb_cAtomic, "value", ir_get, 0);
|
23
28
|
rb_define_method(rb_cAtomic, "set", ir_set, 1);
|
24
|
-
rb_define_method(rb_cAtomic, "value=", ir_set, 1);
|
25
29
|
rb_define_method(rb_cAtomic, "get_and_set", ir_get_and_set, 1);
|
26
|
-
rb_define_method(rb_cAtomic, "swap", ir_get_and_set, 1);
|
27
30
|
rb_define_method(rb_cAtomic, "_compare_and_set", ir_compare_and_set, 2);
|
31
|
+
rb_define_alias(rb_cAtomic, "value", "get");
|
32
|
+
rb_define_alias(rb_cAtomic, "value=", "set");
|
33
|
+
rb_define_alias(rb_cAtomic, "swap", "get_and_set");
|
34
|
+
|
35
|
+
// CAtomicBoolean
|
36
|
+
rb_define_alloc_func(rb_cAtomicBoolean, atomic_boolean_allocate);
|
37
|
+
rb_define_method(rb_cAtomicBoolean, "initialize", method_atomic_boolean_initialize, -1);
|
38
|
+
rb_define_method(rb_cAtomicBoolean, "value", method_atomic_boolean_value, 0);
|
39
|
+
rb_define_method(rb_cAtomicBoolean, "value=", method_atomic_boolean_value_set, 1);
|
40
|
+
rb_define_method(rb_cAtomicBoolean, "true?", method_atomic_boolean_true_question, 0);
|
41
|
+
rb_define_method(rb_cAtomicBoolean, "false?", method_atomic_boolean_false_question, 0);
|
42
|
+
rb_define_method(rb_cAtomicBoolean, "make_true", method_atomic_boolean_make_true, 0);
|
43
|
+
rb_define_method(rb_cAtomicBoolean, "make_false", method_atomic_boolean_make_false, 0);
|
44
|
+
|
45
|
+
// CAtomicFixnum
|
46
|
+
rb_define_const(rb_cAtomicFixnum, "MIN_VALUE", LL2NUM(LLONG_MIN));
|
47
|
+
rb_define_const(rb_cAtomicFixnum, "MAX_VALUE", LL2NUM(LLONG_MAX));
|
48
|
+
rb_define_alloc_func(rb_cAtomicFixnum, atomic_fixnum_allocate);
|
49
|
+
rb_define_method(rb_cAtomicFixnum, "initialize", method_atomic_fixnum_initialize, -1);
|
50
|
+
rb_define_method(rb_cAtomicFixnum, "value", method_atomic_fixnum_value, 0);
|
51
|
+
rb_define_method(rb_cAtomicFixnum, "value=", method_atomic_fixnum_value_set, 1);
|
52
|
+
rb_define_method(rb_cAtomicFixnum, "increment", method_atomic_fixnum_increment, 0);
|
53
|
+
rb_define_method(rb_cAtomicFixnum, "decrement", method_atomic_fixnum_decrement, 0);
|
54
|
+
rb_define_method(rb_cAtomicFixnum, "compare_and_set", method_atomic_fixnum_compare_and_set, 2);
|
55
|
+
rb_define_alias(rb_cAtomicFixnum, "up", "increment");
|
56
|
+
rb_define_alias(rb_cAtomicFixnum, "down", "decrement");
|
28
57
|
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#ifndef rb_check_arity
|
2
|
+
|
3
|
+
// https://github.com/ruby/ruby/blob/ruby_2_0_0/include/ruby/intern.h
|
4
|
+
// rb_check_arity was added in Ruby 2.0
|
5
|
+
|
6
|
+
#define UNLIMITED_ARGUMENTS (-1)
|
7
|
+
|
8
|
+
static inline void rb_error_arity(int argc, int min, int max)
|
9
|
+
{
|
10
|
+
VALUE err_mess = 0;
|
11
|
+
if (min == max) {
|
12
|
+
err_mess = rb_sprintf("wrong number of arguments (%d for %d)", argc, min);
|
13
|
+
}
|
14
|
+
else if (max == UNLIMITED_ARGUMENTS) {
|
15
|
+
err_mess = rb_sprintf("wrong number of arguments (%d for %d+)", argc, min);
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
err_mess = rb_sprintf("wrong number of arguments (%d for %d..%d)", argc, min, max);
|
19
|
+
}
|
20
|
+
rb_raise(rb_eTypeError, err_mess);
|
21
|
+
}
|
22
|
+
|
23
|
+
#define rb_check_arity(argc, min, max) do { \
|
24
|
+
if (((argc) < (min)) || ((argc) > (max) && (max) != UNLIMITED_ARGUMENTS)) \
|
25
|
+
rb_error_arity(argc, min, max); \
|
26
|
+
} while(0)
|
27
|
+
|
28
|
+
#endif
|
Binary file
|
data/lib/concurrent.rb
CHANGED
@@ -8,8 +8,9 @@ require 'concurrent/collections'
|
|
8
8
|
require 'concurrent/executors'
|
9
9
|
require 'concurrent/utilities'
|
10
10
|
|
11
|
-
require 'concurrent/
|
11
|
+
require 'concurrent/actor'
|
12
12
|
require 'concurrent/atomic'
|
13
|
+
require 'concurrent/lazy_register'
|
13
14
|
require 'concurrent/agent'
|
14
15
|
require 'concurrent/async'
|
15
16
|
require 'concurrent/dataflow'
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'concurrent/configuration'
|
2
|
+
require 'concurrent/executor/serialized_execution'
|
3
|
+
require 'concurrent/ivar'
|
4
|
+
require 'concurrent/logging'
|
5
|
+
require 'concurrent/atomic/synchronization'
|
6
|
+
|
7
|
+
module Concurrent
|
8
|
+
# TODO https://github.com/celluloid/celluloid/wiki/Supervision-Groups
|
9
|
+
|
10
|
+
# TODO doc
|
11
|
+
# - what happens if I try to supervise using a normal Context?
|
12
|
+
|
13
|
+
|
14
|
+
# {include:file:doc/actor/main.md}
|
15
|
+
module Actor
|
16
|
+
|
17
|
+
require 'concurrent/actor/type_check'
|
18
|
+
require 'concurrent/actor/errors'
|
19
|
+
require 'concurrent/actor/public_delegations'
|
20
|
+
require 'concurrent/actor/internal_delegations'
|
21
|
+
require 'concurrent/actor/envelope'
|
22
|
+
require 'concurrent/actor/reference'
|
23
|
+
require 'concurrent/actor/core'
|
24
|
+
require 'concurrent/actor/behaviour'
|
25
|
+
require 'concurrent/actor/context'
|
26
|
+
|
27
|
+
require 'concurrent/actor/default_dead_letter_handler'
|
28
|
+
require 'concurrent/actor/root'
|
29
|
+
require 'concurrent/actor/ad_hoc'
|
30
|
+
|
31
|
+
# @return [Reference, nil] current executing actor if any
|
32
|
+
def self.current
|
33
|
+
Thread.current[:__current_actor__]
|
34
|
+
end
|
35
|
+
|
36
|
+
@root = Delay.new do
|
37
|
+
Core.new(parent: nil, name: '/', class: Root, initialized: ivar = IVar.new).reference.tap do
|
38
|
+
ivar.no_error!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# A root actor, a default parent of all actors spawned outside an actor
|
43
|
+
def self.root
|
44
|
+
@root.value!
|
45
|
+
end
|
46
|
+
|
47
|
+
# Spawns a new actor.
|
48
|
+
#
|
49
|
+
# @example simple
|
50
|
+
# Actor.spawn(AdHoc, :ping1) { -> message { message } }
|
51
|
+
#
|
52
|
+
# @example complex
|
53
|
+
# Actor.spawn name: :ping3,
|
54
|
+
# class: AdHoc,
|
55
|
+
# args: [1]
|
56
|
+
# executor: Concurrent.configuration.global_task_pool do |add|
|
57
|
+
# lambda { |number| number + add }
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @param block for context_class instantiation
|
61
|
+
# @param args see {.spawn_optionify}
|
62
|
+
# @return [Reference] never the actual actor
|
63
|
+
def self.spawn(*args, &block)
|
64
|
+
experimental_acknowledged? or
|
65
|
+
warn '[EXPERIMENTAL] A full release of `Actor`, is expected in the 0.7.0 release.'
|
66
|
+
|
67
|
+
if Actor.current
|
68
|
+
Core.new(spawn_optionify(*args).merge(parent: Actor.current), &block).reference
|
69
|
+
else
|
70
|
+
root.ask([:spawn, spawn_optionify(*args), block]).value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# as {.spawn} but it'll raise when Actor not initialized properly
|
75
|
+
def self.spawn!(*args, &block)
|
76
|
+
spawn(spawn_optionify(*args).merge(initialized: ivar = IVar.new), &block).tap { ivar.no_error! }
|
77
|
+
end
|
78
|
+
|
79
|
+
# @overload spawn_optionify(context_class, name, *args)
|
80
|
+
# @param [Context] context_class to be spawned
|
81
|
+
# @param [String, Symbol] name of the instance, it's used to generate the {Core#path} of the actor
|
82
|
+
# @param args for context_class instantiation
|
83
|
+
# @overload spawn_optionify(opts)
|
84
|
+
# see {Core#initialize} opts
|
85
|
+
def self.spawn_optionify(*args)
|
86
|
+
if args.size == 1 && args.first.is_a?(Hash)
|
87
|
+
args.first
|
88
|
+
else
|
89
|
+
{ class: args[0],
|
90
|
+
name: args[1],
|
91
|
+
args: args[2..-1] }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# call this to disable experimental warning
|
96
|
+
def self.i_know_it_is_experimental!
|
97
|
+
@experimental_acknowledged = true
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.experimental_acknowledged?
|
101
|
+
!!@experimental_acknowledged
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|