Call the requests callbacks only once per request

Message creation was like that already, but now we call the response or
error callback for the request only once. The cache does what it needs
there and returns, in the case of a successful response, the message
that will be sent to the client.



SVN revision: 73981
This commit is contained in:
Iván Briano 2012-07-17 14:22:42 +00:00
parent 7f1e95afc8
commit 30dd288a01
3 changed files with 66 additions and 31 deletions

View File

@ -189,8 +189,8 @@ typedef struct _Slave_Msg_Font_Glyphs_Loaded Slave_Msg_Font_Glyphs_Loaded;
typedef void *(*Font_Request_Msg_Create)(void *data, int *size);
typedef void (*Font_Request_Msg_Free)(void *msg, void *data);
typedef void (*Font_Request_Response)(Client *c, void *data, void *resp, unsigned int rid);
typedef void (*Font_Request_Error)(Client *c, void *data, Error_Type error, unsigned int rid);
typedef Msg_Base *(*Font_Request_Response)(void *data, void *resp, int *size);
typedef void (*Font_Request_Error)(void *data, Error_Type error);
struct _Font_Request_Funcs {
Font_Request_Msg_Create msg_create;

View File

@ -1336,13 +1336,10 @@ _font_load_request_free(void *msg, void *data __UNUSED__)
free(msg);
}
static void
_font_load_request_response(Client *client __UNUSED__, void *data, void *resp, unsigned int rid __UNUSED__)
static Msg_Font_Loaded *
_font_load_request_response(Font_Entry *fe, Slave_Msg_Font_Loaded *msg, int *size)
{
Slave_Msg_Font_Loaded *msg = resp;
Font_Entry *fe = data;
DBG("request %d answered.", rid);
Msg_Font_Loaded *resp;
if (!fe->src->ft)
fe->src->ft = msg->ftdata1;
@ -1355,20 +1352,24 @@ _font_load_request_response(Client *client __UNUSED__, void *data, void *resp, u
if (fe->request) fe->request = NULL;
_font_loaded_send(client, rid);
/* could be a function, but it's too basic and only used here */
resp = calloc(1, sizeof(*resp));
resp->base.type = CSERVE2_FONT_LOADED;
*size = sizeof(*resp);
return resp;
}
static void
_font_load_request_failed(Client *client __UNUSED__, void *data __UNUSED__, Error_Type error __UNUSED__, unsigned int rid __UNUSED__)
_font_load_request_failed(Font_Entry *fe, Error_Type error __UNUSED__)
{
Font_Entry *fe = data;
DBG("request %d error answered.", rid);
cserve2_client_error_send(client, rid, error);
Eina_List *l;
Reference *ref;
if (fe->request) fe->request = NULL;
_font_entry_reference_del(client, fe);
EINA_LIST_FOREACH(fe->base.references, l, ref)
_font_entry_reference_del(ref->client, fe);
}
static Font_Request_Funcs _font_load_funcs = {
@ -1447,8 +1448,8 @@ _glyphs_group_create(Glyphs_Request *req)
return groups;
}
static void
_glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
static Msg_Font_Glyphs_Loaded *
_glyphs_loaded_msg_create(Glyphs_Request *req, int *resp_size)
{
Msg_Font_Glyphs_Loaded msg;
unsigned int size;
@ -1460,7 +1461,6 @@ _glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
Glyphs_Group *iter;
memset(&msg, 0, sizeof(msg));
msg.base.rid = rid;
msg.base.type = CSERVE2_FONT_GLYPHS_LOADED;
answers = _glyphs_group_create(req);
@ -1536,6 +1536,20 @@ _glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
free(iter);
}
*resp_size = size;
return (Msg_Font_Glyphs_Loaded *)resp;
}
static void
_glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
{
Msg_Font_Glyphs_Loaded *resp;
int size;
resp = _glyphs_loaded_msg_create(req, &size);
resp->base.rid = rid;
cserve2_client_send(req->client, &size, sizeof(size));
cserve2_client_send(req->client, resp, size);
@ -1695,11 +1709,9 @@ _glyphs_load_request_free(void *msg, void *data)
free(msg);
}
static void
_glyphs_load_request_response(Client *client __UNUSED__, void *data, void *resp, unsigned int rid)
static Msg_Font_Glyphs_Loaded *
_glyphs_load_request_response(Glyphs_Request *req, Slave_Msg_Font_Glyphs_Loaded *msg, int *size)
{
Glyphs_Request *req = data;
Slave_Msg_Font_Glyphs_Loaded *msg = resp;
Font_Entry *fe = req->fe;
Font_Cache *fc = NULL;
unsigned int i = 0;
@ -1762,12 +1774,13 @@ _glyphs_load_request_response(Client *client __UNUSED__, void *data, void *resp,
fe->gl_slave_time += msg->gl_slave_time;
#endif
_glyphs_loaded_send(req, rid);
_font_shm_lru_flush();
return _glyphs_loaded_msg_create(req, size);
}
static void
_glyphs_load_request_failed(Client *client __UNUSED__, void *data __UNUSED__, Error_Type error __UNUSED__, unsigned int rid __UNUSED__)
_glyphs_load_request_failed(void *data __UNUSED__, Error_Type error __UNUSED__)
{
}

View File

@ -192,14 +192,16 @@ cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err)
Eina_List *l, *l_next;
Waiter *w;
if (req->funcs && req->funcs->error)
req->funcs->error(req->data, err);
EINA_LIST_FOREACH_SAFE(req->waiters, l, l_next, w)
{
if (w->client->id == client->id)
{
DBG("Removing answer from waiter client: %d, rid: %d",
client->id, w->rid);
if (req->funcs && req->funcs->error)
req->funcs->error(client, req->data, err, w->rid);
cserve2_client_error_send(w->client, w->rid, err);
req->waiters = eina_list_remove_list(req->waiters, l);
free(w);
}
@ -232,12 +234,14 @@ cserve2_request_cancel_all(Font_Request *req, Error_Type err)
DBG("Removing all answers.");
if (req->funcs && req->funcs->error)
req->funcs->error(req->data, err);
EINA_LIST_FREE(req->waiters, w)
{
DBG("Removing answer from waiter client: %d, rid: %d",
w->client->id, w->rid);
if (req->funcs && req->funcs->error)
req->funcs->error(w->client, req->data, err, w->rid);
cserve2_client_error_send(w->client, w->rid, err);
free(w);
}
@ -275,9 +279,11 @@ _cserve2_request_failed(Font_Request *req, Error_Type type)
{
Waiter *w;
req->funcs->error(req->data, type);
EINA_LIST_FREE(req->waiters, w)
{
req->funcs->error(w->client, req->data, type, w->rid);
cserve2_client_error_send(w->client, w->rid, type);
free(w);
}
@ -297,19 +303,35 @@ _slave_read_cb(Slave *s __UNUSED__, Slave_Command cmd, void *msg, void *data)
Font_Request *dep, *req = sw->data;
Eina_List **working, **idle;
Waiter *w;
Msg_Base *resp = NULL;
int resp_size;
if (cmd == ERROR)
{
Error_Type *err = msg;
req->funcs->error(req->data, *err);
}
else
resp = req->funcs->response(req->data, msg, &resp_size);
EINA_LIST_FREE(req->waiters, w)
{
if (cmd == ERROR)
{
Error_Type *err = msg;
req->funcs->error(w->client, req->data, *err, w->rid);
cserve2_client_error_send(w->client, w->rid, *err);
}
else
req->funcs->response(w->client, req->data, msg, w->rid);
{
resp->rid = w->rid;
cserve2_client_send(w->client, &resp_size, sizeof(resp_size));
cserve2_client_send(w->client, resp, resp_size);
}
free(w);
}
free(resp);
req->funcs->msg_free(req->msg, req->data);
// FIXME: We shouldn't free this message directly, it must be freed by a
// callback.