Skip to content

Instantly share code, notes, and snippets.

@laverdet
Created March 31, 2012 02:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laverdet/2258802 to your computer and use it in GitHub Desktop.
Save laverdet/2258802 to your computer and use it in GitHub Desktop.
new Fiber + run() in same C++ function
diff --git a/src/fibers.cc b/src/fibers.cc
index 49a20f7..c446f9d 100644
--- a/src/fibers.cc
+++ b/src/fibers.cc
@@ -143,6 +143,42 @@ class Fiber {
}
/**
+ * Build a new fiber and immediately run it.
+ */
+ static Handle<Value> NewAndRun(const Arguments& args) {
+ if (args.Length() != 2) {
+ THROW(Exception::TypeError, "Expects 2 arguments");
+ } else if (!args[0]->IsFunction()) {
+ THROW(Exception::TypeError, "First argument should be a function");
+ }
+
+ // Create the fiber
+ Handle<Value> argv[1] = { args[0] };
+ Handle<Object> fiber = tmpl->GetFunction()->NewInstance(1, argv);
+ Unwrap(Fiber& that, fiber);
+
+ // Shamelessly copied from Run() in an attempt to make this faster
+ DestroyOrphans();
+ that.started = true;
+ void** data = new void*[2];
+ data[0] = (void*)&args;
+ data[1] = &that;
+ that.this_fiber = &Coroutine::create_fiber((void (*)(void*))RunFiber, data);
+ V8::AdjustAmountOfExternalAllocatedMemory(that.this_fiber->size() * GC_ADJUST);
+ that.SwapContext();
+
+ // Return an array or exception
+ if (that.yielded_exception) {
+ return that.ReturnYielded();
+ } else {
+ Local<Array> array = Array::New(2);
+ array->Set(0, fiber);
+ array->Set(1, that.ReturnYielded());
+ return array;
+ }
+ }
+
+ /**
* Instantiate a new Fiber object. When a fiber is created it only grabs a handle to the
* callback; it doesn't create any new contexts until run() is called.
*/
@@ -506,6 +542,7 @@ class Fiber {
// Fiber properties
Handle<Function> fn = tmpl->GetFunction();
fn->Set(sym_yield, yield);
+ fn->Set(String::NewSymbol("newAndRun"), FunctionTemplate::New(NewAndRun)->GetFunction());
fn->SetAccessor(String::NewSymbol("current"), GetCurrent);
fn->SetAccessor(String::NewSymbol("poolSize"), GetPoolSize, SetPoolSize);
fn->SetAccessor(String::NewSymbol("fibersCreated"), GetFibersCreated);
marcel@kumo ~/code/fibers $
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment