static void send_queue_item_free(angel_connection_send_item_t *i) { if (!i) return; switch (i->type) { case ANGEL_CONNECTION_ITEM_GSTRING: g_string_free(i->value.string.buf, TRUE); break; case ANGEL_CONNECTION_ITEM_FDS: close_fd_array(i->value.fds.fds); g_array_free(i->value.fds.fds, TRUE); break; } g_slice_free(angel_connection_send_item_t, i); }
static void send_queue_clean(GQueue *queue) { angel_connection_send_item_t *i; while (NULL != (i = g_queue_peek_head(queue))) { switch (i->type) { case ANGEL_CONNECTION_ITEM_GSTRING: if (i->value.string.pos < i->value.string.buf->len) return; g_string_free(i->value.string.buf, TRUE); break; case ANGEL_CONNECTION_ITEM_FDS: if (i->value.fds.pos < i->value.fds.fds->len) return; close_fd_array(i->value.fds.fds); g_array_free(i->value.fds.fds, TRUE); break; } g_queue_pop_head(queue); g_slice_free(angel_connection_send_item_t, i); } }
static gboolean angel_dispatch(liAngelConnection *acon, GError **err) { gint32 id = acon->parse.id, type = acon->parse.type; liAngelCall *call = NULL; liAngelCallCB cb = NULL; gpointer ctx = NULL; switch (type) { case ANGEL_CALL_SEND_SIMPLE: if (-1 != id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i, should be -1 for simple call", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_CALL: if (-1 == id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: -1, should be >= 0 for call"); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_RESULT: g_mutex_lock(acon->mutex); if (!li_idlist_is_used(acon->call_id_list, id)) { g_mutex_unlock(acon->mutex); g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } li_idlist_put(acon->call_id_list, id); if (type == ANGEL_CALL_SEND_RESULT && (guint) id < acon->call_table->len) { call = (liAngelCall*) g_ptr_array_index(acon->call_table, id); g_ptr_array_index(acon->call_table, id) = NULL; if (call) { call->id = -1; ev_timer_stop(acon->loop, &call->timeout_watcher); ctx = call->context; if (NULL == (cb = call->callback)) { g_slice_free(liAngelCall, call); } } } g_mutex_unlock(acon->mutex); if (cb) { cb(call, ctx, FALSE, acon->parse.error, acon->parse.data, acon->parse.fds); } close_fd_array(acon->parse.fds); break; default: g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid type: %i", (gint) type); close_fd_array(acon->parse.fds); return FALSE; } return TRUE; }
static gboolean angel_dispatch(liAngelConnection *acon, GError **err) { gint32 id = acon->parse.id, type = acon->parse.type; liAngelCall *call; switch (type) { case ANGEL_CALL_SEND_SIMPLE: if (-1 != id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i, should be -1 for simple call", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_CALL: if (-1 == id) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: -1, should be >= 0 for call"); close_fd_array(acon->parse.fds); return FALSE; } if (acon->parse.error->len > 0 || acon->parse.fds->len > 0) { g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Wrong data in call"); close_fd_array(acon->parse.fds); return FALSE; } acon->recv_call(acon, GSTR_LEN(acon->parse.mod), GSTR_LEN(acon->parse.action), id, acon->parse.data); break; case ANGEL_CALL_SEND_RESULT: g_mutex_lock(acon->mutex); if (!li_idlist_is_used(acon->call_id_list, id)) { g_mutex_unlock(acon->mutex); g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid id: %i", (gint) id); close_fd_array(acon->parse.fds); return FALSE; } li_idlist_put(acon->call_id_list, id); call = NULL; if ((guint) id < acon->call_table->len) { call = (liAngelCall*) g_ptr_array_index(acon->call_table, id); g_ptr_array_index(acon->call_table, id) = NULL; } if (NULL != call) { call->id = -1; call->result.error = acon->parse.error; call->result.data = acon->parse.data; call->result.fds = acon->parse.fds; acon->parse.error = g_string_sized_new(0); acon->parse.data = g_string_sized_new(0); acon->parse.fds = g_array_new(FALSE, FALSE, sizeof(int)); li_event_async_send(&call->result_watcher); } else { /* timeout - call is gone */ g_string_truncate(acon->parse.error, 0); g_string_truncate(acon->parse.data, 0); close_fd_array(acon->parse.fds); } g_mutex_unlock(acon->mutex); break; default: g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA, "Invalid type: %i", (gint) type); close_fd_array(acon->parse.fds); return FALSE; } return TRUE; }