DeepConnect 0.4.06
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.
- data/lib/deep-connect.rb +83 -0
- data/lib/deep-connect/accepter.rb +64 -0
- data/lib/deep-connect/class-spec-space.rb +652 -0
- data/lib/deep-connect/conf.rb +48 -0
- data/lib/deep-connect/cron.rb +91 -0
- data/lib/deep-connect/deep-fork.rb +70 -0
- data/lib/deep-connect/deep-mq.rb +62 -0
- data/lib/deep-connect/deep-space.rb +403 -0
- data/lib/deep-connect/evaluator.rb +149 -0
- data/lib/deep-connect/event.rb +551 -0
- data/lib/deep-connect/exceptions.rb +38 -0
- data/lib/deep-connect/future.rb +67 -0
- data/lib/deep-connect/organizer.rb +378 -0
- data/lib/deep-connect/port.rb +151 -0
- data/lib/deep-connect/reference.rb +422 -0
- data/lib/deep-connect/serialize.rb +127 -0
- data/lib/deep-connect/session.rb +348 -0
- data/lib/deep-connect/version.rb +8 -0
- metadata +86 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# conf.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
|
8
|
+
module DeepConnect
|
9
|
+
class Config
|
10
|
+
def initialize
|
11
|
+
|
12
|
+
# enable distributed garbage collection.
|
13
|
+
@ENABLE_GC = false
|
14
|
+
|
15
|
+
@KEEP_ALIVE_INTERVAL = 60
|
16
|
+
@MON_INTERVAL = 10
|
17
|
+
|
18
|
+
# debugging attributes.
|
19
|
+
@DISABLE_INFO = false
|
20
|
+
|
21
|
+
@DISPLAY_MESSAGE_TRACE = false
|
22
|
+
@MESSAGE_DISPLAY = false
|
23
|
+
@DEBUG = false
|
24
|
+
@DISPLAY_METHOD_SPEC = false
|
25
|
+
@DISPLAY_MONITOR_MESSAGE = false
|
26
|
+
@DISPLAY_KEEP_ALIVE = false
|
27
|
+
|
28
|
+
@DEBUG_REFERENCE = false
|
29
|
+
@DISPLAY_GC = false
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :ENABLE_GC
|
33
|
+
attr_accessor :KEEP_ALIVE_INTERVAL
|
34
|
+
attr_accessor :MON_INTERVAL
|
35
|
+
|
36
|
+
attr_accessor :DISPLAY_MESSAGE_TRACE
|
37
|
+
attr_accessor :MESSAGE_DISPLAY
|
38
|
+
attr_accessor :DEBUG
|
39
|
+
attr_accessor :DISPLAY_METHOD_SPEC
|
40
|
+
attr_accessor :DISPLAY_MONITOR_MESSAGE
|
41
|
+
attr_accessor :DISPLAY_KEEP_ALIVE
|
42
|
+
|
43
|
+
attr_accessor :DEBUG_REFERENCE
|
44
|
+
attr_accessor :DISPLAY_GC
|
45
|
+
|
46
|
+
attr_accessor :DISABLE_INFO
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# cron.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
|
8
|
+
@RCS_ID='-$Id: $-'
|
9
|
+
|
10
|
+
module DeepConnect
|
11
|
+
|
12
|
+
class Cron
|
13
|
+
|
14
|
+
TAB = [
|
15
|
+
[10, proc{|org, cron, t| cron.mon_10sec}],
|
16
|
+
[60, proc{|org, cron, t| cron.mon_min}],
|
17
|
+
[3060, proc{|org, cron, t| cron.mon_hour}],
|
18
|
+
[Conf.KEEP_ALIVE_INTERVAL, proc{|org, cron, t| org.keep_alive}],
|
19
|
+
]
|
20
|
+
|
21
|
+
def initialize(organizer)
|
22
|
+
@organizer = organizer
|
23
|
+
|
24
|
+
@timer = 0
|
25
|
+
@last_exec_times = {}
|
26
|
+
|
27
|
+
@mon_mutex = Mutex.new
|
28
|
+
|
29
|
+
@prev_message10s = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :timer
|
33
|
+
alias tick timer
|
34
|
+
|
35
|
+
def start
|
36
|
+
Thread.start do
|
37
|
+
loop do
|
38
|
+
sleep Conf.MON_INTERVAL
|
39
|
+
@timer += Conf.MON_INTERVAL
|
40
|
+
|
41
|
+
Thread.start do
|
42
|
+
@mon_mutex.synchronize do
|
43
|
+
for tab in TAB
|
44
|
+
last_time = @last_exec_times[tab]
|
45
|
+
last_time = 0 unless last_time
|
46
|
+
if @timer >= last_time + tab[0]
|
47
|
+
@last_exec_times[tab] = @timer
|
48
|
+
tab[1].call @organizer, self, @timer
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def mon_10sec
|
58
|
+
return if @organizer.deep_spaces.size == 0
|
59
|
+
|
60
|
+
if Conf.DISPLAY_MONITOR_MESSAGE
|
61
|
+
str = ""
|
62
|
+
str.concat "Connect DeepSpaces: BEGIN\n"
|
63
|
+
for peer_id, ds in @organizer.deep_spaces.dup
|
64
|
+
str.concat "#{peer_id.inspect} => \n"
|
65
|
+
str.concat "\t#{ds}\n"
|
66
|
+
end
|
67
|
+
str.concat "Connect DeepSpaces: END\n"
|
68
|
+
|
69
|
+
if @prev_message10s != str
|
70
|
+
@prev_message10s = str
|
71
|
+
puts "MON 10SEC: #{@timer}\n", str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def mon_min
|
77
|
+
if Conf.DISPLAY_MONITOR_MESSAGE
|
78
|
+
puts "MON MIN: #{@timer}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def mon_hour
|
83
|
+
if Conf.DISPLAY_MONITOR_MESSAGE
|
84
|
+
puts "MON HOUR: #{@timer}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# deep-fork.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
|
8
|
+
@RCS_ID='-$Id: $-'
|
9
|
+
|
10
|
+
|
11
|
+
require "thread"
|
12
|
+
|
13
|
+
module DeepConnect
|
14
|
+
|
15
|
+
class DeepFork
|
16
|
+
|
17
|
+
def initialize(dc1, service = 0, except_closing_io = [STDIN, STDOUT, STDERR], &block)
|
18
|
+
@dc1 = dc1
|
19
|
+
|
20
|
+
@peer_pid = nil
|
21
|
+
@peer_deep_space = nil
|
22
|
+
@peer_deep_space_mx = Mutex.new
|
23
|
+
@peer_deep_space_cv = ConditionVariable.new
|
24
|
+
|
25
|
+
exp = "DeepFork_#{format("%0xd", self.object_id)}"
|
26
|
+
@dc1.export(exp, self)
|
27
|
+
|
28
|
+
@peer_pid = Process.fork {
|
29
|
+
ionos = except_closing_io.collect{|io| io.fileno}
|
30
|
+
|
31
|
+
ObjectSpace.each_object(IO) do |io|
|
32
|
+
begin
|
33
|
+
unless ionos.include?(io.fileno)
|
34
|
+
io.close
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
end
|
38
|
+
end
|
39
|
+
dc2 = DeepConnect.start(service)
|
40
|
+
ds2 = dc2.open_deepspace("localhost", @dc1.local_id)
|
41
|
+
df1 = ds2.import(exp)
|
42
|
+
df1.connect(self, $$)
|
43
|
+
block.call(dc2, ds2)
|
44
|
+
}
|
45
|
+
|
46
|
+
@peer_deep_space_mx.synchronize do
|
47
|
+
until @peer_deep_space
|
48
|
+
@peer_deep_space_cv.wait(@peer_deep_space_mx)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :peer_deep_space
|
55
|
+
attr_reader :peer_pid
|
56
|
+
|
57
|
+
def connect(df2, peer_pid)
|
58
|
+
@peer_deep_space_mx.synchronize do
|
59
|
+
if @peer_pid == peer_pid
|
60
|
+
@peer_deep_space = df2.deep_space
|
61
|
+
@peer_deep_space_cv.signal
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class <<self
|
67
|
+
alias fork new
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# deep-mq.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
|
8
|
+
@RCS_ID='-$Id: $-'
|
9
|
+
|
10
|
+
|
11
|
+
require "thread"
|
12
|
+
|
13
|
+
module DeepConnect
|
14
|
+
module DeepMQ
|
15
|
+
class SV
|
16
|
+
def initialize(org)
|
17
|
+
@organizer = org
|
18
|
+
@event_q = Queue.new
|
19
|
+
start
|
20
|
+
end
|
21
|
+
|
22
|
+
def enq(session, ev)
|
23
|
+
begin
|
24
|
+
@event_q.push [session, ev]
|
25
|
+
session.accept ev.reply(nil)
|
26
|
+
rescue SystemExit
|
27
|
+
raise
|
28
|
+
rescue Exception
|
29
|
+
session.accept event.reply(ret, $!)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def start
|
34
|
+
Thread.start do
|
35
|
+
loop do
|
36
|
+
evaluate_request(*@event_q.pop)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def evaluate_request(session, ev)
|
42
|
+
receiver = ev.args.first
|
43
|
+
method = ev.args[1]
|
44
|
+
args = ev.args[2..-1]
|
45
|
+
callback = ev.callback
|
46
|
+
ev0 = Event::Request.request(session, receiver, method, args)
|
47
|
+
@organizer.evaluator.evaluate_mq_request(session, ev0, callback)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class CL
|
52
|
+
def initialize(sv)
|
53
|
+
@sv = sv
|
54
|
+
end
|
55
|
+
|
56
|
+
def push(ref, method, *arg, &callback)
|
57
|
+
@sv.deep_space.session.mq_send_to(@sv, :push, [ref, method, *arg], callback)
|
58
|
+
end
|
59
|
+
# Organizer::def_method_spec(SV, "push(DEFAULT, DEFAULT, VAL)")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,403 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# deep-space.rb -
|
4
|
+
# Copyright (C) 1996-2010 Keiju ISHITSUKA
|
5
|
+
# (Penta Advanced Labrabries, Co.,Ltd)
|
6
|
+
#
|
7
|
+
|
8
|
+
require "thread"
|
9
|
+
require "forwardable"
|
10
|
+
|
11
|
+
require "ipaddr"
|
12
|
+
|
13
|
+
require "deep-connect/session"
|
14
|
+
require "deep-connect/class-spec-space"
|
15
|
+
|
16
|
+
module DeepConnect
|
17
|
+
class DeepSpace
|
18
|
+
extend Forwardable
|
19
|
+
|
20
|
+
def initialize(org, port, local_id = nil)
|
21
|
+
@status = :INITIALIZE
|
22
|
+
|
23
|
+
@organizer = org
|
24
|
+
@session = Session.new(self, port, local_id)
|
25
|
+
|
26
|
+
unless local_id
|
27
|
+
local_id = port.peeraddr[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
addr = port.peeraddr[3]
|
31
|
+
ipaddr = IPAddr.new(addr)
|
32
|
+
# ipaddr = ipaddr.ipv4_mapped if ipaddr.ipv4?
|
33
|
+
ipaddr = ipaddr.native
|
34
|
+
|
35
|
+
@peer_uuid = [ipaddr.to_s, local_id]
|
36
|
+
|
37
|
+
init_class_spec_feature
|
38
|
+
init_export_feature
|
39
|
+
init_import_feature
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :status
|
43
|
+
attr_reader :organizer
|
44
|
+
attr_reader :session
|
45
|
+
attr_reader :peer_uuid
|
46
|
+
alias peer_id peer_uuid
|
47
|
+
|
48
|
+
def close
|
49
|
+
@organizer.close_deepspace(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def connect
|
53
|
+
@session.start
|
54
|
+
|
55
|
+
@deregister_reference_thread = start_deregister_reference
|
56
|
+
|
57
|
+
@status = :SERVICING
|
58
|
+
end
|
59
|
+
|
60
|
+
def disconnect(*opts)
|
61
|
+
org_status = @status
|
62
|
+
@status = :SERVICE_STOP
|
63
|
+
|
64
|
+
@session.stop_service(*opts)
|
65
|
+
if !opts.include?(:SESSION_CLOSED) && !opts.include?(:REQUEST_FROM_PEER)
|
66
|
+
@session.send_disconnect
|
67
|
+
end
|
68
|
+
@session.stop
|
69
|
+
|
70
|
+
@deregister_reference_thread.exit if org_status == :SERVICING
|
71
|
+
@import_reference = nil
|
72
|
+
@export_roots = nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def import(name, waitp = false)
|
76
|
+
@session.get_service(name, waitp)
|
77
|
+
end
|
78
|
+
alias get_service import
|
79
|
+
|
80
|
+
def import_mq(name, waitp = false)
|
81
|
+
sv = @session.import_mq(name, waitp)
|
82
|
+
DeepMQ::CL.new(sv)
|
83
|
+
end
|
84
|
+
alias get_mq import_mq
|
85
|
+
|
86
|
+
#
|
87
|
+
# class spec feature
|
88
|
+
#
|
89
|
+
def init_class_spec_feature
|
90
|
+
# class spec
|
91
|
+
@class_spec_space = ClassSpecSpace.new(:remote)
|
92
|
+
end
|
93
|
+
|
94
|
+
def_delegator :@class_spec_space, :class_specs=
|
95
|
+
def_delegator :@class_spec_space, :method_spec
|
96
|
+
def_delegator :@class_spec_space, :class_spec_id_of
|
97
|
+
alias csid_of class_spec_id_of
|
98
|
+
|
99
|
+
def my_method_spec(obj, method)
|
100
|
+
Organizer::method_spec(obj, method)
|
101
|
+
end
|
102
|
+
|
103
|
+
def my_csid_of(obj)
|
104
|
+
Organizer::class_spec_id_of(obj)
|
105
|
+
end
|
106
|
+
|
107
|
+
def recv_class_spec(cspecs)
|
108
|
+
cspecs.each{|cspec| add_class_spec(cspec)}
|
109
|
+
make_class_spec_cache(cspecs.first)
|
110
|
+
end
|
111
|
+
|
112
|
+
def make_class_spec_cache(cspec)
|
113
|
+
cache = ClassSpec.new
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# export root 関連メソッド
|
118
|
+
#
|
119
|
+
def init_export_feature
|
120
|
+
# exportしているオブジェクト
|
121
|
+
@export_roots_mutex = Mutex.new
|
122
|
+
@export_roots = {}
|
123
|
+
end
|
124
|
+
|
125
|
+
def release_object(obj)
|
126
|
+
@export_roots_mutex.synchronize do
|
127
|
+
@export_roots.delete(obj.object_id)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def set_root(root)
|
132
|
+
#if root.kind_of?(Proc)
|
133
|
+
# puts "SET_ROOT: #{root}\n #{caller(0)}"
|
134
|
+
#end
|
135
|
+
@export_roots_mutex.synchronize do
|
136
|
+
if pair = @export_roots[root.object_id]
|
137
|
+
pair[1] += 1
|
138
|
+
else
|
139
|
+
@export_roots[root.object_id] = [root, 1]
|
140
|
+
end
|
141
|
+
root.object_id
|
142
|
+
end
|
143
|
+
end
|
144
|
+
alias set_export_root set_root
|
145
|
+
|
146
|
+
def root(id)
|
147
|
+
@export_roots_mutex.synchronize do
|
148
|
+
pair = @export_roots.fetch(id){return IllegalObject.new(id)}
|
149
|
+
pair.first
|
150
|
+
#@export_roots.fetch(id){:__DEEPCONNECT_NO_VALUE__}
|
151
|
+
end
|
152
|
+
end
|
153
|
+
alias export_root root
|
154
|
+
|
155
|
+
def register_root_from_other_session(id)
|
156
|
+
obj = @organizer.id2obj(id)
|
157
|
+
@export_roots_mutex.synchronize do
|
158
|
+
if pair = @export_roots[id]
|
159
|
+
pair[1] += 1
|
160
|
+
else
|
161
|
+
@export_roots[id] = [obj, 1]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
obj
|
165
|
+
end
|
166
|
+
|
167
|
+
def delete_roots(pairs)
|
168
|
+
@export_roots_mutex.synchronize do
|
169
|
+
pairs.each_slice(2) do |id, refcount|
|
170
|
+
if pair = @export_roots[id]
|
171
|
+
# puts "#{$$}: GC: #{id} #{refcount} #{pair.first.class} #{pair.last}"
|
172
|
+
|
173
|
+
if (pair[1] -= refcount) == 0
|
174
|
+
obj = @export_roots.delete(id)
|
175
|
+
if Conf.DISPLAY_GC
|
176
|
+
puts "#{$$}: GC: delete root: #{id} #{obj.first.to_s}"
|
177
|
+
end
|
178
|
+
else
|
179
|
+
if Conf.DISPLAY_GC
|
180
|
+
puts "#{$$}: GC: derefcount root: #{id} #{pair.first.to_s} #{pair[1]}"
|
181
|
+
if pair.first.kind_of?(Exception)
|
182
|
+
p pair.first
|
183
|
+
p pair.first.backtrace
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
else
|
188
|
+
if Conf.DISPLAY_GC
|
189
|
+
puts "#{$$}: GC: warn already deleted root: #{id.inspect}"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
#
|
197
|
+
# import 関連メソッド
|
198
|
+
#
|
199
|
+
def init_import_feature
|
200
|
+
# importしているオブジェクト
|
201
|
+
# peer_id => ref_id
|
202
|
+
@import_reference = {}
|
203
|
+
@rev_import_reference = {}
|
204
|
+
|
205
|
+
@import_reference_mutex = Mutex.new
|
206
|
+
@import_reference_cv = ConditionVariable.new
|
207
|
+
@deregister_reference_queue = []
|
208
|
+
|
209
|
+
@deregister_thread = nil
|
210
|
+
end
|
211
|
+
|
212
|
+
def import_reference(peer_id)
|
213
|
+
return import_reference_for_disable_gc(peer_id) unless Conf.ENABLE_GC
|
214
|
+
|
215
|
+
status = GC.disable
|
216
|
+
begin
|
217
|
+
@import_reference_mutex.synchronize do
|
218
|
+
if pair = @import_reference[peer_id]
|
219
|
+
begin
|
220
|
+
ObjectSpace._id2ref(pair.first)
|
221
|
+
rescue
|
222
|
+
ref_id = @import_reference.delete(peer_id)
|
223
|
+
@rev_import_reference.delete(ref_id)
|
224
|
+
@deregister_reference_queue.concat [peer_id, 1]
|
225
|
+
return nil
|
226
|
+
end
|
227
|
+
else
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
end
|
231
|
+
ensure
|
232
|
+
GC.enable unless status
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def import_reference_for_disable_gc(peer_id)
|
237
|
+
@import_reference_mutex.synchronize do
|
238
|
+
if pair = @import_reference[peer_id]
|
239
|
+
pair.first
|
240
|
+
else
|
241
|
+
nil
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def register_import_reference(ref)
|
247
|
+
return register_import_reference_for_disable_gc(ref) unless Conf.ENABLE_GC
|
248
|
+
|
249
|
+
status = GC.disable
|
250
|
+
begin
|
251
|
+
@import_reference_mutex.synchronize do
|
252
|
+
if pair = @import_reference[ref.peer_id]
|
253
|
+
pair[1] += 1
|
254
|
+
else
|
255
|
+
@import_reference[ref.peer_id] = [ref.object_id, 1]
|
256
|
+
@rev_import_reference[ref.object_id] = ref.peer_id
|
257
|
+
end
|
258
|
+
end
|
259
|
+
ObjectSpace.define_finalizer(ref, deregister_import_reference_proc)
|
260
|
+
ensure
|
261
|
+
GC.enable unless status
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def register_import_reference_for_disable_gc(ref)
|
266
|
+
@import_reference_mutex.synchronize do
|
267
|
+
if pair = @import_reference[ref.peer_id]
|
268
|
+
pair[1] += 1
|
269
|
+
else
|
270
|
+
@import_reference[ref.peer_id] = [ref, 1]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def deregister_import_reference(ref)
|
276
|
+
return deregister_import_reference_for_disable_gc(ref) unless Conf.ENABLE_GC
|
277
|
+
status = GC.disable
|
278
|
+
begin
|
279
|
+
@import_reference_mutex.synchronize do
|
280
|
+
pair = @import_reference.delete(ref.peer_id)
|
281
|
+
@rev_import_reference.delete(pair.first)
|
282
|
+
@deregister_reference_queue.concat [ref.peer_id, pair.last]
|
283
|
+
end
|
284
|
+
ensure
|
285
|
+
GC.enable unless status
|
286
|
+
@deregister_thread.wakeup
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def deregister_import_reference_for_disable_gc(ref)
|
291
|
+
status = GC.disable
|
292
|
+
begin
|
293
|
+
@import_reference_mutex.synchronize do
|
294
|
+
pair = @import_reference.delete(ref.peer_id)
|
295
|
+
@deregister_reference_queue.concat [ref.peer_id, pair.last]
|
296
|
+
end
|
297
|
+
ensure
|
298
|
+
GC.enable unless status
|
299
|
+
@deregister_thread.wakeup
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def deregister_import_reference_proc
|
304
|
+
proc do |ref_id|
|
305
|
+
if @status == :SERVICING
|
306
|
+
puts "#{$$}: GC: gced id: #{ref_id}" if Conf.DISPLAY_GC
|
307
|
+
peer_id = @rev_import_reference.delete(ref_id)
|
308
|
+
pair = @import_reference.delete(peer_id)
|
309
|
+
@deregister_reference_queue.concat [peer_id, pair.last]
|
310
|
+
@deregister_thread.wakeup
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def start_deregister_reference_org
|
316
|
+
@deregister_thread = Thread.start {
|
317
|
+
ids = []
|
318
|
+
while ids.push @deregister_reference_queue.pop
|
319
|
+
begin
|
320
|
+
while ids.push @deregister_reference_queue.pop(true); end
|
321
|
+
rescue ThreadError
|
322
|
+
deregister_roots_to_peer(ids) if @status == :SERVICING
|
323
|
+
end
|
324
|
+
end
|
325
|
+
}
|
326
|
+
end
|
327
|
+
|
328
|
+
def start_deregister_reference
|
329
|
+
@deregister_thread = Thread.start {
|
330
|
+
ids = []
|
331
|
+
loop do
|
332
|
+
Thread.stop
|
333
|
+
Thread.exit unless @status == :SERVICING
|
334
|
+
|
335
|
+
ids = []
|
336
|
+
@import_reference_mutex.synchronize do
|
337
|
+
status = GC.disable
|
338
|
+
begin
|
339
|
+
ids = @deregister_reference_queue.dup
|
340
|
+
@deregister_reference_queue.clear
|
341
|
+
ensure
|
342
|
+
GC.enable unless status
|
343
|
+
end
|
344
|
+
end
|
345
|
+
unless ids.empty?
|
346
|
+
deregister_roots_to_peer(ids)
|
347
|
+
end
|
348
|
+
sleep 1
|
349
|
+
end
|
350
|
+
}
|
351
|
+
end
|
352
|
+
|
353
|
+
def register_root_to_peer(id)
|
354
|
+
unless import_reference(id)
|
355
|
+
@session.register_root_to_peer(id)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def deregister_roots_to_peer(ids)
|
360
|
+
puts "#{$$}: GC: send deregister id: #{ids.join(' ')}" if Conf.DISPLAY_GC
|
361
|
+
@session.deregister_root_to_peer(ids)
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
366
|
+
class DeepSpaceNoConnection
|
367
|
+
def initialize(peer_id)
|
368
|
+
@peer_id = peer_id
|
369
|
+
end
|
370
|
+
|
371
|
+
attr_reader :peer_id
|
372
|
+
alias peer_uuid peer_id
|
373
|
+
|
374
|
+
def session
|
375
|
+
DC::Raise ConnectionRefused, @peer_id
|
376
|
+
end
|
377
|
+
def register_import_reference(r)
|
378
|
+
nil
|
379
|
+
end
|
380
|
+
|
381
|
+
def import_reference(r)
|
382
|
+
nil
|
383
|
+
end
|
384
|
+
|
385
|
+
def register_root_to_peer(object_id)
|
386
|
+
# do nothing
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
class IllegalObject
|
392
|
+
def initialize(id)
|
393
|
+
@id = id
|
394
|
+
end
|
395
|
+
|
396
|
+
def send(*opts)
|
397
|
+
DC.Raise IllegalReference, @id, opts.first
|
398
|
+
end
|
399
|
+
alias __send__ send
|
400
|
+
alias __public_send__ send
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|