00001 Hello,
00002
00003 Here's the stuff. It should be pretty self-explanatory.
00004
00005 Ideally, we should have some way of encapsulating message
00006 sends/replies so we can send some buffers around rather than
00007 primitive C arrays, but right now, I'm just testing.
00008
00009 This worked out of the box, BTW---no need to do anything
00010 bizarre (except that the C++ compiler doesn't like the bool
00011 type, so I had to make those ints).
00012
00013 The code follows my signature. Just 'cc thread.cc'. It's
00014 lousy; I don't check all return values. But then again,
00015 that's just test code, and most production code doesn't check
00016 all return values, either (I should know; I write production
00017 code during summers) :{)
00018
00019 To whomever had an a.out in the c directory: I scrapped it,
00020 sorry. :{) I also put the C++ code in thread.cc in the c
00021 subdirectory of our group directory (in other words,
00022
00023
00024 The technique should be applicable to other kinds of
00025 callbacks. I'll work on getting support for interrupt
00026 handlers later this week.
00027
00028 While I'm here, if you want to contact me by phone, it's
00029 (514) 351-2378. I recommend you e-mail me instead unless it's
00030 something really, really urgent.
00031
00032 --
00033 Benoit Goudreault-Emond -- Reply to: bge@crosswinds.net
00034 CoFounder, KMS Group. Student, B. CompEng, Concordia University.
00035 A proud user of Linux---I'd rather work than nursemaid my computer.
00036 My homepage (such as it is): http:
00037
00038
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <process.h>
00043 #include <stddef.h>
00044 #include <string.h>
00045 #include <sys/kernel.h>
00046 #include <assert.h>
00047
00048 class Thread
00049 {
00050 protected:
00051 pid_t thread_id_;
00052 static void wrapper(void* p);
00053 static const size_t stack_size;
00054 public:
00055 Thread() : thread_id_(-1) {}
00056 int start(size_t stk = stack_size);
00057 int sendmsg(void* msg, size_t mlen,
00058 void* rcv, size_t rlen);
00059 virtual void run() = 0;
00060 virtual ~Thread() {}
00061 };
00062
00063 const size_t Thread::stack_size = 4096;
00064
00065 void Thread::wrapper(void* p)
00066 {
00067 Thread* self = (Thread*)p;
00068 self->run();
00069 _endthread();
00070 }
00071
00072 int Thread::start(size_t stk)
00073 {
00074 assert(thread_id_ < 0);
00075 thread_id_ = _beginthread(Thread::wrapper, NULL, stk, this);
00076 return thread_id_;
00077 }
00078
00079 int Thread::sendmsg(void* msg, size_t mlen, void* rcv, size_t rlen)
00080 {
00081 assert(thread_id_ >= 0);
00082 return Send(thread_id_, msg, rcv, mlen, rlen);
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092 class DisplayThread : public Thread
00093 {
00094 private:
00095 char buffer_[256];
00096 static const char* ok_response;
00097 static const char* error_response;
00098
00099 virtual void run();
00100 };
00101
00102 const char* DisplayThread::ok_response = "OK\n";
00103 const char* DisplayThread::error_response = "ERROR\n";
00104
00105 void DisplayThread::run()
00106 {
00107 pid_t pid;
00108 while(1)
00109 {
00110 const char* response;
00111
00112 if((pid = Receive(0, buffer_, sizeof(buffer_))) < 0)
00113 {
00114 printf("ERROR--code %d\n", errno);
00115 return;
00116 }
00117
00118 buffer_[sizeof(buffer_)-1] = '\0';
00119
00120 if(!strcmp(buffer_, "ERROR"))
00121 response = error_response;
00122 else if(!strcmp(buffer_, "END"))
00123 break;
00124 else
00125 response = ok_response;
00126
00127 printf("Got from %d: %s\n", pid, buffer_);
00128
00129 Reply(pid, response, strlen(response)+1);
00130 }
00131
00132 Reply(pid, ok_response, sizeof(ok_response));
00133 }
00134
00135
00136
00137 int main()
00138 {
00139 DisplayThread thread;
00140 char buffer[256], recv[256];
00141
00142 if(thread.start() < 0)
00143 {
00144 printf("UUURGH! Thread could not start! (%d)\n", errno);
00145 return 1;
00146 }
00147
00148
00149 while(1)
00150 {
00151
00152 printf("Message to send (END to end): ");
00153 fgets(buffer, sizeof(buffer), stdin);
00154 int len = strlen(buffer);
00155 if(buffer[len-1] == '\n')
00156 {
00157 buffer[len-1] = '\0';
00158 --len;
00159 }
00160 thread.sendmsg(buffer, len+1, recv, sizeof(recv));
00161 printf("Got back: %s", recv);
00162 if(!strcmp(buffer, "END"))
00163 break;
00164 }
00165 return 0;
00166 }