1/*
2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/p2p/client/socketmonitor.h"
12
13#include "webrtc/base/common.h"
14
15namespace cricket {
16
17enum {
18  MSG_MONITOR_POLL,
19  MSG_MONITOR_START,
20  MSG_MONITOR_STOP,
21  MSG_MONITOR_SIGNAL
22};
23
24ConnectionMonitor::ConnectionMonitor(ConnectionStatsGetter* stats_getter,
25                                     rtc::Thread* worker_thread,
26                                     rtc::Thread* monitoring_thread) {
27  stats_getter_ = stats_getter;
28  worker_thread_ = worker_thread;
29  monitoring_thread_ = monitoring_thread;
30  monitoring_ = false;
31}
32
33ConnectionMonitor::~ConnectionMonitor() {
34  worker_thread_->Clear(this);
35  monitoring_thread_->Clear(this);
36}
37
38void ConnectionMonitor::Start(int milliseconds) {
39  rate_ = milliseconds;
40  if (rate_ < 250)
41    rate_ = 250;
42  worker_thread_->Post(this, MSG_MONITOR_START);
43}
44
45void ConnectionMonitor::Stop() {
46  worker_thread_->Post(this, MSG_MONITOR_STOP);
47}
48
49void ConnectionMonitor::OnMessage(rtc::Message *message) {
50  rtc::CritScope cs(&crit_);
51  switch (message->message_id) {
52    case MSG_MONITOR_START:
53      ASSERT(rtc::Thread::Current() == worker_thread_);
54      if (!monitoring_) {
55        monitoring_ = true;
56        PollConnectionStats_w();
57      }
58      break;
59
60    case MSG_MONITOR_STOP:
61      ASSERT(rtc::Thread::Current() == worker_thread_);
62      if (monitoring_) {
63        monitoring_ = false;
64        worker_thread_->Clear(this);
65      }
66      break;
67
68    case MSG_MONITOR_POLL:
69      ASSERT(rtc::Thread::Current() == worker_thread_);
70      PollConnectionStats_w();
71      break;
72
73    case MSG_MONITOR_SIGNAL: {
74      ASSERT(rtc::Thread::Current() == monitoring_thread_);
75      std::vector<ConnectionInfo> infos = connection_infos_;
76      crit_.Leave();
77      SignalUpdate(this, infos);
78      crit_.Enter();
79      break;
80    }
81  }
82}
83
84void ConnectionMonitor::PollConnectionStats_w() {
85  ASSERT(rtc::Thread::Current() == worker_thread_);
86  rtc::CritScope cs(&crit_);
87
88  // Gather connection infos
89  stats_getter_->GetConnectionStats(&connection_infos_);
90
91  // Signal the monitoring thread, start another poll timer
92  monitoring_thread_->Post(this, MSG_MONITOR_SIGNAL);
93  worker_thread_->PostDelayed(rate_, this, MSG_MONITOR_POLL);
94}
95
96}  // namespace cricket
97