evas/cserve2: Reconnect to cserve2 in case of server crash

Try to reconnect to cserve2 if the socket connection was lost.
Resend some messages if necessary.

Images reload seems to be working.
Actually, the images don't change over time, so the clients just
keep the previous references to their images.

FONT RELOAD IS NOT WORKING:
- Crashes
- Invalid glyph data
- Infinite loop in _glyph_map_remap_check()

Root cause:
When new glyphs are requested from the server, they are added to
the mempool. So it is necessary to remap the font.
Unfortunately, in case of server reboot, we did not keep the mempool
so the old glyphs that were not requested again will not be valid.
This commit is contained in:
Jean-Philippe Andre 2013-10-02 20:23:14 +09:00
parent 3889feca24
commit e74cac57e4
7 changed files with 380 additions and 109 deletions

View File

@ -2769,6 +2769,7 @@ try_again:
0, &unscaled, buf, sizeof(buf));
if (!orig_entry) return -1;
image_id = orig_entry->base.id;
orig_data = _image_data_find(ENTRYID(orig_entry));
orig_data->unused = EINA_TRUE;
fentry = _file_entry_find(orig_data->file_id);
@ -2914,12 +2915,17 @@ cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned
{
ERR("Can't load: client %d has no image id %d",
client->id, client_image_id);
cserve2_client_error_send(client, rid, CSERVE2_NOT_LOADED);
return;
}
ientry = (Image_Entry *) ref->entry;
idata = _image_data_find(ENTRYID(ientry));
if (!idata) return;
if (!idata)
{
cserve2_client_error_send(client, rid, CSERVE2_INVALID_CACHE);
return;
}
fd = _file_data_find(idata->file_id);
if (!fd || fd->invalid)
@ -3120,6 +3126,7 @@ cserve2_cache_font_glyphs_load(Client *client, const char *source,
if (!req)
{
free(glyphs);
cserve2_client_error_send(client, rid, CSERVE2_NOT_LOADED);
return -1;
}
@ -3153,6 +3160,7 @@ cserve2_cache_font_glyphs_used(Client *client, const char *source,
if (!req)
{
free(glyphs);
cserve2_client_error_send(client, rid, CSERVE2_NOT_LOADED);
return 0;
}

View File

@ -997,10 +997,10 @@ evas_cache2_image_load_data(Image_Entry *ie)
error = evas_cserve2_image_load_data_wait(ie);
RGBA_Image *im = (RGBA_Image *)ie;
DBG("try cserve2 image data '%s' '%s' loaded!",
ie->file, ie->key ? ie->key : "");
if ((error == CSERVE2_NONE) && im->image.data)
{
DBG("try cserve2 image data '%s' '%s' loaded!",
ie->file, ie->key ? ie->key : "");
error = EVAS_LOAD_ERROR_NONE;
}
else

View File

@ -304,7 +304,12 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
fg = evas_common_font_int_cache_glyph_get(fi, idx);
if (!fg) continue;
if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
if (!fg->glyph_out)
if (!evas_common_font_int_cache_glyph_render(fg))
{
fg = NULL;
goto error;
}
glyph = eina_inarray_grow(glyphs, 1);
if (!glyph) goto error;

View File

@ -548,8 +548,14 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg)
fg->glyph_out = evas_cserve2_font_glyph_bitmap_get(fi->cs2_handler,
fg->index,
fg->fi->hinting);
if (fg->glyph_out)
return EINA_TRUE;
if (!fg->glyph_out)
{
if (!fi->fash) fi->fash = _fash_gl_new();
if (fi->fash) _fash_gl_add(fi->fash, fg->index, (void *)(-1));
free(fg);
return EINA_FALSE;
}
return EINA_TRUE;
}
#endif

View File

@ -39,6 +39,7 @@ typedef enum {
CSERVE2_LOADER_DIED,
CSERVE2_LOADER_EXEC_ERR,
CSERVE2_INVALID_CACHE, // invalid cserve cache entry
CSERVE2_NOT_LOADED,
CSERVE2_FILE_CHANGED,
CSERVE2_REQUEST_CANCEL
} Error_Type;

View File

