00001
00002
00003 #include "cppscript"
00004 #include "dynamic/extensions.hpp"
00005 #include "thread.hpp"
00006 #include <memory>
00007
00008
00009 namespace
00010 {
00012 void thread_proc(void * param)
00013 {
00014 internal::use_new_apartment a;
00015 std::auto_ptr<var> thread(static_cast<var*>(param));
00016
00017 try
00018 {
00019 stack_trace_entry e1("thread");
00020
00021 (*thread)["return"] = (*thread)["Thread::function"]();
00022 }
00023 catch(var & v)
00024 {
00025 (*thread)["exception"] = v;
00026 }
00027 catch(std::exception&ex)
00028 {
00029 (*thread)["exception"] = exception("std::exception", ex.what());
00030 }
00031 catch(...)
00032 {
00033 (*thread)["exception"] = exception("...");
00034 }
00035 }
00036
00038 var thread_join(var thread)
00039 {
00040 {
00041 internal::leave_apartment l;
00042 thread["Thread::object"].as<api::thread>().join();
00043 }
00044 if( thread.contains("exception") )
00045 {
00046 throw var(thread["exception"]);
00047 }
00048 return thread["return"];
00049 }
00050
00051
00053 var thread_create(var fn)
00054 {
00055 var thread_t = dynamic::create<api::thread>();
00056
00057 var thread = object("thread").extend
00058 ("Thread::function", fn)
00059 ("join", thread_join)
00060 ("Thread::object", thread_t);
00061
00063 thread_t.as<api::thread>().run(thread_proc, new var( thread.proxy() ) );
00064
00065 return thread;
00066 }
00067
00068 void event_wait(var event)
00069 {
00070 internal::leave_apartment l;
00071 event["Event::object"].as<api::event>().wait();
00072 }
00073
00074 void event_signal(var event)
00075 {
00076 event["Event::object"].as<api::event>().signal();
00077 }
00078
00079 var event_create()
00080 {
00081 return object("event").extend
00082 ("Event::object", dynamic::create<api::event>())
00083 ("wait", event_wait)
00084 ("signal", event_signal);
00085 }
00086
00087 void mutex_lock(var mutex)
00088 {
00089 mutex["mutex"].as<api::mutex>().lock();
00090 }
00091
00092 void mutex_unlock(var mutex)
00093 {
00094 mutex["mutex"].as<api::mutex>().unlock();
00095 }
00096 }
00097
00098
00099 var dynamic::event()
00100 {
00101 return event_create();
00102 }
00103
00104
00105 var dynamic::thread(const var & fn)
00106 {
00107 return thread_create(fn);
00108 }
00109
00110
00111 void dynamic::sleep(var const & s)
00112 {
00113 internal::leave_apartment l;
00114 api::sleep(s.as_int());
00115 }
00116
00117
00118 var dynamic::mutex()
00119 {
00120 return object("mutex").extend
00121 ("lock", mutex_lock)
00122 ("unlock", mutex_unlock)
00123 ("mutex", create<api::mutex>());
00124 }
00125