Class: Dramatis::Runtime::Task::Continuation::RPC

Inherits:
Object
  • Object
show all
Includes:
Dramatis
Defined in:
lib/dramatis/runtime/task.rb

Instance Method Summary collapse

Methods included from Dramatis

future, interface, release

Constructor Details

#initialize(name, call_thread, nonblocking) ⇒ RPC

Returns a new instance of RPC.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/dramatis/runtime/task.rb', line 119

def initialize name, call_thread, nonblocking
  # all the synchronizaton here probably gets tossed
  # proof:
  # to create the continuation, you have to have the actor lock
  # to deliver the continuation you have to have the actor lock
  # QED
  # when this wasn't a message send, you could try to execute before
  # but now that's not possible; it'll get queued
  # i think
  # of course, it should be harmless
  # fix ... might want to seperate the two parts of a continuation
  # the value part and the thread state part
  @blocking = !nonblocking
  @state = :start
  @mutex = Mutex.new
  @wait = ConditionVariable.new
  @call_thread = call_thread
  # warn "contiunation to #{actor}"
  @actor = interface( Dramatis::Runtime::Scheduler.actor ).send :continuation, self, :call_thread => call_thread
end

Instance Method Details

#actorObject



115
116
117
# File 'lib/dramatis/runtime/task.rb', line 115

def actor
  @actor.instance_eval { @actor }
end

#continuation_exception(exception) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/dramatis/runtime/task.rb', line 220

def continuation_exception exception
  # warn "except rpc"
  @mutex.synchronize do
    raise "hell" if @state != :start and @state != :waiting
    @type = :exception
    @value = exception
    if @state == :start
      @state = :signaled
    else
      @state = :done
      Dramatis::Runtime::Scheduler.current.wakeup_notification self
      @wait.signal
    end
  end
end

#continuation_result(result) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/dramatis/runtime/task.rb', line 205

def continuation_result result
  @mutex.synchronize do
    raise "hell" if @state != :start and @state != :waiting
    @type = :return
    @value = result
    if @state == :start
      @state = :signaled
    else
      @state = :done
      Dramatis::Runtime::Scheduler.current.wakeup_notification self
      @wait.signal
    end
  end
end

#exception(exception) ⇒ Object



198
199
200
201
202
203
# File 'lib/dramatis/runtime/task.rb', line 198

def exception exception
  # warn "4 exception " + exception.to_s
  # warn "4 exception " + exception.backtrace.join("\n")
  @actor.exception exception
  # warn "4 delivered ".to_s
end

#queuedObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/dramatis/runtime/task.rb', line 140

def queued

  @mutex.synchronize do
    raise "hell " + @state.to_s if @state != :start and @state != :signaled
    if @state == :start
      @state = :waiting
      begin
        tag = to_s
        call_thread = @call_thread
        blocking = @blocking
        @actor.instance_eval do
          @actor.instance_eval do
            # warn "#{self} ct [ #{call_thread} ]"
            @call_thread = call_thread
          end
          if blocking
            @actor.gate.only [ :continuation, tag ], :tag => tag
          end
          @actor.schedule self
        end
        begin
          Dramatis::Runtime::Scheduler.current.suspend_notification self
          @wait.wait @mutex
          # this causes a deadlock if the waking thread, which may be
          # retiring, does so before this thead has awakend and notified
          # the scheduler
          # sleep 1
        ensure
          # Dramatis::Runtime::Scheduler.current.wakeup_notification self
        end
      ensure
        tag = to_s
        @actor.instance_eval do
          @actor.gate.default_by_tag tag
        end
      end
      raise "hell" if @state != :done
    end
  end

  raise "hell " + @type.inspect if ![ :return, :exception ].include? @type
  case @type
  when :return
    return @value
  when :exception
    # if Dramatis::Deadlock === @value 
    # @value = Dramatis::Deadlock.new nil, :next => @value
    # end
    # pp "reraise", caller
    @value._dramatis_reraise
    raise @value
  end
end

#result(result) ⇒ Object



194
195
196
# File 'lib/dramatis/runtime/task.rb', line 194

def result result
  @actor.result result
end