/
SessionManager.c
99 lines (76 loc) · 1.66 KB
/
SessionManager.c
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
#import "SessionManager.h"
#define self SessionManager
/* TODO Use a more efficient data structure. */
Singleton(self);
SingletonDestructor(self);
rsdef(self, New) {
return (self) {
.sessions = Sessions_New(1024),
.backend = NULL
};
}
static def(void, DestroyItem, SessionItem *item) {
String_Destroy(&item->id);
call(DestroySession, item->sess);
}
def(void, Destroy) {
each(sess, this->sessions) {
call(DestroyItem, sess);
}
Sessions_Free(this->sessions);
}
def(void, SetBackend, BackendSessionInterface *backend) {
this->backend = backend;
}
def(Session *, CreateSession) {
if (this->backend != NULL) {
Session *sess = Session_New(this->backend->size);
this->backend->init(Session_GetData(sess));
return sess;
}
return Session_New(0);
}
def(void, DestroySession, Session *sess) {
if (this->backend != NULL) {
this->backend->destroy(Session_GetData(sess));
}
Session_Destroy(sess);
}
/* TODO Use a better algorithm. */
def(String, GetUniqueId) {
Time_UnixEpoch time = Time_GetCurrent();
return Integer_ToString((u32) time.sec);
}
def(RdString, Register, Session *sess) {
sess->ref = true;
SessionItem item = {
.id = call(GetUniqueId),
.sess = sess
};
each(sess, this->sessions) {
if (sess == NULL) {
*sess = item;
goto out;
}
}
Sessions_Push(&this->sessions, item);
out:
return item.id.rd;
}
def(Session *, Resolve, RdString id) {
each(sess, this->sessions) {
if (String_Equals(sess->id.rd, id)) {
return sess->sess;
}
}
return NULL;
}
def(void, Unlink, RdString id) {
each(sess, this->sessions) {
if (String_Equals(sess->id.rd, id)) {
call(DestroyItem, sess);
sess->sess = NULL;
break;
}
}
}