Mercurial > projects > ldc
view tango/example/synchronization/condition.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line source
/******************************************************************************* copyright: Copyright (c) 2006 Juan Jose Comellas. All rights reserved license: BSD style: $(LICENSE) author: Juan Jose Comellas <juanjo@comellas.com.ar> Converted to use core.sync by Sean Kelly <sean@f4.ca> *******************************************************************************/ private import tango.core.sync.Condition; private import tango.core.Exception; private import tango.core.Thread; private import tango.text.convert.Integer; private import tango.io.Stdout; debug (condition) { private import tango.util.log.Log; private import tango.util.log.ConsoleAppender; private import tango.util.log.DateLayout; } void main(char[][] args) { debug (condition) { Logger log = Log.getLogger("condition"); log.addAppender(new ConsoleAppender(new DateLayout())); log.info("Condition test"); } testNotifyOne(); testNotifyAll(); } /** * Test for Condition.notify(). */ void testNotifyOne() { debug (condition) { Logger log = Log.getLogger("condition.notify-one"); } scope Mutex mutex = new Mutex(); scope Condition cond = new Condition(mutex); int waiting = 0; Thread thread; void notifyOneTestThread() { debug (condition) { Logger log = Log.getLogger("condition.notify-one." ~ Thread.getThis().name()); log.trace("Starting thread"); } try { synchronized (mutex) { debug (condition) log.trace("Acquired mutex"); scope(exit) { debug (condition) log.trace("Releasing mutex"); } waiting++; while (waiting != 2) { debug (condition) log.trace("Waiting on condition variable"); cond.wait(); } debug (condition) log.trace("Condition variable was signaled"); } } catch (SyncException e) { Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}", Thread.getThis().name(), e.toString()); } catch (Exception e) { Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}", Thread.getThis().name(), e.toString()); } debug (condition) log.trace("Exiting thread"); } thread = new Thread(¬ifyOneTestThread); thread.name = "thread-1"; debug (condition) log.trace("Created thread " ~ thread.name); thread.start(); try { // Poor man's barrier: wait until the other thread is waiting. while (true) { synchronized (mutex) { if (waiting != 1) { Thread.yield(); } else { break; } } } synchronized (mutex) { debug (condition) log.trace("Acquired mutex"); waiting++; debug (condition) log.trace("Notifying test thread"); cond.notify(); debug (condition) log.trace("Releasing mutex"); } thread.join(); if (waiting == 2) { debug (condition) log.info("The Condition notification test to one thread was successful"); } else { debug (condition) { log.error("The condition variable notification to one thread is not working"); assert(false); } else { assert(false, "The condition variable notification to one thread is not working"); } } } catch (SyncException e) { Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString()); } } /** * Test for Condition.notifyAll(). */ void testNotifyAll() { const uint MaxThreadCount = 10; debug (condition) { Logger log = Log.getLogger("condition.notify-all"); } scope Mutex mutex = new Mutex(); scope Condition cond = new Condition(mutex); int waiting = 0; /** * This thread waits for a notification from the main thread. */ void notifyAllTestThread() { debug (condition) { Logger log = Log.getLogger("condition.notify-all." ~ Thread.getThis().name()); log.trace("Starting thread"); } try { synchronized (mutex) { debug (condition) log.trace("Acquired mutex"); waiting++; while (waiting != MaxThreadCount + 1) { debug (condition) log.trace("Waiting on condition variable"); cond.wait(); } debug (condition) log.trace("Condition variable was signaled"); debug (condition) log.trace("Releasing mutex"); } } catch (SyncException e) { Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}", Thread.getThis().name(), e.toString()); } catch (Exception e) { Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}", Thread.getThis().name(), e.toString()); } debug (condition) log.trace("Exiting thread"); } ThreadGroup group = new ThreadGroup(); Thread thread; char[10] tmp; for (uint i = 0; i < MaxThreadCount; ++i) { thread = new Thread(¬ifyAllTestThread); thread.name = "thread-" ~ format(tmp, i); group.add(thread); debug (condition) log.trace("Created thread " ~ thread.name); thread.start(); } try { // Poor man's barrier: wait until all the threads are waiting. while (true) { synchronized (mutex) { if (waiting != MaxThreadCount) { Thread.yield(); } else { break; } } } synchronized (mutex) { debug (condition) log.trace("Acquired mutex"); waiting++; debug (condition) log.trace("Notifying all threads"); cond.notifyAll(); debug (condition) log.trace("Releasing mutex"); } debug (condition) log.trace("Waiting for threads to finish"); group.joinAll(); if (waiting == MaxThreadCount + 1) { debug (condition) log.info("The Condition notification test to many threads was successful"); } else { debug (condition) { log.error("The condition variable notification to many threads is not working"); assert(false); } else { assert(false, "The condition variable notification to many threads is not working"); } } } catch (SyncException e) { Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString()); } }