00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <unistd.h>
00026
00027 #include <stlib/os/Thread.h>
00028 #include <stlib/Array.h>
00029 #include <stlib/Iterator.h>
00030 #include <stlib/Set.h>
00031 #include <stlib/String.h>
00032 #include <stlib/NotFoundError.h>
00033
00034 using namespace OS;
00035
00036 Set Thread::threads(5);
00037
00038 Thread::Thread(Callback<void> *receiver)
00039 {
00040 finalizeThreads();
00041
00042 pthread_mutex_init(&mutVar, NULL);
00043 pthread_cond_init(&runCond, NULL);
00044
00045 _receiver = receiver;
00046 _arguments = nil;
00047
00048 runningThread = false;
00049 }
00050
00051 Thread::~Thread(void)
00052 {
00053 terminate();
00054
00055 pthread_cond_destroy(&runCond);
00056 pthread_mutex_destroy(&mutVar);
00057 _receiver = nil;
00058 }
00059
00060
00061 String *Thread::className(void) const
00062 {
00063 return new String("Thread");
00064 }
00065
00066 Thread *Thread::fork(Callback<void> *receiver)
00067 {
00068 Thread *thread = new Thread(receiver);
00069 thread->run();
00070 return thread;
00071 }
00072
00073 Thread *Thread::fork(Callback<void> *receiver, Array *args)
00074 {
00075 Thread *thread = new Thread(receiver);
00076 thread->arguments(args);
00077 thread->run();
00078 return thread;
00079 }
00080
00081
00082 void Thread::finalizeThreads(void)
00083 {
00084 Set *temp = (Set *) threads.copy();
00085 for (Iterator* i = temp->iterator(); !i->finished(); i->next()) {
00086 Thread *th = (Thread *) i->value();
00087 if (!th->isRunning())
00088 th->finalize();
00089 }
00090 delete temp;
00091 }
00092
00093 void Thread::arguments(Array *args)
00094 {
00095 _arguments = args;
00096 }
00097
00098
00099 void Thread::resume()
00100 {
00101 if (runningThread == false) {
00102
00103 return;
00104 }
00105 pthread_cond_signal(&runCond);
00106 }
00107
00108
00109 void Thread::suspend()
00110 {
00111 if (runningThread == false) {
00112
00113 return;
00114 }
00115 pthread_cond_wait(&runCond, &mutVar);
00116 }
00117
00118
00119
00120 void Thread::run()
00121 {
00122 runningThread = true;
00123 pthread_create(&hThread, NULL, threadProc, this);
00124 threads.add(this);
00125 }
00126
00127 void Thread::finalize(void)
00128 {
00129 pthread_join(hThread, NULL);
00130 runningThread = false;
00131 try {
00132 threads.remove(this);
00133 }
00134 catch (NotFoundError *ex) {
00135
00136 }
00137 }
00138
00139 void Thread::terminate(void)
00140 {
00141
00142 if (runningThread != false) {
00143 pthread_cancel(hThread);
00144
00145 finalize();
00146 }
00147 }
00148
00149 void Thread::yield(void)
00150 {
00151 sleep(1);
00152 }
00153
00154
00155 bool Thread::isRunning(void)
00156 {
00157 return runningThread;
00158 }
00159
00160
00161 void *Thread::threadProc(void *x)
00162 {
00163
00164 Thread *myThread = (Thread *) x;
00165
00166 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00167 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00168 myThread->runningThread = true;
00169
00170 myThread->_receiver->executeWith(myThread->_arguments);
00171
00172 myThread->runningThread = false;
00173
00174 return NULL;
00175
00176 }