File: //usr/share/ri/3.0.0/system/Fiber/transfer-i.ri
U:RDoc::AnyMethod[iI"
transfer:ETI"Fiber#transfer;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [
I"GTransfer control to another fiber, resuming it from where it last ;TI"Fstopped or starting it if it was not resumed before. The calling ;TI"4fiber will be suspended much like in a call to ;TI";Fiber.yield. You need to <code>require 'fiber'</code> ;TI"before using this method.;To:RDoc::Markup::BlankLine o;
; [I"GThe fiber which receives the transfer call is treats it much like ;TI"Ha resume call. Arguments passed to transfer are treated like those ;TI"passed to resume.;T@o;
; [I"LThe two style of control passing to and from fiber (one is #resume and ;TI"KFiber::yield, another is #transfer to and from fiber) can't be freely ;TI"mixed.;T@o:RDoc::Markup::List:
@type:BULLET:@items[o:RDoc::Markup::ListItem:@label0; [o;
; [ I"GIf the Fiber's lifecycle had started with transfer, it will never ;TI":be able to yield or be resumed control passing, only ;TI"Efinish or transfer back. (It still can resume other fibers that ;TI" are allowed to be resumed.);To;;0; [o;
; [I"DIf the Fiber's lifecycle had started with resume, it can yield ;TI"Eor transfer to another Fiber, but can receive control back only ;TI"Bthe way compatible with the way it was given away: if it had ;TI"Atransferred, it only can be transferred back, and if it had ;TI"Dyielded, it only can be resumed back. After that, it again can ;TI"transfer or yield.;T@o;
; [I"4If those rules are broken FiberError is raised.;T@o;
; [
I"FFor an individual Fiber design, yield/resume is more easy to use ;TI"Hstyle (the Fiber just gives away control, it doesn't need to think ;TI"Iabout who the control is given to), while transfer is more flexible ;TI"Efor complex cases, allowing to build arbitrary graphs of Fibers ;TI"dependent on each other.;T@o;
; [I"
Example:;T@o:RDoc::Markup::Verbatim; [%I"require 'fiber'
;TI"
;TI"Emanager = nil # For local var to be visible inside worker block
;TI"
;TI"1# This fiber would be started with transfer
;TI",# It can't yield, and can't be resumed
;TI"!worker = Fiber.new { |work|
;TI" puts "Worker: starts"
;TI"C puts "Worker: Performed #{work.inspect}, transferring back"
;TI"` # Fiber.yield # this would raise FiberError: attempt to yield on a not resumed fiber
;TI"j # manager.resume # this would raise FiberError: attempt to resume a resumed fiber (double resume)
;TI") manager.transfer(work.capitalize)
;TI"}
;TI"
;TI"/# This fiber would be started with resume
;TI"8# It can yield or transfer, and can be transferred
;TI"# back or resumed
;TI"manager = Fiber.new {
;TI" puts "Manager: starts"
;TI": puts "Manager: transferring 'something' to worker"
;TI"- result = worker.transfer('something')
;TI"9 puts "Manager: worker returned #{result.inspect}"
;TI"` # worker.resume # this would raise FiberError: attempt to resume a transferring fiber
;TI"\ Fiber.yield # this is OK, the fiber transferred from and to, now it can yield
;TI" puts "Manager: finished"
;TI"}
;TI"
;TI"!puts "Starting the manager"
;TI"manager.resume
;TI"!puts "Resuming the manager"
;TI"`# manager.transfer # this would raise FiberError: attempt to transfer to a yielding fiber
;TI"manager.resume
;T:@format0o;
; [I"<em>produces</em>;T@o;; [
I"Starting the manager
;TI"Manager: starts
;TI"1Manager: transferring 'something' to worker
;TI"Worker: starts
;TI"6Worker: Performed "something", transferring back
;TI"*Manager: worker returned "Something"
;TI"Resuming the manager
;TI"Manager: finished;T;0:
@fileI"cont.c;T:0@omit_headings_from_table_of_contents_below0I"&fiber.transfer(args, ...) -> obj
;T0[ I"(*args);T@mFI"
Fiber;TcRDoc::NormalClass00