Mercurial > hg > orthanc
comparison Resources/Archives/MessageWithDestination.cpp @ 281:e5402c368b21
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 10 Dec 2012 17:49:14 +0100 |
parents | UnitTests/MessageWithDestination.cpp@24681d35bad9 |
children |
comparison
equal
deleted
inserted
replaced
280:77e526e6fdf8 | 281:e5402c368b21 |
---|---|
1 #include "../Core/IDynamicObject.h" | |
2 | |
3 #include "../Core/OrthancException.h" | |
4 | |
5 #include <stdint.h> | |
6 #include <memory> | |
7 #include <map> | |
8 #include <gtest/gtest.h> | |
9 #include <string> | |
10 #include <boost/thread.hpp> | |
11 #include <boost/date_time/posix_time/posix_time_types.hpp> | |
12 | |
13 namespace Orthanc | |
14 { | |
15 class SharedMessageQueue | |
16 { | |
17 private: | |
18 typedef std::list<IDynamicObject*> Queue; | |
19 | |
20 unsigned int maxSize_; | |
21 Queue queue_; | |
22 boost::mutex mutex_; | |
23 boost::condition_variable elementAvailable_; | |
24 | |
25 public: | |
26 SharedMessageQueue(unsigned int maxSize = 0) | |
27 { | |
28 maxSize_ = maxSize; | |
29 } | |
30 | |
31 ~SharedMessageQueue() | |
32 { | |
33 for (Queue::iterator it = queue_.begin(); it != queue_.end(); it++) | |
34 { | |
35 delete *it; | |
36 } | |
37 } | |
38 | |
39 void Enqueue(IDynamicObject* message) | |
40 { | |
41 boost::mutex::scoped_lock lock(mutex_); | |
42 | |
43 if (maxSize_ != 0 && queue_.size() > maxSize_) | |
44 { | |
45 // Too many elements in the queue: First remove the oldest | |
46 delete queue_.front(); | |
47 queue_.pop_front(); | |
48 } | |
49 | |
50 queue_.push_back(message); | |
51 elementAvailable_.notify_one(); | |
52 } | |
53 | |
54 IDynamicObject* Dequeue(int32_t timeout) | |
55 { | |
56 boost::mutex::scoped_lock lock(mutex_); | |
57 | |
58 // Wait for a message to arrive in the FIFO queue | |
59 while (queue_.empty()) | |
60 { | |
61 if (timeout == 0) | |
62 { | |
63 elementAvailable_.wait(lock); | |
64 } | |
65 else | |
66 { | |
67 bool success = elementAvailable_.timed_wait | |
68 (lock, boost::posix_time::milliseconds(timeout)); | |
69 if (!success) | |
70 { | |
71 throw OrthancException(ErrorCode_Timeout); | |
72 } | |
73 } | |
74 } | |
75 | |
76 std::auto_ptr<IDynamicObject> message(queue_.front()); | |
77 queue_.pop_front(); | |
78 | |
79 return message.release(); | |
80 } | |
81 | |
82 IDynamicObject* Dequeue() | |
83 { | |
84 return Dequeue(0); | |
85 } | |
86 }; | |
87 | |
88 | |
89 /** | |
90 * This class represents a message that is to be sent to some destination. | |
91 **/ | |
92 class MessageToDispatch : public boost::noncopyable | |
93 { | |
94 private: | |
95 IDynamicObject* message_; | |
96 std::string destination_; | |
97 | |
98 public: | |
99 /** | |
100 * Create a new message with a destination. | |
101 * \param message The content of the message (takes the ownership) | |
102 * \param destination The destination of the message | |
103 **/ | |
104 MessageToDispatch(IDynamicObject* message, | |
105 const char* destination) | |
106 { | |
107 message_ = message; | |
108 destination_ = destination; | |
109 } | |
110 | |
111 ~MessageToDispatch() | |
112 { | |
113 if (message_) | |
114 { | |
115 delete message_; | |
116 } | |
117 } | |
118 }; | |
119 | |
120 | |
121 class IDestinationContext : public IDynamicObject | |
122 { | |
123 public: | |
124 virtual void Handle(const IDynamicObject& message) = 0; | |
125 }; | |
126 | |
127 | |
128 class IDestinationContextFactory : public IDynamicObject | |
129 { | |
130 public: | |
131 virtual IDestinationContext* Construct(const char* destination) = 0; | |
132 }; | |
133 | |
134 | |
135 class MessageDispatcher | |
136 { | |
137 private: | |
138 typedef std::map<std::string, IDestinationContext*> ActiveContexts; | |
139 | |
140 std::auto_ptr<IDestinationContextFactory> factory_; | |
141 ActiveContexts activeContexts_; | |
142 SharedMessageQueue queue_; | |
143 | |
144 public: | |
145 MessageDispatcher(IDestinationContextFactory* factory) // takes the ownership | |
146 { | |
147 factory_.reset(factory); | |
148 } | |
149 | |
150 ~MessageDispatcher() | |
151 { | |
152 for (ActiveContexts::iterator it = activeContexts_.begin(); | |
153 it != activeContexts_.end(); it++) | |
154 { | |
155 delete it->second; | |
156 } | |
157 } | |
158 }; | |
159 } | |
160 | |
161 | |
162 | |
163 #include "../Core/DicomFormat/DicomString.h" | |
164 | |
165 using namespace Orthanc; | |
166 | |
167 TEST(MessageToDispatch, A) | |
168 { | |
169 MessageToDispatch a(new DicomString("coucou"), "pukkaj"); | |
170 } | |
171 |