blob: e5d99980ced9c880a648cc9f929841a4b3f41067 [file] [log] [blame]
Zhenkai Zhue4dc4d82013-01-23 13:17:08 -08001#include "ccnx-discovery.h"
2#include "simple-interval-generator.h"
3#include "task.h"
4#include "periodic-task.h"
5#include <sstream>
6#include <boost/make_shared.hpp>
7#include <boost/bind.hpp>
8
9using namespace Ccnx;
10using namespace std;
11
12const string
13TaggedFunction::CHAR_SET = string("abcdefghijklmnopqtrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
14
15TaggedFunction::TaggedFunction(const Callback &callback, const string &tag)
16 : m_callback(callback)
17 , m_tag(tag)
18{
19}
20
21string
22TaggedFunction::GetRandomTag()
23{
24 //boost::random::random_device rng;
25 boost::random::uniform_int_distribution<> dist(0, CHAR_SET.size() - 1);
26 ostringstream oss;
27 for (int i = 0; i < DEFAULT_TAG_SIZE; i++)
28 {
29 //oss << CHAR_SET[dist(rng)];
30 }
31 return oss.str();
32}
33
34void
35TaggedFunction::operator()(const Name &name)
36{
37 if (!m_callback.empty())
38 {
39 m_callback(name);
40 }
41}
42
43const double
44CcnxDiscovery::INTERVAL = 15.0;
45
46CcnxDiscovery *
47CcnxDiscovery::instance = NULL;
48
49boost::mutex
50CcnxDiscovery::mutex;
51
52CcnxDiscovery::CcnxDiscovery()
53 : m_scheduler(new Scheduler())
54 , m_localPrefix("/")
55{
56 m_scheduler->start();
57 IntervalGeneratorPtr generator = boost::make_shared<SimpleIntervalGenerator>(INTERVAL);
58 TaskPtr task = boost::make_shared<PeriodicTask>(boost::bind(&CcnxDiscovery::poll, this), "Local-Prefix-Check", m_scheduler, generator);
59 m_scheduler->addTask(task);
60}
61
62CcnxDiscovery::~CcnxDiscovery()
63{
64 m_scheduler->shutdown();
65}
66
67void
68CcnxDiscovery::addCallback(const TaggedFunction &callback)
69{
70 m_callbacks.push_back(callback);
71}
72
73int
74CcnxDiscovery::deleteCallback(const TaggedFunction &callback)
75{
76 List::iterator it = m_callbacks.begin();
77 while (it != m_callbacks.end())
78 {
79 if ((*it) == callback)
80 {
81 it = m_callbacks.erase(it);
82 }
83 else
84 {
85 ++it;
86 }
87 }
88 return m_callbacks.size();
89}
90
91void
92CcnxDiscovery::poll()
93{
94 Name localPrefix = CcnxWrapper::getLocalPrefix();
95 if (localPrefix != m_localPrefix)
96 {
97 Lock lock(mutex);
98 for (List::iterator it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
99 {
100 (*it)(localPrefix);
101 }
102 m_localPrefix = localPrefix;
103 }
104}
105
106void
107CcnxDiscovery::registerCallback(const TaggedFunction &callback)
108{
109 Lock lock(mutex);
110 if (instance == NULL)
111 {
112 instance = new CcnxDiscovery();
113 }
114
115 instance->addCallback(callback);
116}
117
118void
119CcnxDiscovery::deregisterCallback(const TaggedFunction &callback)
120{
121 Lock lock(mutex);
122 if (instance == NULL)
123 {
124 cerr << "CcnxDiscovery::deregisterCallback called without instance" << endl;
125 }
126 else
127 {
128 int size = instance->deleteCallback(callback);
129 if (size == 0)
130 {
131 delete instance;
132 instance = NULL;
133 }
134 }
135}
136