1 | // |
---|---|
2 | // ActiveDispatcher.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Threading |
6 | // Module: ActiveObjects |
7 | // |
8 | // Copyright (c) 2006-2007, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/ActiveDispatcher.h" |
16 | #include "Poco/Notification.h" |
17 | #include "Poco/AutoPtr.h" |
18 | |
19 | |
20 | namespace Poco { |
21 | |
22 | |
23 | namespace |
24 | { |
25 | class MethodNotification: public Notification |
26 | { |
27 | public: |
28 | MethodNotification(ActiveRunnableBase::Ptr pRunnable): |
29 | _pRunnable(pRunnable) |
30 | { |
31 | } |
32 | |
33 | ActiveRunnableBase::Ptr runnable() const |
34 | { |
35 | return _pRunnable; |
36 | } |
37 | |
38 | private: |
39 | ActiveRunnableBase::Ptr _pRunnable; |
40 | }; |
41 | |
42 | class StopNotification: public Notification |
43 | { |
44 | }; |
45 | } |
46 | |
47 | |
48 | ActiveDispatcher::ActiveDispatcher() |
49 | { |
50 | } |
51 | |
52 | |
53 | ActiveDispatcher::ActiveDispatcher(Thread::Priority prio) |
54 | { |
55 | _thread.setPriority(prio); |
56 | } |
57 | |
58 | |
59 | ActiveDispatcher::~ActiveDispatcher() |
60 | { |
61 | try |
62 | { |
63 | stop(); |
64 | } |
65 | catch (...) |
66 | { |
67 | } |
68 | } |
69 | |
70 | |
71 | void ActiveDispatcher::start(ActiveRunnableBase::Ptr pRunnable) |
72 | { |
73 | poco_check_ptr (pRunnable); |
74 | |
75 | if (!_thread.isRunning()) |
76 | { |
77 | _thread.start(*this); |
78 | } |
79 | |
80 | _queue.enqueueNotification(new MethodNotification(pRunnable)); |
81 | } |
82 | |
83 | |
84 | void ActiveDispatcher::cancel() |
85 | { |
86 | _queue.clear(); |
87 | } |
88 | |
89 | |
90 | void ActiveDispatcher::run() |
91 | { |
92 | AutoPtr<Notification> pNf = _queue.waitDequeueNotification(); |
93 | while (pNf && !dynamic_cast<StopNotification*>(pNf.get())) |
94 | { |
95 | MethodNotification* pMethodNf = dynamic_cast<MethodNotification*>(pNf.get()); |
96 | poco_check_ptr (pMethodNf); |
97 | ActiveRunnableBase::Ptr pRunnable = pMethodNf->runnable(); |
98 | pRunnable->duplicate(); // run will release |
99 | pRunnable->run(); |
100 | pRunnable = 0; |
101 | pNf = 0; |
102 | pNf = _queue.waitDequeueNotification(); |
103 | } |
104 | } |
105 | |
106 | |
107 | void ActiveDispatcher::stop() |
108 | { |
109 | _queue.clear(); |
110 | _queue.wakeUpAll(); |
111 | _queue.enqueueNotification(new StopNotification); |
112 | _thread.join(); |
113 | } |
114 | |
115 | |
116 | } // namespace Poco |
117 |