@ -21,7 +21,9 @@
#define USE_SHARED_INDEX 1
#define SHARED_INDEX_ADD_TO_HASH 1
#define HKEY_LOAD_OPTS_STR_LEN 215
typedef void (*Op_Callback)(void *data, const void *msg, int size);
#define SPECIAL_RID_INDEX_LIST ((unsigned int) 0xFFFFFF42)
typedef Eina_Bool (*Op_Callback)(void *data, const void *msg, int size);
static const Evas_Image_Load_Opts empty_lo = {
{ 0, 0, 0, 0 },
@ -47,8 +49,8 @@ struct _File_Entry {
};
struct _Client_Request {
Message_Type type;
unsigned int rid;
Msg_Base *msg;
int msg_size;
Op_Callback cb;
void *data;
};
@ -77,6 +79,11 @@ static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie);
static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe);
static Eina_Bool _shared_index_remap_check(Shared_Index *si, int elemsize);
static Eina_Bool _server_dispatch_until(unsigned int rid);
unsigned int _image_load_server_send(Image_Entry *ie);
static unsigned int _image_open_server_send(Image_Entry *ie);
static unsigned int _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used);
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)NULL)->sun_path)
#endif
@ -213,12 +220,12 @@ _server_disconnect(void)
}
static void
_request_answer_add(Message_Type type, unsigned int rid, Op_Callback cb, void *data)
_request_answer_add(Msg_Base *msg, int size, Op_Callback cb, void *data)
{
Client_Request *cr = calloc(1, sizeof(*cr));
cr->type = type;
cr->rid = rid;
cr->msg = msg;
cr->msg_size = size;
cr->cb = cb;
cr->data = data;
@ -239,7 +246,7 @@ _server_safe_send(int fd, const void *data, int size)
{
if ((errno == EAGAIN) || (errno == EINTR))
continue;
DBG("send() failed with error [%d] %s", errno, strerror(errno));
ERR("send() failed with error %d %m", errno);
return EINA_FALSE;
}
sent += ret;
@ -249,18 +256,114 @@ _server_safe_send(int fd, const void *data, int size)
}
static Eina_Bool
_server_send(const void *buf, int size, Op_Callback cb, void *data)
_request_resend(unsigned int rid)
{
const Msg_Base *msg;
Eina_List *l;
Client_Request *cr;
Eina_Bool found = EINA_FALSE;
EINA_LIST_FOREACH(_requests, l, cr)
{
if (rid)
{
if (cr->msg->rid != rid)
continue;
found = EINA_TRUE;
}
DBG("Sending request %d again: type %d", cr->msg->rid, cr->msg->type);
if (!_server_safe_send(socketfd, &cr->msg_size, sizeof(cr->msg_size)))
return EINA_FALSE;
if (!_server_safe_send(socketfd, cr->msg, cr->msg_size))
return EINA_FALSE;
if (found) break;
}
if (rid)
return found;
return EINA_TRUE;
}
static void
_shared_index_close(Shared_Index *si)
{
if (!si) return;
if (si->f)
{
if (si->data)
eina_file_map_free(si->f, si->data);
eina_file_close(si->f);
}
if (si->entries_by_hkey)
eina_hash_free(si->entries_by_hkey);
si->f = NULL;
si->data = NULL;
memset(si, 0, sizeof(Shared_Index));
}
static void
_shared_index_close_all()
{
DBG("Closing all index files");
if (_index.strings_entries.f)
{
if (_index.strings_entries.data)
eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
eina_file_close(_index.strings_entries.f);
_index.strings_entries.data = NULL;
_index.strings_entries.f = NULL;
}
_shared_index_close(&_index.strings_index);
_shared_index_close(&_index.files);
_shared_index_close(&_index.images);
_shared_index_close(&_index.fonts);
_index.generation_id = 0;
}
static Eina_Bool
_server_reconnect()
{
_shared_index_close_all();
errno = 0;
_server_disconnect();
if (!_server_connect())
goto on_error;
if (!_server_dispatch_until(SPECIAL_RID_INDEX_LIST))
goto on_error;
#warning TODO: Reopen all files, images, fonts...
DBG("Re-sending %d requests...", eina_list_count(_requests));
if (!_request_resend(0))
goto on_error;
INF("Successfully reconnected to cserve2");
return EINA_TRUE;
on_error:
ERR("Unable to reconnect to server: %d %m", errno);
return EINA_FALSE;
}
static Eina_Bool
_server_send(void *buf, int size, Op_Callback cb, void *data)
{
Msg_Base *msg;
if (!_server_safe_send(socketfd, &size, sizeof(size)))
{
ERR("Couldn't send message size to server.");
return EINA_FALSE;
goto on_error;
}
if (!_server_safe_send(socketfd, buf, size))
{
ERR("Couldn't send message body to server.");
return EINA_FALSE;
goto on_error;
}
msg = buf;
@ -271,13 +374,40 @@ _server_send(const void *buf, int size, Op_Callback cb, void *data)
case CSERVE2_PRELOAD:
case CSERVE2_FONT_LOAD:
case CSERVE2_FONT_GLYPHS_LOAD:
_request_answer_add(msg->type, msg->rid, cb, data);
break;
_request_answer_add(msg, size, cb, data);
break;
case CSERVE2_CLOSE:
case CSERVE2_UNLOAD:
case CSERVE2_FONT_UNLOAD:
case CSERVE2_FONT_GLYPHS_USED:
free(msg);
break;
default:
break;
ERR("Invalid message type %d", msg->type);
free(msg);
return EINA_FALSE;
}
return EINA_TRUE;
on_error:
ERR("Socket error: %d %m", errno);
switch (errno)
{
case EPIPE:
case EBADF:
WRN("Trying to reconnect to server...");
if (!_server_reconnect())
{
free(buf);
return EINA_FALSE;
}
return _server_send(buf, size, cb, data);
default:
ERR("Can not recover from this error!");
free(buf);
return EINA_FALSE;
}
}
static int sr_size = 0;
@ -290,12 +420,21 @@ _server_read(int *size)
int n;
void *ret;
if (socketfd < 0)
return NULL;
if (sr_size)
goto get_data;
n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
if (n < 0)
return NULL;
if (n == 0)
{
DBG("Socket connection closed by server.");
_server_disconnect();
return NULL;
}
sr_buf = malloc(sr_size);
@ -400,20 +539,27 @@ _server_dispatch(Eina_Bool *failed)
case CSERVE2_INDEX_LIST:
_server_index_list_set(msg, size);
free(msg);
return 0;
default: break;
return SPECIAL_RID_INDEX_LIST;
default:
break;
}
// Normal client to server requests
EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr)
{
if (cr->rid != msg->rid) // dispatch this answer
Eina_Bool remove = EINA_TRUE;
if (cr->msg->rid != msg->rid) // dispatch this answer
continue;
_requests = eina_list_remove_list(_requests, l);
if (cr->cb)
cr->cb(cr->data, msg, size);
free(cr);
remove = cr->cb(cr->data, msg, size);
if (remove)
{
_requests = eina_list_remove_list(_requests, l);
free(cr->msg);
free(cr);
}
}
rid = msg->rid;
@ -439,6 +585,16 @@ _server_dispatch_until(unsigned int rid)
{
int sel;
if (socketfd == -1)
{
DBG("Reconnecting to server...");
if (!_server_connect())
{
ERR("Could not reconnect to cserve2!");
return EINA_FALSE;
}
}
//DBG("Waiting for request %d...", rid);
FD_ZERO(&rfds);
FD_SET(socketfd, &rfds);
@ -470,7 +626,7 @@ _server_dispatch_until(unsigned int rid)
return EINA_TRUE;
}
static void
static Eina_Bool
_image_opened_cb(void *data, const void *msg_received, int size)
{
const Msg_Base *answer = msg_received;
@ -481,15 +637,15 @@ _image_opened_cb(void *data, const void *msg_received, int size)
* and so we would have to check that open_rid is equal to answer->rid.
* -- jpeg
*/
//DBG("Received OPENED for RID: %d [open_rid: %d]", answer->rid, ie->open_rid);
DBG("Received OPENED for RID: %d [open_rid: %d]", answer->rid, ie->open_rid);
if (ie->server_id && !ie->open_rid)
return;
return EINA_TRUE;
if (answer->rid != ie->open_rid)
{
WRN("Message rid (%d) differs from expected rid (open_rid: %d)", answer->rid, ie->open_rid);
return;
return EINA_TRUE;
}
ie->open_rid = 0;
@ -505,14 +661,14 @@ _image_opened_cb(void *data, const void *msg_received, int size)
ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
free(ie->data1);
ie->data1 = NULL;
return;
return EINA_TRUE;
}
else if (size < (int) sizeof(*msg))
{
ERR("Received message is too small");
free(ie->data1);
ie->data1 = NULL;
return;
return EINA_TRUE;
}
ie->w = msg->image.w;
@ -522,6 +678,8 @@ _image_opened_cb(void *data, const void *msg_received, int size)
ie->animated.loop_count = msg->image.loop_count;
ie->animated.frame_count = msg->image.frame_count;
ie->animated.animated = msg->image.animated;
return EINA_TRUE;
}
static void
@ -575,29 +733,29 @@ fail:
ie->data2 = NULL;
}
static void
static Eina_Bool
_image_loaded_cb(void *data, const void *msg_received, int size)
{
const Msg_Base *answer = msg_received;
const Msg_Loaded *msg = msg_received;
Image_Entry *ie = data;
//DBG("Received LOADED for RID: %d [load_rid: %d]", answer->rid, ie->load_rid);
DBG("Received LOADED for RID: %d [load_rid: %d]", answer->rid, ie->load_rid);
if (!ie->load_rid)
return;
return EINA_TRUE;
if (answer->rid != ie->load_rid)
{
WRN("Message rid (%d) differs from expected rid (load_rid: %d)", answer->rid, ie->load_rid);
return;
return EINA_TRUE;
}
ie->load_rid = 0;
if (!ie->data2)
{
ERR("No data2 for loaded file");
return;
return EINA_TRUE;
}
if (answer->type != CSERVE2_LOADED)
@ -607,18 +765,29 @@ _image_loaded_cb(void *data, const void *msg_received, int size)
const Msg_Error *msg_error = msg_received;
ERR("Couldn't load image: '%s':'%s'; error: %d",
ie->file, ie->key, msg_error->error);
if (msg_error->error == CSERVE2_NOT_LOADED)
{
#warning Code path to check
DBG("Trying to reopen the image");
ie->open_rid = _image_open_server_send(ie);
if (_server_dispatch_until(ie->open_rid))
if (_request_resend(answer->rid))
return EINA_TRUE;
}
}
else
ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
free(ie->data2);
ie->data2 = NULL;
return;
return EINA_TRUE;
}
_loaded_handle(ie, msg, size);
return EINA_TRUE;
}
static void
static Eina_Bool
_image_preloaded_cb(void *data, const void *msg_received, int size)
{
const Msg_Base *answer = msg_received;
@ -633,7 +802,7 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
if (!ie->data2)
{
ERR("No data2 for preloaded file");
return;
return EINA_TRUE;
}
if (answer->type != CSERVE2_PRELOAD &&
@ -650,7 +819,7 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
if (dentry->preloaded_cb)
dentry->preloaded_cb(data, EINA_FALSE);
dentry->preloaded_cb = NULL;
return;
return EINA_TRUE;
}
_loaded_handle(ie, msg_received, size);
@ -661,6 +830,8 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
dentry->preloaded_cb(data, EINA_TRUE);
dentry->preloaded_cb = NULL;
}
return EINA_TRUE;
}
static int
@ -716,7 +887,11 @@ _evas_image_load_opts_empty(Evas_Image_Load_Opts *lo)
&& (lo->w == 0) && (lo->h == 0)
&& (lo->region.x == 0) && (lo->region.y == 0)
&& (lo->region.w == 0) && (lo->region.h == 0)
&& (lo->orientation == 0));
&& (lo->orientation == 0)
&& (lo->scale_load.src_x == 0) && (lo->scale_load.src_y == 0)
&& (lo->scale_load.src_w == 0) && (lo->scale_load.src_h == 0)
&& (lo->scale_load.dst_w == 0) && (lo->scale_load.dst_h == 0)
&& (lo->scale_load.scale_hint == 0)); // Skip smooth
}
static void
@ -747,8 +922,7 @@ _file_hkey_get(char *buf, size_t sz, const char *path, const char *key,
}
static unsigned int
_image_open_server_send(Image_Entry *ie, const char *file, const char *key,
Evas_Image_Load_Opts *opts)
_image_open_server_send(Image_Entry *ie)
{
int flen, klen;
int size, hkey_len;
@ -758,6 +932,8 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
Msg_Open msg_open;
File_Entry *fentry;
Data_Entry *dentry;
const char *file, *key;
Evas_Image_Load_Opts *opts = NULL;
if (cserve2_init == 0)
{
@ -765,9 +941,15 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
return 0;
}
if (!_evas_image_load_opts_empty(&ie->load_opts))
opts = &ie->load_opts;
ie->data1 = NULL;
ie->data2 = NULL;
file = ie->file;
key = ie->key;
flen = _build_absolute_path(file, filebuf, sizeof(filebuf));
if (!flen)
{
@ -833,16 +1015,13 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
if (!_server_send(buf, size, _image_opened_cb, ie))
{
ERR("Couldn't send message to server.");
free(buf);
free(dentry);
if (!(--fentry->refcount))
eina_hash_del(_file_entries, fentry->hkey, fentry);
return 0;
}
free(buf);
ie->data1 = fentry;
dentry->image_id = msg_open.image_id;
ie->data2 = dentry;
@ -853,7 +1032,8 @@ unsigned int
_image_load_server_send(Image_Entry *ie)
{
Data_Entry *dentry;
Msg_Load msg;
Msg_Load *msg;
unsigned int rid;
if (cserve2_init == 0)
return 0;
@ -871,23 +1051,24 @@ _image_load_server_send(Image_Entry *ie)
return 0;
}
memset(&msg, 0, sizeof(msg));
msg = calloc(1, sizeof(Msg_Load));
msg->base.rid = _next_rid();
msg->base.type = CSERVE2_LOAD;
msg->image_id = dentry->image_id;
msg.base.rid = _next_rid();
msg.base.type = CSERVE2_LOAD;
msg.image_id = dentry->image_id;
if (!_server_send(&msg, sizeof(msg), _image_loaded_cb, ie))
rid = msg->base.rid;
if (!_server_send(msg, sizeof(Msg_Load), _image_loaded_cb, ie))
return 0;
return msg.base.rid;
return rid;
}
unsigned int
_image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success))
{
Data_Entry *dentry;
Msg_Preload msg;
Msg_Preload *msg;
unsigned int rid;
if (cserve2_init == 0)
return 0;
@ -900,23 +1081,24 @@ _image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_
}
dentry->preloaded_cb = preloaded_cb;
memset(&msg, 0, sizeof(msg));
msg = calloc(1, sizeof(Msg_Preload));
msg->base.rid = _next_rid();
msg->base.type = CSERVE2_PRELOAD;
msg->image_id = dentry->image_id;
msg.base.rid = _next_rid();
msg.base.type = CSERVE2_PRELOAD;
msg.image_id = dentry->image_id;
if (!_server_send(&msg, sizeof(msg), _image_preloaded_cb, ie))
rid = msg->base.rid;
if (!_server_send(msg, sizeof(Msg_Preload), _image_preloaded_cb, ie))
return 0;
return msg.base.rid;
return rid;
}
unsigned int
_image_close_server_send(Image_Entry *ie)
{
Msg_Close msg;
Msg_Close *msg;
File_Entry *fentry;
unsigned int rid;
if (cserve2_init == 0)
return 0;
@ -937,26 +1119,28 @@ _image_close_server_send(Image_Entry *ie)
ie->data2 = NULL;
}
memset(&msg, 0, sizeof(msg));
msg.base.rid = _next_rid();
msg.base.type = CSERVE2_CLOSE;
msg.file_id = fentry->file_id;
msg = calloc(1, sizeof(Msg_Close));
msg->base.rid = _next_rid();
msg->base.type = CSERVE2_CLOSE;
msg->file_id = fentry->file_id;
if (!(--fentry->refcount))
eina_hash_del(_file_entries, fentry->hkey, fentry);
ie->data1 = NULL;
if (!_server_send(&msg, sizeof(msg), NULL, NULL))
rid = msg->base.rid;
if (!_server_send(msg, sizeof(Msg_Close), NULL, NULL))
return 0;
return msg.base.rid;
return rid;
}
unsigned int
_image_unload_server_send(Image_Entry *ie)
{
Msg_Unload msg;
Msg_Unload *msg;
Data_Entry *dentry;
unsigned int rid;
if (cserve2_init == 0)
return 0;
@ -971,37 +1155,30 @@ _image_unload_server_send(Image_Entry *ie)
if (dentry->shm.f)
eina_file_close(dentry->shm.f);
// if (dentry->shm.path)
// free(dentry->shm.path);
memset(&msg, 0, sizeof(msg));
msg.base.rid = _next_rid();
msg.base.type = CSERVE2_UNLOAD;
msg.image_id = dentry->image_id;
msg = calloc(1, sizeof(Msg_Unload));
msg->base.rid = _next_rid();
msg->base.type = CSERVE2_UNLOAD;
msg->image_id = dentry->image_id;
free(dentry);
ie->data2 = NULL;
if (!_server_send(&msg, sizeof(msg), NULL, NULL))
rid = msg->base.rid;
if (!_server_send(msg, sizeof(Msg_Unload), NULL, NULL))
return 0;
return msg.base.rid;
return rid;
}
Eina_Bool
evas_cserve2_image_load(Image_Entry *ie)
{
unsigned int rid;
const char *file, *key;
Evas_Image_Load_Opts *opts = NULL;
if (!ie)
return EINA_FALSE;
file = ie->file;
key = ie->key;
if (!_memory_zero_cmp(&ie->load_opts, sizeof(ie->load_opts)))
opts = &ie->load_opts;
rid = _image_open_server_send(ie, file, key, opts);
rid = _image_open_server_send(ie);
if (!rid)
return EINA_FALSE;
@ -1282,7 +1459,7 @@ _font_entry_free(Font_Entry *fe)
free(fe);
}
static void
static Eina_Bool
_font_loaded_cb(void *data, const void *msg, int size)
{
const Msg_Base *m = msg;
@ -1293,6 +1470,8 @@ _font_loaded_cb(void *data, const void *msg, int size)
if ((size < (int) sizeof(*m))
|| (m->type == CSERVE2_ERROR))
fe->failed = EINA_TRUE;
return EINA_TRUE;
}
static unsigned int
@ -1330,10 +1509,9 @@ _font_load_server_send(Font_Entry *fe, Message_Type type)
if (type == CSERVE2_FONT_LOAD)
cb = _font_loaded_cb;
if (_server_send(msg, size, cb, fe))
ret = msg->base.rid;
free(msg);
ret = msg->base.rid;
if (!_server_send(msg, size, cb, fe))
return 0;
return ret;
}
@ -1465,6 +1643,23 @@ _glyph_map_remap_check(Glyph_Map *map)
{
Eina_Bool changed = EINA_FALSE;
int oldcount;
const void *oldmap = map->mempool.data;
if (!map->mempool.f)
{
WRN("The glyph mempool has been closed.");
if (!map->mempool.path)
return EINA_FALSE;
DBG("Remapping from %s", map->mempool.path);
map->mempool.f = eina_file_open(map->mempool.path, EINA_TRUE);
if (!map->mempool.f)
{
ERR("Could not open shm file: %d %m", errno);
return EINA_FALSE;
}
map->mempool.size = 0;
}
if (eina_file_refresh(map->mempool.f)
|| (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size))
@ -1481,6 +1676,7 @@ _glyph_map_remap_check(Glyph_Map *map)
changed = EINA_TRUE;
// Remap loaded glyphs
#warning Infinite loop again here. FONT RELOAD IS STILL BROKEN.
EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs,
CS_Glyph_Out, map_entry)
{
@ -1496,6 +1692,7 @@ _glyph_map_remap_check(Glyph_Map *map)
oldcount = map->index.count;
_shared_index_remap_check(&map->index, sizeof(Glyph_Data));
changed |= (oldcount != map->index.count);
changed |= (oldmap != map->mempool.data);
return changed;
}
@ -1571,7 +1768,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
return cnt;
}
static void
static Eina_Bool
_glyph_request_cb(void *data, const void *msg, int size)
{
const Msg_Font_Glyphs_Loaded *resp = msg;
@ -1583,11 +1780,56 @@ _glyph_request_cb(void *data, const void *msg, int size)
const char *name;
int pos;
if (resp->base.type == CSERVE2_ERROR)
if (!fe || !fe->fash[grd->hints])
goto end;
if (!fe->fash[grd->hints])
goto end;
if (resp->base.type == CSERVE2_ERROR)
{
const Msg_Error *err = msg;
ERR("We got an error message when waiting for glyphs: %d", err->error);
if (err->error == CSERVE2_NOT_LOADED)
{
DBG("Reloading the font: %s from %s", fe->name, fe->source);
// This will crash for sure.
/*
for (i = 0; i < 3; i++)
{
if (fe->fash[i])
fash_gl_free(fe->fash[i]);
fe->fash[i] = NULL;
}
_glyphs_map_free(fe->map);
fe->map = NULL;
*/
if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD)))
{
ERR("Failed to send font load message");
free(data);
return EINA_TRUE;
}
#warning Code path to check
if (fe->glyphs_queue_count)
_glyph_request_server_send(fe, grd->hints, EINA_FALSE);
if (fe->glyphs_used_count)
_glyph_request_server_send(fe, grd->hints, EINA_TRUE);
DBG("Resending glyph load message now...");
if (!_request_resend(err->base.rid))
{
free(data);
return EINA_TRUE;
}
return EINA_FALSE;
}
free(data);
return EINA_TRUE;
}
if (size <= (int) sizeof(*resp)) goto end;
@ -1686,15 +1928,23 @@ _glyph_request_cb(void *data, const void *msg, int size)
{
ERR("Failed to remap glyph mempool!");
gl->base.bitmap.buffer = NULL;
//gl->base.bitmap.rows = 0;
//gl->base.bitmap.width = 0;
}
}
eina_clist_add_head(&fe->map->glyphs, &gl->map_entry);
if (!eina_clist_element_is_linked(&gl->map_entry))
eina_clist_add_head(&fe->map->glyphs, &gl->map_entry);
}
}
end:
free(grd);
return EINA_TRUE;
end:
ERR("An unknown error occured when waiting for glyph data!");
free(grd);
return EINA_TRUE;
}
static unsigned int
@ -1782,12 +2032,12 @@ _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used
else
cb = NULL;
if (_server_send(msg, size, cb, grd))
ret = msg->base.rid;
else
free(grd);
free(msg);
ret = msg->base.rid;
if (!_server_send(msg, size, cb, grd))
{
free(grd);
return 0;
}
return ret;
}
@ -1916,7 +2166,12 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx,
#endif
if (out->rid)
_server_dispatch_until(out->rid);
if (!_server_dispatch_until(out->rid))
{
ERR("failed to load the requested glyphs");
//fe->failed = EINA_TRUE;
//return NULL;
}
// promote shm and font entry in lru or something
@ -2050,10 +2305,7 @@ _server_index_list_set(Msg_Base *data, int size)
SHARED_BUFFER_PATH_MAX) != 0)
{
DBG("Updating string indexes shm to: '%s'", msg->strings_index_path);
eina_file_map_free(_index.strings_index.f, _index.strings_index.data);
eina_file_close(_index.strings_index.f);
_index.strings_index.f = NULL;
_index.strings_index.data = NULL;
_shared_index_close(&_index.strings_index);
}
eina_strlcpy(_index.strings_entries.path, msg->strings_entries_path, SHARED_BUFFER_PATH_MAX);

View File

@ -17,7 +17,6 @@ struct _Data_Entry
unsigned int hit_count;
void (*preloaded_cb)(void *, Eina_Bool);
struct {
const char *path;
int mmap_offset;
int use_offset;
int mmap_size;