diff options
Diffstat (limited to 'content/content.c')
-rw-r--r-- | content/content.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/content/content.c b/content/content.c index 052a35fe7..7dd85a668 100644 --- a/content/content.c +++ b/content/content.c @@ -392,7 +392,16 @@ bool content_set_type(struct content *c, content_type type, callback = c->user_list->next->next->callback; p1 = c->user_list->next->next->p1; p2 = c->user_list->next->next->p2; - content_add_user(clone, callback, p1, p2); + if (!content_add_user(clone, callback, p1, p2)) { + c->type = CONTENT_UNKNOWN; + c->status = CONTENT_STATUS_ERROR; + content_destroy(clone); + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, + msg_data); + warn_user("NoMemory", 0); + return false; + } content_remove_user(c, callback, p1, p2); content_broadcast(clone, CONTENT_MSG_NEWPTR, msg_data); fetchcache_go(clone, 0, callback, p1, p2, 0, 0, false); @@ -706,24 +715,39 @@ bool content_redraw(struct content *c, int x, int y, /** * Register a user for callbacks. * + * \param c The content to register + * \param callback The callback function + * \param p1, p2 Callback private data + * \return true on success, false otherwise and error broadcast to users + * * The callback will be called with p1 and p2 when content_broadcast() is * called with the content. */ -void content_add_user(struct content *c, +bool content_add_user(struct content *c, void (*callback)(content_msg msg, struct content *c, void *p1, void *p2, union content_msg_data data), void *p1, void *p2) { struct content_user *user; + union content_msg_data msg_data; + LOG(("content %s, user %p %p %p", c->url, callback, p1, p2)); - user = xcalloc(1, sizeof(*user)); + user = calloc(1, sizeof(*user)); + if (!user) { + c->status = CONTENT_STATUS_ERROR; + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } user->callback = callback; user->p1 = p1; user->p2 = p2; user->stop = false; user->next = c->user_list->next; c->user_list->next = user; + + return true; } |