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