try out a queue API to notify "listeners" of the session
I was always unsure on what to do: a callback or a simple queue for dc_event_t. But since we already have dc_event_t (and ref counting) this seemed like the best solution.
This commit is contained in:
@@ -83,6 +83,23 @@ dc_account_t dc_session_me(dc_session_t s);
|
||||
*/
|
||||
dc_api_t dc_session_api(dc_session_t s);
|
||||
|
||||
/**
|
||||
* Queue API. If you enable queuing the session will keep the events from the
|
||||
* web socket around for you to handle. Please note that all internal states
|
||||
* will already have been upgraded, and changed once you pull these events
|
||||
* from the queue. Also note that if you enable queuing but never pull these
|
||||
* events from the queue they will pile up, and use a lot of memory.
|
||||
*
|
||||
* If you disable queuing then the queue is deleted, and no more events are
|
||||
* placed into the queue.
|
||||
*
|
||||
* dc_session_pop_event() will remove an event from the queue for you to handle.
|
||||
* You will have to call dc_unref() on it yourself to cleanup any internal data
|
||||
* of the event. It will return NULL if no event is in the queue.
|
||||
*/
|
||||
void dc_session_enable_queue(dc_session_t s, bool enable);
|
||||
dc_event_t dc_session_pop_event(dc_session_t s);
|
||||
|
||||
/**
|
||||
* access to the internal account cache
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,9 @@ struct dc_session_
|
||||
GHashTable *accounts;
|
||||
GHashTable *channels;
|
||||
GHashTable *guilds;
|
||||
|
||||
GQueue *queue;
|
||||
pthread_mutex_t *mutex;
|
||||
};
|
||||
|
||||
/* event handlers
|
||||
@@ -50,6 +53,16 @@ static void dc_session_free(dc_session_t s)
|
||||
{
|
||||
return_if_true(s == NULL,);
|
||||
|
||||
if (s->mutex != NULL) {
|
||||
pthread_mutex_lock(s->mutex);
|
||||
if (s->queue != NULL) {
|
||||
g_queue_free_full(s->queue, (GDestroyNotify)dc_unref);
|
||||
s->queue = NULL;
|
||||
}
|
||||
pthread_mutex_destroy(s->mutex);
|
||||
s->mutex = NULL;
|
||||
}
|
||||
|
||||
if (s->accounts != NULL) {
|
||||
g_hash_table_unref(s->accounts);
|
||||
s->accounts = NULL;
|
||||
@@ -189,6 +202,14 @@ static void dc_session_handler(dc_gateway_t gw, dc_event_t e, void *p)
|
||||
h(s, e);
|
||||
}
|
||||
|
||||
/* add to queue, if the queue is enabled
|
||||
*/
|
||||
pthread_mutex_lock(s->mutex);
|
||||
if (s->queue != NULL) {
|
||||
g_queue_push_tail(s->queue, dc_ref(e));
|
||||
}
|
||||
pthread_mutex_unlock(s->mutex);
|
||||
|
||||
#ifdef DEBUG
|
||||
char *str = NULL;
|
||||
str = json_dumps(dc_event_payload(e), 0);
|
||||
@@ -223,6 +244,9 @@ dc_session_t dc_session_new(dc_loop_t loop)
|
||||
);
|
||||
goto_if_true(s->channels == NULL, error);
|
||||
|
||||
s->mutex = calloc(1, sizeof(pthread_mutex_t));
|
||||
goto_if_true(s->mutex == NULL, error);
|
||||
|
||||
s->loop = dc_ref(loop);
|
||||
|
||||
s->api = dc_api_new();
|
||||
@@ -337,6 +361,38 @@ bool dc_session_equal_me(dc_session_t s, dc_account_t a)
|
||||
);
|
||||
}
|
||||
|
||||
void dc_session_enable_queue(dc_session_t s, bool enable)
|
||||
{
|
||||
return_if_true(s == NULL,);
|
||||
|
||||
return_if_true(enable == true && s->queue != NULL,);
|
||||
return_if_true(enable == false && s->queue == NULL,);
|
||||
|
||||
if (enable) {
|
||||
pthread_mutex_lock(s->mutex);
|
||||
s->queue = g_queue_new();
|
||||
pthread_mutex_unlock(s->mutex);
|
||||
} else {
|
||||
pthread_mutex_lock(s->mutex);
|
||||
g_queue_free_full(s->queue, (GDestroyNotify)dc_unref);
|
||||
s->queue = NULL;
|
||||
pthread_mutex_unlock(s->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
dc_event_t dc_session_pop_event(dc_session_t s)
|
||||
{
|
||||
return_if_true(s == NULL || s->queue == NULL, NULL);
|
||||
|
||||
dc_event_t e = NULL;
|
||||
|
||||
pthread_mutex_lock(s->mutex);
|
||||
e = g_queue_pop_head(s->queue);
|
||||
pthread_mutex_unlock(s->mutex);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool dc_session_equal_me_fullname(dc_session_t s, char const *a)
|
||||
{
|
||||
return_if_true(s == NULL || s->login == NULL || a == NULL, false);
|
||||
|
||||
Reference in New Issue
Block a user