~stolowski/unity-scopes-api/fix-1393382-rtm

« back to all changes in this revision

Viewing changes to src/scopes/internal/zmq_middleware/StopPublisher.cpp

  • Committer: Pawel Stolowski
  • Date: 2014-11-04 14:33:07 UTC
  • mfrom: (241.1.20 unity-scopes-api)
  • Revision ID: pawel.stolowski@canonical.com-20141104143307-cs70gjyowjtwpk69
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <unity/scopes/ScopeExceptions.h>
22
22
 
23
23
#include <cassert>
24
 
#include <iostream>
 
24
#include <iostream>  // TODO: remove this once logging is added
25
25
 
26
26
using namespace std;
27
27
 
70
70
 
71
71
StopPublisher::~StopPublisher()
72
72
{
73
 
    try
74
 
    {
75
 
        stop();
76
 
    }
77
 
    // LCOV_EXCL_START
78
 
    catch (std::exception const& e)
79
 
    {
80
 
        cerr << "~StopPublisher(): exception from stop(): " << e.what() << endl;
81
 
        // TODO: log this
82
 
    }
83
 
    catch (...)
84
 
    {
85
 
        cerr << "~StopPublisher(): unknown exception from stop()" << endl;
86
 
        // TODO: log this
87
 
    }
88
 
    // LCOV_EXCL_STOP
89
 
 
90
 
    {
91
 
        // The destructor may not be called from the same thread as
92
 
        // the constructor, so we need a full fence here.
93
 
        lock_guard<mutex> lock(m_);
94
 
    }
95
 
 
 
73
    stop();
 
74
    wait_until_stopped();
96
75
    if (thread_.joinable())
97
76
    {
98
77
        thread_.join();
152
131
// The stopper thread sends a stop message only once; subsequent calls
153
132
// to stop() are no-ops.
154
133
 
155
 
void StopPublisher::stop()
 
134
void StopPublisher::stop() noexcept
156
135
{
157
136
    unique_lock<mutex> lock(m_);
158
137
 
160
139
    {
161
140
        case Stopping:
162
141
        case Stopped:
 
142
        case Failed:
163
143
        {
 
144
            cond_.notify_all();
164
145
            return;  // no-op
165
146
        }
166
 
        // LCOV_EXCL_START
167
 
        case Failed:
168
 
        {
169
 
            try
170
 
            {
171
 
                rethrow_exception(ex_);
172
 
            }
173
 
            catch (...)
174
 
            {
175
 
                throw MiddlewareException("StopPublisher::stop(): cannot stop failed publisher");
176
 
            }
177
 
        }
178
 
        // LCOV_EXCL_STOP
179
147
        default:
180
148
        {
181
149
            assert(state_ == Started);
185
153
    }
186
154
}
187
155
 
 
156
void StopPublisher::wait_until_stopped() noexcept
 
157
{
 
158
    unique_lock<mutex> lock(m_);
 
159
    cond_.wait(lock, [this]{ return state_ == Stopped || state_ == Failed; });
 
160
}
 
161
 
188
162
void StopPublisher::stopper_thread() noexcept
189
163
{
190
164
    try
194
168
        assert(state_ == Starting);
195
169
 
196
170
        // Create the publishing socket.
197
 
        zmqpp::socket pub_socket(zmqpp::socket(*context_, zmqpp::socket_type::publish));
 
171
        zmqpp::socket pub_socket(*context_, zmqpp::socket_type::publish);
198
172
        // Allow time for stop message to be buffered, so close() won't discard it.
199
 
        pub_socket.set(zmqpp::socket_option::linger, 5000);
 
173
        pub_socket.set(zmqpp::socket_option::linger, 200);
200
174
        pub_socket.bind(endpoint_);
201
175
 
202
176
        // Notify that we are ready. This ensures that subscribers
215
189
        if (!stop_sent_)
216
190
        {
217
191
            stop_sent_ = true;
218
 
            pub_socket.send("");
 
192
            pub_socket.send("");  // Fails if context was terminated
219
193
            pub_socket.close();
220
194
        }
221
195
        state_ = Stopped;
 
196
        cond_.notify_all();
222
197
    }
223
198
    catch (...)
224
199
    {