using GLib; class Generator { private weak Thread thread; private Mutex mutex; private Cond cond_avail; private T yielded; private bool has_data; public delegate void Func(Generator gen); private Func func; public void* thread_func() { func(this); mutex.lock(); func = null; cond_avail.signal(); mutex.unlock(); return null; } public void yield(T data) { mutex.lock(); while(has_data) cond_avail.wait(mutex); yielded = data; has_data = true; cond_avail.signal(); mutex.unlock(); } public bool next(ref T value) { bool running; mutex.lock(); while(!has_data && func != null) cond_avail.wait(mutex); if(!has_data && func == null) running = false; else { running = true; value = yielded; has_data = false; cond_avail.signal(); } mutex.unlock(); return running; } public Generator (Func genfunc) { if (!Thread.supported ()) Thread.init (); func = genfunc; cond_avail = new Cond (); mutex = new Mutex (); has_data = false; } public void start() { thread = Thread.create (thread_func, false); } } class Test { static void generate(Generator gen) { int[] values = new int [] {100, 200, 300, 400, 500, 0}; int i; for(i=0; values[i] != 0; i++) { gen.yield(values[i]); Thread.usleep(500000); } } static void main(string[] args) { Generator gen = new Generator(generate); gen.start(); int value; while(gen.next(ref value)) { stdout.printf("Value = %d\n", value); } } }