Mercurial > hg > orthanc-stone
comparison Framework/Loaders/LoaderStateMachine.cpp @ 973:38409549db43 toa2019082903
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
where:
- a message is sent with a receiver
- the receiver dies
- another receiver with the SAME address is created
- the message reply is executed --> execution on the wrong object!
(since their "identity" is their address. The fix is to identify them with
an UUID stored at creation time)
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Thu, 29 Aug 2019 18:07:55 +0200 |
parents | 91f827272c1f |
children | e75fd08d6c75 |
comparison
equal
deleted
inserted
replaced
972:fdf8b013f228 | 973:38409549db43 |
---|---|
21 | 21 |
22 #include "LoaderStateMachine.h" | 22 #include "LoaderStateMachine.h" |
23 | 23 |
24 #include <Core/OrthancException.h> | 24 #include <Core/OrthancException.h> |
25 | 25 |
26 #if 0 | |
27 extern bool logbgo233; | |
28 extern bool logbgo115; | |
29 #endif | |
30 | |
31 namespace OrthancStone | 26 namespace OrthancStone |
32 { | 27 { |
33 void LoaderStateMachine::State::Handle(const OrthancRestApiCommand::SuccessMessage& message) | 28 void LoaderStateMachine::State::Handle(const OrthancRestApiCommand::SuccessMessage& message) |
34 { | 29 { |
35 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 30 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
48 } | 43 } |
49 | 44 |
50 | 45 |
51 void LoaderStateMachine::Schedule(OracleCommandWithPayload* command) | 46 void LoaderStateMachine::Schedule(OracleCommandWithPayload* command) |
52 { | 47 { |
53 #if 0 | 48 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Schedule()"; |
54 if (logbgo233) { | |
55 if (logbgo115) | |
56 LOG(TRACE) << " LoaderStateMachine::Schedule()"; | |
57 } | |
58 #endif | |
59 | 49 |
60 std::auto_ptr<OracleCommandWithPayload> protection(command); | 50 std::auto_ptr<OracleCommandWithPayload> protection(command); |
61 | 51 |
62 if (command == NULL) | 52 if (command == NULL) |
63 { | 53 { |
67 if (!command->HasPayload()) | 57 if (!command->HasPayload()) |
68 { | 58 { |
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | 59 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, |
70 "The payload must contain the next state"); | 60 "The payload must contain the next state"); |
71 } | 61 } |
72 | |
73 #if 0 | |
74 if (logbgo233) { | |
75 if (logbgo115) | |
76 LOG(TRACE) << " * LoaderStateMachine::Schedule(): adding command with addr: " << std::hex << protection.get() << std::dec << " pendingCommands_.size() is now : " << pendingCommands_.size()+1; | |
77 } | |
78 #endif | |
79 pendingCommands_.push_back(protection.release()); | 62 pendingCommands_.push_back(protection.release()); |
80 | 63 |
81 Step(); | 64 Step(); |
82 } | 65 } |
83 | 66 |
84 | 67 |
85 void LoaderStateMachine::Start() | 68 void LoaderStateMachine::Start() |
86 { | 69 { |
70 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Start()"; | |
71 | |
87 if (active_) | 72 if (active_) |
88 { | 73 { |
89 LOG(TRACE) << "LoaderStateMachine::Start() called while active_ is true"; | 74 LOG(TRACE) << "LoaderStateMachine::Start() called while active_ is true"; |
90 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | 75 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
91 } | 76 } |
99 } | 84 } |
100 | 85 |
101 | 86 |
102 void LoaderStateMachine::Step() | 87 void LoaderStateMachine::Step() |
103 { | 88 { |
104 #if 0 | |
105 if (logbgo115) | |
106 LOG(TRACE) << " LoaderStateMachine::Step(): pendingCommands_.size() = " << pendingCommands_.size(); | |
107 #endif | |
108 if (!pendingCommands_.empty() && | 89 if (!pendingCommands_.empty() && |
109 activeCommands_ < simultaneousDownloads_) | 90 activeCommands_ < simultaneousDownloads_) |
110 { | 91 { |
111 | 92 |
112 IOracleCommand* nextCommand = pendingCommands_.front(); | 93 IOracleCommand* nextCommand = pendingCommands_.front(); |
113 | 94 |
114 #if 0 | 95 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec << |
115 if (logbgo233) { | 96 ")::Step(): activeCommands_ (" << activeCommands_ << |
116 if (logbgo115) | 97 ") < simultaneousDownloads_ (" << simultaneousDownloads_ << |
117 LOG(TRACE) << " * LoaderStateMachine::Step(): activeCommands_ (" << activeCommands_ << ") < simultaneousDownloads_ (" << simultaneousDownloads_ << ") --> will Schedule command addr " << std::hex << nextCommand << std::dec; | 98 ") --> will Schedule command addr " << std::hex << nextCommand << std::dec; |
118 } | |
119 #endif | |
120 | 99 |
121 oracle_.Schedule(*this, nextCommand); | 100 oracle_.Schedule(*this, nextCommand); |
122 pendingCommands_.pop_front(); | 101 pendingCommands_.pop_front(); |
123 | 102 |
124 activeCommands_++; | 103 activeCommands_++; |
125 } | 104 } |
126 else | 105 else |
127 { | 106 { |
128 #if 0 | 107 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec << |
129 if (logbgo233) { | 108 ")::Step(): activeCommands_ (" << activeCommands_ << |
130 if (logbgo115) | 109 ") < simultaneousDownloads_ (" << simultaneousDownloads_ << |
131 LOG(TRACE) << " * pendingCommands_.size() == " << pendingCommands_.size() << " LoaderStateMachine::Step(): activeCommands_ (" << activeCommands_ << ") >= simultaneousDownloads_ (" << simultaneousDownloads_ << ") --> will NOT Schedule anything"; | 110 ") --> will NOT Schedule command"; |
132 } | |
133 #endif | |
134 } | 111 } |
135 } | 112 } |
136 | 113 |
137 | 114 |
138 void LoaderStateMachine::Clear() | 115 void LoaderStateMachine::Clear() |
139 { | 116 { |
117 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Clear()"; | |
140 for (PendingCommands::iterator it = pendingCommands_.begin(); | 118 for (PendingCommands::iterator it = pendingCommands_.begin(); |
141 it != pendingCommands_.end(); ++it) | 119 it != pendingCommands_.end(); ++it) |
142 { | 120 { |
143 delete *it; | 121 delete *it; |
144 } | 122 } |
156 } | 134 } |
157 | 135 |
158 template <typename T> | 136 template <typename T> |
159 void LoaderStateMachine::HandleSuccessMessage(const T& message) | 137 void LoaderStateMachine::HandleSuccessMessage(const T& message) |
160 { | 138 { |
161 assert(activeCommands_ > 0); | 139 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage()"; |
140 if (activeCommands_ <= 0) { | |
141 LOG(ERROR) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage : activeCommands_ should be > 0 but is: " << activeCommands_; | |
142 } | |
162 activeCommands_--; | 143 activeCommands_--; |
163 | 144 |
164 try | 145 try |
165 { | 146 { |
166 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message); | 147 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message); |
181 oracle_(oracle), | 162 oracle_(oracle), |
182 active_(false), | 163 active_(false), |
183 simultaneousDownloads_(4), | 164 simultaneousDownloads_(4), |
184 activeCommands_(0) | 165 activeCommands_(0) |
185 { | 166 { |
167 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::LoaderStateMachine()"; | |
168 | |
186 oracleObservable.RegisterObserverCallback( | 169 oracleObservable.RegisterObserverCallback( |
187 new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage> | 170 new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage> |
188 (*this, &LoaderStateMachine::HandleSuccessMessage)); | 171 (*this, &LoaderStateMachine::HandleSuccessMessage)); |
189 | 172 |
190 oracleObservable.RegisterObserverCallback( | 173 oracleObservable.RegisterObserverCallback( |
198 oracleObservable.RegisterObserverCallback( | 181 oracleObservable.RegisterObserverCallback( |
199 new Callable<LoaderStateMachine, OracleCommandExceptionMessage> | 182 new Callable<LoaderStateMachine, OracleCommandExceptionMessage> |
200 (*this, &LoaderStateMachine::HandleExceptionMessage)); | 183 (*this, &LoaderStateMachine::HandleExceptionMessage)); |
201 } | 184 } |
202 | 185 |
186 LoaderStateMachine::~LoaderStateMachine() | |
187 { | |
188 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::~LoaderStateMachine()"; | |
189 Clear(); | |
190 } | |
203 | 191 |
204 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count) | 192 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count) |
205 { | 193 { |
206 if (active_) | 194 if (active_) |
207 { | 195 { |