00001
00002 #ifndef DV_THREAD_ACTOR_H
00003 #define DV_THREAD_ACTOR_H
00004
00005 #include <functional>
00006 #include <dvthread/mailbox.h>
00007 #include <dvthread/flexlock.h>
00008
00009 namespace Dv {
00010 namespace Thread {
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 template<typename Handler>
00025 class Actor: public Dv::Thread::Thread {
00026 public:
00027 typedef typename Handler::argument_type Message;
00028 typedef typename Handler::result_type Reply;
00029 typedef MailBox<Reply> ReplyBox;
00030 typedef std::pair<Message,ReplyBox*> MessageReply;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 Actor(const std::string& name, Handler& handler, size_t delay = 2000,
00045 size_t max_capacity = 0, unsigned int min_debug_level = 0,
00046 Debugable* debug_master=0): Thread(false, min_debug_level, debug_master),
00047 name_(name), delay_(delay), handler_(handler),
00048 mbox_(name + "_mbox", max_capacity, min_debug_level, debug_master) {
00049 start();
00050 }
00051
00052
00053 ~Actor() {
00054 }
00055
00056
00057
00058
00059
00060
00061
00062 void request(const Message& m, ReplyBox* r = 0) {
00063 mbox_.put(std::make_pair(m,r));
00064 }
00065
00066
00067 int main() {
00068 try {
00069 while (! killed()) {
00070 try {
00071 MessageReply mr = mbox_.get(delay_);
00072 if (mr.second)
00073 mr.second->put(handler_(mr.first));
00074 else
00075 handler_(mr.first);
00076 }
00077 catch (std::runtime_error& e) {
00078
00079
00080 }
00081 }
00082 return 0;
00083 }
00084 catch (std::exception& e) {
00085 return -1;
00086 }
00087 catch (int e) {
00088 return e;
00089 }
00090 }
00091
00092
00093 const std::string& name() const { return name_; }
00094
00095 private:
00096 std::string name_;
00097 size_t delay_;
00098 Handler& handler_;
00099 MailBox<MessageReply> mbox_;
00100 };
00101
00102 }
00103 }
00104 #endif