diff options
Diffstat (limited to 'protocols/Skype/msgq.c')
-rw-r--r-- | protocols/Skype/msgq.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/protocols/Skype/msgq.c b/protocols/Skype/msgq.c new file mode 100644 index 0000000000..48790e1c29 --- /dev/null +++ b/protocols/Skype/msgq.c @@ -0,0 +1,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;
+}
|