~thomas-voss/dbus-cpp/force_gcc_4.7_and_symbols

« back to all changes in this revision

Viewing changes to include/core/dbus/impl/signal.h

  • Committer: Tarmac
  • Author(s): Pete Woods
  • Date: 2014-02-03 12:21:44 UTC
  • mfrom: (24.3.36 trunk)
  • Revision ID: tarmac-20140203122144-u15nf8142o7cplj3
Add service watcher class to allow watching DBus name ownership changes.

Approved by PS Jenkins bot, Thomas Voß.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#define CORE_DBUS_IMPL_SIGNAL_H_
20
20
 
21
21
#include <core/dbus/message_streaming_operators.h>
 
22
#include <core/dbus/object.h>
22
23
#include <core/dbus/lifetime_constrained_cache.h>
23
24
 
24
25
namespace core
136
137
 
137
138
    d->parent->signal_router.uninstall_route(
138
139
        Object::SignalKey{d->interface, d->name});
139
 
    d->parent->remove_match(d->rule);
 
140
 
 
141
    // Iterate through the unique keys in the map
 
142
    for (auto it = d->handlers.begin(); it != d->handlers.end();
 
143
            it = d->handlers.upper_bound(it->first))
 
144
    {
 
145
        const MatchRule::MatchArgs& match_args(it->first);
 
146
        d->parent->remove_match(d->rule.args(match_args));
 
147
    }
140
148
}
141
149
 
142
150
template<typename SignalDescription>
167
175
    >::type
168
176
>::connect(const Handler& h)
169
177
{
 
178
    return connect_with_match_args(h, MatchRule::MatchArgs());
 
179
}
 
180
 
 
181
template<typename SignalDescription>
 
182
inline typename Signal<
 
183
SignalDescription,
 
184
typename std::enable_if<
 
185
    is_not_void<typename SignalDescription::ArgumentType>::value,
 
186
    typename SignalDescription::ArgumentType
 
187
>::type
 
188
>::SubscriptionToken
 
189
Signal<
 
190
    SignalDescription,
 
191
    typename std::enable_if<
 
192
        is_not_void<typename SignalDescription::ArgumentType>::value,
 
193
        typename SignalDescription::ArgumentType
 
194
    >::type
 
195
>::connect_with_match_args(const Handler& h, const MatchRule::MatchArgs& match_args)
 
196
{
170
197
    std::lock_guard<std::mutex> lg(d->handlers_guard);
171
 
    return d->handlers.insert(d->handlers.end(), h);
 
198
 
 
199
    bool new_entry = (d->handlers.find(match_args) == d->handlers.cend());
 
200
 
 
201
    SubscriptionToken token = d->handlers.insert(std::make_pair(match_args, h));
 
202
 
 
203
    if (new_entry)
 
204
        d->parent->add_match(d->rule.args(match_args));
 
205
 
 
206
    return token;
172
207
}
173
208
 
174
209
template<typename SignalDescription>
182
217
>::disconnect(const SubscriptionToken& token)
183
218
{
184
219
    std::lock_guard<std::mutex> lg(d->handlers_guard);
185
 
    return d->handlers.erase(token);
 
220
 
 
221
    MatchRule::MatchArgs match_args(token->first);
 
222
    d->handlers.erase(token);
 
223
    if (d->handlers.count(match_args) == 0)
 
224
    {
 
225
        d->parent->remove_match(d->rule.args(match_args));
 
226
    }
186
227
}
 
228
 
187
229
template<typename SignalDescription>
188
230
inline const core::Signal<void>&
189
231
Signal<
251
293
            &Signal<SignalDescription, typename SignalDescription::ArgumentType>::operator(),
252
294
            this,
253
295
            std::placeholders::_1));
254
 
    d->parent->add_match(d->rule.type(Message::Type::signal).interface(interface).member(name));
255
296
}
256
297
 
257
298
template<typename SignalDescription>
267
308
    {
268
309
        msg->reader() >> d->value;
269
310
        std::lock_guard<std::mutex> lg(d->handlers_guard);
270
 
        for (auto handler : d->handlers)
 
311
        for (auto it : d->handlers)
 
312
        {
 
313
            const MatchRule::MatchArgs& match_args(it.first);
 
314
            const Handler &handler(it.second);
 
315
 
 
316
            if (!match_args.empty())
 
317
            {
 
318
                bool matched = true;
 
319
                for(const MatchRule::MatchArg& arg: match_args)
 
320
                {
 
321
                    std::size_t index = arg.first;
 
322
                    const std::string& value = arg.second;
 
323
 
 
324
                    // FIXME This code is probably bad, it starts reading the arguments
 
325
                    // from the beginning each time
 
326
                    auto reader = msg->reader();
 
327
 
 
328
                    // Wind the reader forward until we get to the desired point
 
329
                    for (std::size_t i(0); i < index && reader.type() != dbus::ArgumentType::invalid; ++i)
 
330
                        reader.pop();
 
331
 
 
332
                    if (value != reader.pop_string())
 
333
                    {
 
334
                        matched = false;
 
335
                        continue;
 
336
                    }
 
337
                }
 
338
 
 
339
                if (!matched)
 
340
                    continue;
 
341
            }
 
342
 
271
343
            handler(d->value);
 
344
        }
272
345
    }
273
346
    catch (const std::runtime_error& e)
274
347
    {