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
|
/*
* Implements a simple message queue for send and receive queue.
* We could use memlist.c, but it's not efficient
* enough for this purpose (would always memmove on removing first
* element), therefore it's implemented as tail queue.
*/
#include "skype.h"
#include "msgq.h"
#include "debug.h"
void MsgQ_Init(TYP_MSGQ *q)
{
TAILQ_INIT(&q->l);
InitializeCriticalSection (&q->cs);
}
void MsgQ_Exit(TYP_MSGQ *q)
{
struct MsgQueue *ptr;
EnterCriticalSection(&q->cs);
while (ptr=q->l.tqh_first)
free(MsgQ_RemoveMsg(q, ptr));
LeaveCriticalSection(&q->cs);
DeleteCriticalSection (&q->cs);
}
BOOL MsgQ_Add(TYP_MSGQ *q, char *msg)
{
struct MsgQueue *ptr;
if (!(ptr=(struct MsgQueue*)malloc(sizeof(struct MsgQueue))))
return FALSE;
ptr->message = _strdup(msg); // Don't forget to free!
ptr->tAdded = SkypeTime(NULL);
SkypeTime(&ptr->tReceived);
EnterCriticalSection(&q->cs);
TAILQ_INSERT_TAIL(&q->l, ptr, l);
//LOG (("MsgQ_Add (%s) @%lu/%ld", msg, ptr->tReceived, ptr->tAdded));
LeaveCriticalSection(&q->cs);
return TRUE;
}
char *MsgQ_RemoveMsg(TYP_MSGQ *q, struct MsgQueue *ptr)
{
char *msg;
if (!ptr) return NULL;
TAILQ_REMOVE(&q->l, ptr, l);
msg=ptr->message;
free(ptr);
return msg;
}
char *MsgQ_Get(TYP_MSGQ *q)
{
char *msg;
EnterCriticalSection(&q->cs);
msg=MsgQ_RemoveMsg(q, q->l.tqh_first);
LeaveCriticalSection(&q->cs);
return msg;
}
int MsgQ_CollectGarbage(TYP_MSGQ *q, time_t age)
{
struct MsgQueue *ptr;
int i=0;
EnterCriticalSection(&q->cs);
ptr=q->l.tqh_first;
while (ptr)
{
if (ptr->tAdded && SkypeTime(NULL)-ptr->tAdded>age)
{
struct MsgQueue *ptr_;
LOG(("GarbageCollector throwing out message: %s", ptr->message));
ptr_=ptr;
ptr=ptr->l.tqe_next;
free(MsgQ_RemoveMsg(q, ptr_));
i++;
continue;
}
ptr=ptr->l.tqe_next;
}
LeaveCriticalSection(&q->cs);
return i;
}
|