Skip to content

Commit d532138

Browse files
committed
^Synchronized_queue ^Active_object
1 parent 7d21ec8 commit d532138

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

cpp/patterns.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -830,33 +830,36 @@ void architectural_patterns_demo()
830830
@{
831831
*/
832832

833-
template <typename T, class Container = std::queue<T>>
833+
template <typename T, class Container = queue<T>>
834834
class Synchronized_queue
835835
: Container {
836836
mutex mtx;
837+
bool stoped = false;
837838

838839
public:
839840
condition_variable cv;
840-
bool stop = false;
841841
void push(T&& v)
842842
{
843843
scoped_lock<mutex> { mtx }, Container::push(v);
844844
cv.notify_one();
845845
};
846846

847-
optional<reference_wrapper<T>> pull()
847+
T& pull()
848848
{
849849
unique_lock<mutex> lk(mtx);
850-
cv.wait(lk, [&] { return !this->empty() || stop; });
851-
optional<reference_wrapper<T>> ret;
852-
if (stop) {
853-
ret = nullopt;
854-
} else {
855-
ret = make_optional(ref(Container::front()));
856-
this->pop();
857-
}
850+
cv.wait(lk, [&] { return !this->empty() || stoped; });
851+
if (stoped)
852+
throw "stopped";
853+
auto ret = ref(Container::front());
854+
this->pop();
858855
return ret;
859856
};
857+
858+
void stop()
859+
{
860+
stoped = true;
861+
cv.notify_one();
862+
}
860863
};
861864

862865
struct Active_object
@@ -872,18 +875,16 @@ struct Active_object
872875
: subject(s)
873876
{
874877
th = thread([this] {
875-
while (true) {
876-
auto cmd = cmd_q.pull();
877-
if (!cmd.has_value())
878-
break;
879-
cmd.value()();
878+
try {
879+
while (true)
880+
cmd_q.pull()(); // call Command
881+
} catch (...) {
880882
}
881883
});
882884
}
883885
~Active_object()
884886
{
885-
cmd_q.stop = true;
886-
cmd_q.cv.notify_one();
887+
cmd_q.stop();
887888
th.join();
888889
}
889890

@@ -892,6 +893,9 @@ struct Active_object
892893
promise<int> p;
893894
future f = p.get_future();
894895
cmd_q.push([&p, this] { p.set_value(subject.method()); });
896+
auto status = f.wait_for(1s);
897+
if (status != future_status::ready)
898+
throw status;
895899
return f.get();
896900
}
897901

0 commit comments

Comments
 (0)