~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to src/client/rpc/stream_socket_transport.cpp

  • Committer: Package Import Robot
  • Author(s): CI Train Bot
  • Date: 2015-05-12 13:12:55 UTC
  • mto: This revision was merged to the branch mainline in revision 96.
  • Revision ID: package-import@ubuntu.com-20150512131255-y7z12i8n4pbvo70x
Tags: upstream-0.13.0+15.10.20150512
ImportĀ upstreamĀ versionĀ 0.13.0+15.10.20150512

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
namespace mclr = mir::client::rpc;
36
36
namespace md = mir::dispatch;
37
37
 
 
38
void mclr::TransportObservers::on_data_available()
 
39
{
 
40
    for_each([](auto observer) { observer->on_data_available(); });
 
41
}
 
42
 
 
43
void mclr::TransportObservers::on_disconnected()
 
44
{
 
45
    for_each([](auto observer) { observer->on_disconnected(); });
 
46
}
 
47
 
38
48
mclr::StreamSocketTransport::StreamSocketTransport(mir::Fd const& fd)
39
49
    : socket_fd{fd}
40
50
{
47
57
 
48
58
void mclr::StreamSocketTransport::register_observer(std::shared_ptr<Observer> const& observer)
49
59
{
50
 
    std::lock_guard<decltype(observer_mutex)> lock(observer_mutex);
51
 
    observers.push_back(observer);
 
60
    observers.add(observer);
 
61
}
 
62
 
 
63
void mclr::StreamSocketTransport::unregister_observer(std::shared_ptr<Observer> const& observer)
 
64
{
 
65
    observers.remove(observer);
52
66
}
53
67
 
54
68
void mclr::StreamSocketTransport::receive_data(void* buffer, size_t bytes_requested)
86
100
 
87
101
        if (result == 0)
88
102
        {
89
 
            notify_disconnected();
 
103
            observers.on_disconnected();
90
104
            BOOST_THROW_EXCEPTION(std::runtime_error("Failed to read message from server: server has shutdown"));
91
105
        }
92
106
        if (result < 0)
97
111
            }
98
112
            if (errno == EPIPE)
99
113
            {
100
 
                notify_disconnected();
 
114
                observers.on_disconnected();
101
115
                BOOST_THROW_EXCEPTION(
102
116
                            boost::enable_error_info(
103
117
                                socket_disconnected_error("Failed to read message from server"))
124
138
}
125
139
catch (socket_disconnected_error &e)
126
140
{
127
 
    notify_disconnected();
 
141
    observers.on_disconnected();
128
142
    throw e;
129
143
}
130
144
 
148
162
            }
149
163
            if (errno == EPIPE)
150
164
            {
151
 
                notify_disconnected();
 
165
                observers.on_disconnected();
152
166
                BOOST_THROW_EXCEPTION(
153
167
                            boost::enable_error_info(socket_disconnected_error("Failed to send message to server"))
154
168
                            << boost::errinfo_errno(errno));
182
196
            int dummy;
183
197
            if (recv(socket_fd, &dummy, sizeof(dummy), MSG_PEEK | MSG_NOSIGNAL) > 0)
184
198
            {
185
 
                notify_data_available();
 
199
                observers.on_data_available();
186
200
                return true;
187
201
            }
188
202
        }
189
 
        notify_disconnected();
 
203
        observers.on_disconnected();
190
204
        return false;
191
205
    }
192
206
    else if (events & md::FdEvent::readable)
193
207
    {
194
 
        notify_data_available();
 
208
        observers.on_data_available();
195
209
    }
196
210
    return true;
197
211
}
220
234
    }
221
235
    return fd;
222
236
}
223
 
 
224
 
void mclr::StreamSocketTransport::notify_data_available()
225
 
{
226
 
    // TODO: If copying the observers turns out to be slow, replace with
227
 
    // an RCUish data type; this is a read-mostly, write infrequently structure.
228
 
    decltype(observers) observer_copy;
229
 
    {
230
 
        std::lock_guard<decltype(observer_mutex)> lock(observer_mutex);
231
 
        observer_copy = observers;
232
 
    }
233
 
    for (auto& observer : observer_copy)
234
 
    {
235
 
        observer->on_data_available();
236
 
    }
237
 
}
238
 
 
239
 
void mclr::StreamSocketTransport::notify_disconnected()
240
 
{
241
 
    decltype(observers) observer_copy;
242
 
    {
243
 
        std::lock_guard<decltype(observer_mutex)> lock(observer_mutex);
244
 
        observer_copy = observers;
245
 
    }
246
 
    for (auto& observer : observer_copy)
247
 
    {
248
 
        observer->on_disconnected();
249
 
    }
250
 
}