00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define ACEDIA_REDUCED_ANNOUNCE
00031
00032 #include "abstractactor.hpp"
00033 #include "actor.hpp"
00034 #include "actorref.hpp"
00035 #include "acedia_atomic.hpp"
00036 #include "acedia.hpp"
00037
00038 #include <map>
00039 #include <boost/thread/mutex.hpp>
00040
00041 static volatile boost::uint32_t usedActorIds = 0;
00042
00043 typedef std::map<boost::uint32_t, acedia::ActorRef> InstancesMap;
00044 typedef std::pair<boost::uint32_t, acedia::ActorRef> IdAndActorPair;
00045 typedef boost::mutex::scoped_lock ScopedLock;
00046
00047 static InstancesMap actorInstances;
00048 static boost::mutex actorInstancesMutex;
00049
00050 void addToInstances(boost::uint32_t id, const acedia::ActorRef &actor)
00051 {
00052 ScopedLock lock(actorInstancesMutex);
00053 actorInstances.insert(IdAndActorPair(id, actor));
00054 }
00055
00056 void removeFromInstances(boost::uint32_t id)
00057 {
00058 ScopedLock lock(actorInstancesMutex);
00059 actorInstances.erase(id);
00060 }
00061
00062 namespace acedia
00063 {
00064 namespace details
00065 {
00066 ActorRef getInstanceById(boost::uint32_t id)
00067 {
00068 ScopedLock lock(actorInstancesMutex);
00069 InstancesMap::iterator it = actorInstances.find(id);
00070 if (it == actorInstances.end())
00071 {
00072 return acedia::ActorRef();
00073 }
00074 return it->second;
00075 }
00076 }
00077
00078 AbstractActor::AbstractActor(bool farRef, bool isDummy) throw() :
00079 ReferenceCounted(0), m_isFarRef(farRef),
00080 m_exitReason(exit_reasons::NOT_EXITED)
00081 {
00082 m_self = new ActorRef(this, true);
00083 ACEDIA_MEMORY_BARRIER();
00084 if (!isDummy)
00085 {
00086 m_id = atomic::addAndFetch(&usedActorIds, 1);
00087 addToInstances(m_id, *m_self);
00088 }
00089 else m_id = 0;
00090 }
00091
00092 AbstractActor::~AbstractActor() { delete m_self; }
00093
00094 void AbstractActor::forward(const Message& what, ActorRef& whom)
00095 {
00096 whom.send(what);
00097 }
00098
00099 void AbstractActor::send(ActorRef &receiver,const Any &v1)
00100 {
00101 receiver.send(Message(self(),receiver,v1));
00102 }
00103
00104 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2)
00105 {
00106 receiver.send(Message(self(),receiver,v1,v2));
00107 }
00108
00109 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3)
00110 {
00111 receiver.send(Message(self(),receiver,v1,v2,v3));
00112 }
00113
00114 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4)
00115 {
00116 receiver.send(Message(self(),receiver,v1,v2,v3,v4));
00117 }
00118
00119 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5)
00120 {
00121 receiver.send(Message(self(),receiver,v1,v2,v3,v4,v5));
00122 }
00123
00124 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6)
00125 {
00126 receiver.send(Message(self(),receiver,v1,v2,v3,v4,v5,v6));
00127 }
00128
00129 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7)
00130 {
00131 receiver.send(Message(self(),receiver,v1,v2,v3,v4,v5,v6,v7));
00132 }
00133
00134 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7, const Any &v8)
00135 {
00136 receiver.send(Message(self(),receiver,v1,v2,v3,v4,v5,v6,v7,v8));
00137 }
00138
00139 void AbstractActor::send(ActorRef &receiver,const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7, const Any &v8, const Any &v9)
00140 {
00141 receiver.send(Message(self(),receiver,v1,v2,v3,v4,v5,v6,v7,v8,v9));
00142 }
00143
00144 void Actor::executeActor()
00145 {
00146 if (m_state == READY) m_state = RUNNING;
00147 try { act(); }
00148 catch (ActorKilledException &e)
00149 {
00150 m_exitReason = e.reason();
00151 }
00152 catch (...)
00153 {
00154 m_exitReason = exit_reasons::UNHANDLED_EXCEPTION;
00155 }
00156 if (exit_reasons::NOT_EXITED == m_exitReason)
00157 m_exitReason = exit_reasons::NORMAL_EXIT;
00158 ACEDIA_MEMORY_BARRIER();
00159 *yieldState = EXITED;
00160 removeFromInstances(id());
00161 }
00162
00163 void Actor::trampoline(Actor *_this)
00164 {
00165 _this->executeActor();
00166
00167 ACEDIA_MEMORY_BARRIER();
00168 Context::swap(*(_this->m_context),
00169 *const_cast<Context*>(_this->m_returnContext));
00170 }
00171
00172 #if defined(ACEDIA_UCONTEXT_IMPL)
00173 void Actor::ucontext_trampoline(int thisActor)
00174 #elif defined(ACEDIA_FIBER_IMPL)
00175 void Actor::fiber_trampoline(PVOID *thisActor)
00176 #endif
00177 {
00178 trampoline(reinterpret_cast<Actor*>(thisActor));
00179 }
00180
00181 }