Mercurial > hg > orthanc
annotate Resources/Archives/MessageWithDestination.cpp @ 445:7816aaa5db17
merge
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 17 May 2013 17:32:16 +0200 |
parents | e5402c368b21 |
children |
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 | |
141 | 5 #include <stdint.h> |
140 | 6 #include <memory> |
7 #include <map> | |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
8 #include <gtest/gtest.h> |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
9 #include <string> |
140 | 10 #include <boost/thread.hpp> |
11 #include <boost/date_time/posix_time/posix_time_types.hpp> | |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
12 |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
13 namespace Orthanc |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
14 { |
140 | 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 | |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
89 /** |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
90 * 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
|
91 **/ |
140 | 92 class MessageToDispatch : public boost::noncopyable |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
93 { |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
94 private: |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
95 IDynamicObject* message_; |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
96 std::string destination_; |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
97 |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
98 public: |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
99 /** |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
100 * Create a new message with a destination. |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
101 * \param message The content of the message (takes the ownership) |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
102 * \param destination The destination of the message |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
103 **/ |
140 | 104 MessageToDispatch(IDynamicObject* message, |
105 const char* destination) | |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
106 { |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
107 message_ = message; |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
108 destination_ = destination; |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
109 } |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
110 |
140 | 111 ~MessageToDispatch() |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
112 { |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
113 if (message_) |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
114 { |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
115 delete message_; |
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 } |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
118 }; |
140 | 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 }; | |
139
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 |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
163 #include "../Core/DicomFormat/DicomString.h" |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
164 |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
165 using namespace Orthanc; |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
166 |
140 | 167 TEST(MessageToDispatch, A) |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
168 { |
140 | 169 MessageToDispatch a(new DicomString("coucou"), "pukkaj"); |
139
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
170 } |
3ad78369fcc4
start threaded messages
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
171 |