summaryrefslogtreecommitdiff
path: root/project2/sessionShm.cpp
blob: e4c9d161b8dd898f24c4f6f7fa75302b599583fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "sessionShm.h"
#include <syslog.h>
#include <set>
#include <boost/uuid/uuid.hpp>
#include <boost/foreach.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid_io.hpp>

using namespace boost::interprocess;
using namespace boost::uuids;
class SessionShmData {
	public:
		typedef boost::interprocess::string SKey;
		typedef boost::interprocess::string SValue;

		typedef std::pair<const SKey, SValue> SValueType;
		typedef boost::interprocess::allocator<SValueType, boost::interprocess::managed_mapped_file::segment_manager> AllocatorValueType;
		typedef boost::interprocess::map<SKey, SValue, std::less<SKey>, AllocatorValueType> SessionValues;

		SessionShmData();
		~SessionShmData();

		SessionValues svs;
		time_t expiryTime;

		static boost::interprocess::managed_mapped_file shm;
		friend class SessionContainerShm;
};

const char * shmFile = "/tmp/project2.sessions";

boost::interprocess::managed_mapped_file SessionShmData::shm(open_or_create, shmFile, 1024 * 1024);

SessionContainerShm::SessionContainerShm()
{
}

SessionContainerShm::~SessionContainerShm()
{
}

void
SessionContainerShm::CleanUp()
{
	std::set<std::string> toDelete;
	for (managed_mapped_file::const_named_iterator i = SessionShmData::shm.named_begin();
			i != SessionShmData::shm.named_end(); i++) {
		const SessionShmData * s = static_cast<const SessionShmData *>(i->value());
		if (s) {
			if (s->expiryTime < time(NULL)) {
				toDelete.insert(i->name());
			}
		}
	}
	for(std::set<std::string>::const_iterator s = toDelete.begin(); s != toDelete.end(); s++) {
		SessionShmData::shm.destroy<const SessionShmData>(s->c_str());
	}
}

SessionPtr
SessionContainerShm::getSession(boost::uuids::uuid & sid)
{
	if (sid.is_nil()) {
		sid = boost::uuids::random_generator()();
	}
	return SessionPtr(new SessionShm(
			SessionShmData::shm.find_or_construct<SessionShmData>(boost::lexical_cast<std::string>(sid).c_str())()));
}

SessionShm::SessionShm(SessionShmData * d) : data(d)
{
}

SessionShm::~SessionShm()
{
}

void
SessionShm::ExpiryTime(time_t t)
{
	data->expiryTime = t;
}

time_t
SessionShm::ExpiryTime() const
{
	return data->expiryTime;
}

SessionShmData::SessionShmData() :
	svs(std::less<SKey>(), AllocatorValueType(shm.get_segment_manager()))
{
}

SessionShmData::~SessionShmData()
{
}

Glib::ustring
SessionShm::GetValue(const Glib::ustring & name) const
{
	SessionShmData::SessionValues::const_iterator i = data->svs.find(name.c_str());
	if (i == data->svs.end()) {
		throw Session::VariableNotFound();
	}
	return i->second.c_str();
}

void
SessionShm::SetValue(const Glib::ustring & name, const Glib::ustring & value)
{
	data->svs.erase(name.c_str());
	data->svs.insert(std::pair<SessionShmData::SKey, SessionShmData::SValue>(name.c_str(), value.c_str()));
}

void
SessionShm::ClearValue(const Glib::ustring & name)
{
	data->svs.erase(name.c_str());
}

Session::Values
SessionShm::GetValuesCopy() const
{
	Values v;
	BOOST_FOREACH(SessionShmData::SessionValues::value_type kvp, data->svs) {
		v[kvp.first.c_str()] = kvp.second.c_str();
	}
	return v;
}