summaryrefslogtreecommitdiff
path: root/src/lib/evas/cserve2/evas_cs2_client.c
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-10-02 20:23:14 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-10-28 15:47:16 +0900
commite74cac57e412bcd71f2cc58ba46d326aef0996c4 (patch)
tree3ef14985f93e18bbb642aa537562e648ba01e77b /src/lib/evas/cserve2/evas_cs2_client.c
parent3889feca24ad3dba2aead16261a6b8dde0687b57 (diff)
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.
Diffstat (limited to '')
-rw-r--r--src/lib/evas/cserve2/evas_cs2_client.c454
1 files changed, 353 insertions, 101 deletions
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c
index cf3e1b7a1e..a1ca4d3135 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -21,7 +21,9 @@
21#define USE_SHARED_INDEX 1 21#define USE_SHARED_INDEX 1
22#define SHARED_INDEX_ADD_TO_HASH 1 22#define SHARED_INDEX_ADD_TO_HASH 1
23#define HKEY_LOAD_OPTS_STR_LEN 215 23#define HKEY_LOAD_OPTS_STR_LEN 215
24typedef void (*Op_Callback)(void *data, const void *msg, int size); 24#define SPECIAL_RID_INDEX_LIST ((unsigned int) 0xFFFFFF42)
25
26typedef Eina_Bool (*Op_Callback)(void *data, const void *msg, int size);
25 27
26static const Evas_Image_Load_Opts empty_lo = { 28static const Evas_Image_Load_Opts empty_lo = {
27 { 0, 0, 0, 0 }, 29 { 0, 0, 0, 0 },
@@ -47,8 +49,8 @@ struct _File_Entry {
47}; 49};
48 50
49struct _Client_Request { 51struct _Client_Request {
50 Message_Type type; 52 Msg_Base *msg;
51 unsigned int rid; 53 int msg_size;
52 Op_Callback cb; 54 Op_Callback cb;
53 void *data; 55 void *data;
54}; 56};
@@ -77,6 +79,11 @@ static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie);
77static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe); 79static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe);
78static Eina_Bool _shared_index_remap_check(Shared_Index *si, int elemsize); 80static Eina_Bool _shared_index_remap_check(Shared_Index *si, int elemsize);
79 81
82static Eina_Bool _server_dispatch_until(unsigned int rid);
83unsigned int _image_load_server_send(Image_Entry *ie);
84static unsigned int _image_open_server_send(Image_Entry *ie);
85static unsigned int _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used);
86
80#ifndef UNIX_PATH_MAX 87#ifndef UNIX_PATH_MAX
81#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)NULL)->sun_path) 88#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)NULL)->sun_path)
82#endif 89#endif
@@ -213,12 +220,12 @@ _server_disconnect(void)
213} 220}
214 221
215static void 222static void
216_request_answer_add(Message_Type type, unsigned int rid, Op_Callback cb, void *data) 223_request_answer_add(Msg_Base *msg, int size, Op_Callback cb, void *data)
217{ 224{
218 Client_Request *cr = calloc(1, sizeof(*cr)); 225 Client_Request *cr = calloc(1, sizeof(*cr));
219 226
220 cr->type = type; 227 cr->msg = msg;
221 cr->rid = rid; 228 cr->msg_size = size;
222 cr->cb = cb; 229 cr->cb = cb;
223 cr->data = data; 230 cr->data = data;
224 231
@@ -239,7 +246,7 @@ _server_safe_send(int fd, const void *data, int size)
239 { 246 {
240 if ((errno == EAGAIN) || (errno == EINTR)) 247 if ((errno == EAGAIN) || (errno == EINTR))
241 continue; 248 continue;
242 DBG("send() failed with error [%d] %s", errno, strerror(errno)); 249 ERR("send() failed with error %d %m", errno);
243 return EINA_FALSE; 250 return EINA_FALSE;
244 } 251 }
245 sent += ret; 252 sent += ret;
@@ -249,18 +256,114 @@ _server_safe_send(int fd, const void *data, int size)
249} 256}
250 257
251static Eina_Bool 258static Eina_Bool
252_server_send(const void *buf, int size, Op_Callback cb, void *data) 259_request_resend(unsigned int rid)
253{ 260{
254 const Msg_Base *msg; 261 Eina_List *l;
262 Client_Request *cr;
263 Eina_Bool found = EINA_FALSE;
264
265 EINA_LIST_FOREACH(_requests, l, cr)
266 {
267 if (rid)
268 {
269 if (cr->msg->rid != rid)
270 continue;
271 found = EINA_TRUE;
272 }
273
274 DBG("Sending request %d again: type %d", cr->msg->rid, cr->msg->type);
275
276 if (!_server_safe_send(socketfd, &cr->msg_size, sizeof(cr->msg_size)))
277 return EINA_FALSE;
278 if (!_server_safe_send(socketfd, cr->msg, cr->msg_size))
279 return EINA_FALSE;
280
281 if (found) break;
282 }
283
284 if (rid)
285 return found;
286
287 return EINA_TRUE;
288}
289
290static void
291_shared_index_close(Shared_Index *si)
292{
293 if (!si) return;
294
295 if (si->f)
296 {
297 if (si->data)
298 eina_file_map_free(si->f, si->data);
299 eina_file_close(si->f);
300 }
301 if (si->entries_by_hkey)
302 eina_hash_free(si->entries_by_hkey);
303 si->f = NULL;
304 si->data = NULL;
305 memset(si, 0, sizeof(Shared_Index));
306}
307
308static void
309_shared_index_close_all()
310{
311 DBG("Closing all index files");
312 if (_index.strings_entries.f)
313 {
314 if (_index.strings_entries.data)
315 eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data);
316 eina_file_close(_index.strings_entries.f);
317 _index.strings_entries.data = NULL;
318 _index.strings_entries.f = NULL;
319 }
320 _shared_index_close(&_index.strings_index);
321 _shared_index_close(&_index.files);
322 _shared_index_close(&_index.images);
323 _shared_index_close(&_index.fonts);
324 _index.generation_id = 0;
325}
326
327static Eina_Bool
328_server_reconnect()
329{
330 _shared_index_close_all();
331
332 errno = 0;
333 _server_disconnect();
334 if (!_server_connect())
335 goto on_error;
336
337 if (!_server_dispatch_until(SPECIAL_RID_INDEX_LIST))
338 goto on_error;
339
340#warning TODO: Reopen all files, images, fonts...
341
342 DBG("Re-sending %d requests...", eina_list_count(_requests));
343 if (!_request_resend(0))
344 goto on_error;
345
346 INF("Successfully reconnected to cserve2");
347 return EINA_TRUE;
348
349on_error:
350 ERR("Unable to reconnect to server: %d %m", errno);
351 return EINA_FALSE;
352}
353
354static Eina_Bool
355_server_send(void *buf, int size, Op_Callback cb, void *data)
356{
357 Msg_Base *msg;
255 if (!_server_safe_send(socketfd, &size, sizeof(size))) 358 if (!_server_safe_send(socketfd, &size, sizeof(size)))
256 { 359 {
257 ERR("Couldn't send message size to server."); 360 ERR("Couldn't send message size to server.");
258 return EINA_FALSE; 361 goto on_error;
259 } 362 }
260 if (!_server_safe_send(socketfd, buf, size)) 363 if (!_server_safe_send(socketfd, buf, size))
261 { 364 {
262 ERR("Couldn't send message body to server."); 365 ERR("Couldn't send message body to server.");
263 return EINA_FALSE; 366 goto on_error;
264 } 367 }
265 368
266 msg = buf; 369 msg = buf;
@@ -271,13 +374,40 @@ _server_send(const void *buf, int size, Op_Callback cb, void *data)
271 case CSERVE2_PRELOAD: 374 case CSERVE2_PRELOAD:
272 case CSERVE2_FONT_LOAD: 375 case CSERVE2_FONT_LOAD:
273 case CSERVE2_FONT_GLYPHS_LOAD: 376 case CSERVE2_FONT_GLYPHS_LOAD:
274 _request_answer_add(msg->type, msg->rid, cb, data); 377 _request_answer_add(msg, size, cb, data);
275 break; 378 break;
379 case CSERVE2_CLOSE:
380 case CSERVE2_UNLOAD:
381 case CSERVE2_FONT_UNLOAD:
382 case CSERVE2_FONT_GLYPHS_USED:
383 free(msg);
384 break;
276 default: 385 default:
277 break; 386 ERR("Invalid message type %d", msg->type);
387 free(msg);
388 return EINA_FALSE;
278 } 389 }
279 390
280 return EINA_TRUE; 391 return EINA_TRUE;
392
393on_error:
394 ERR("Socket error: %d %m", errno);
395 switch (errno)
396 {
397 case EPIPE:
398 case EBADF:
399 WRN("Trying to reconnect to server...");
400 if (!_server_reconnect())
401 {
402 free(buf);
403 return EINA_FALSE;
404 }
405 return _server_send(buf, size, cb, data);
406 default:
407 ERR("Can not recover from this error!");
408 free(buf);
409 return EINA_FALSE;
410 }
281} 411}
282 412
283static int sr_size = 0; 413static int sr_size = 0;
@@ -290,12 +420,21 @@ _server_read(int *size)
290 int n; 420 int n;
291 void *ret; 421 void *ret;
292 422
423 if (socketfd < 0)
424 return NULL;
425
293 if (sr_size) 426 if (sr_size)
294 goto get_data; 427 goto get_data;
295 428
296 n = recv(socketfd, &sr_size, sizeof(sr_size), 0); 429 n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
297 if (n < 0) 430 if (n < 0)
298 return NULL; 431 return NULL;
432 if (n == 0)
433 {
434 DBG("Socket connection closed by server.");
435 _server_disconnect();
436 return NULL;
437 }
299 438
300 sr_buf = malloc(sr_size); 439 sr_buf = malloc(sr_size);
301 440
@@ -400,20 +539,27 @@ _server_dispatch(Eina_Bool *failed)
400 case CSERVE2_INDEX_LIST: 539 case CSERVE2_INDEX_LIST:
401 _server_index_list_set(msg, size); 540 _server_index_list_set(msg, size);
402 free(msg); 541 free(msg);
403 return 0; 542 return SPECIAL_RID_INDEX_LIST;
404 default: break; 543 default:
544 break;
405 } 545 }
406 546
407 // Normal client to server requests 547 // Normal client to server requests
408 EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr) 548 EINA_LIST_FOREACH_SAFE(_requests, l, l_next, cr)
409 { 549 {
410 if (cr->rid != msg->rid) // dispatch this answer 550 Eina_Bool remove = EINA_TRUE;
551
552 if (cr->msg->rid != msg->rid) // dispatch this answer
411 continue; 553 continue;
412 554
413 _requests = eina_list_remove_list(_requests, l);
414 if (cr->cb) 555 if (cr->cb)
415 cr->cb(cr->data, msg, size); 556 remove = cr->cb(cr->data, msg, size);
416 free(cr); 557 if (remove)
558 {
559 _requests = eina_list_remove_list(_requests, l);
560 free(cr->msg);
561 free(cr);
562 }
417 } 563 }
418 564
419 rid = msg->rid; 565 rid = msg->rid;
@@ -439,6 +585,16 @@ _server_dispatch_until(unsigned int rid)
439 { 585 {
440 int sel; 586 int sel;
441 587
588 if (socketfd == -1)
589 {
590 DBG("Reconnecting to server...");
591 if (!_server_connect())
592 {
593 ERR("Could not reconnect to cserve2!");
594 return EINA_FALSE;
595 }
596 }
597
442 //DBG("Waiting for request %d...", rid); 598 //DBG("Waiting for request %d...", rid);
443 FD_ZERO(&rfds); 599 FD_ZERO(&rfds);
444 FD_SET(socketfd, &rfds); 600 FD_SET(socketfd, &rfds);
@@ -470,7 +626,7 @@ _server_dispatch_until(unsigned int rid)
470 return EINA_TRUE; 626 return EINA_TRUE;
471} 627}
472 628
473static void 629static Eina_Bool
474_image_opened_cb(void *data, const void *msg_received, int size) 630_image_opened_cb(void *data, const void *msg_received, int size)
475{ 631{
476 const Msg_Base *answer = msg_received; 632 const Msg_Base *answer = msg_received;
@@ -481,15 +637,15 @@ _image_opened_cb(void *data, const void *msg_received, int size)
481 * and so we would have to check that open_rid is equal to answer->rid. 637 * and so we would have to check that open_rid is equal to answer->rid.
482 * -- jpeg 638 * -- jpeg
483 */ 639 */
484 //DBG("Received OPENED for RID: %d [open_rid: %d]", answer->rid, ie->open_rid); 640 DBG("Received OPENED for RID: %d [open_rid: %d]", answer->rid, ie->open_rid);
485 641
486 if (ie->server_id && !ie->open_rid) 642 if (ie->server_id && !ie->open_rid)
487 return; 643 return EINA_TRUE;
488 644
489 if (answer->rid != ie->open_rid) 645 if (answer->rid != ie->open_rid)
490 { 646 {
491 WRN("Message rid (%d) differs from expected rid (open_rid: %d)", answer->rid, ie->open_rid); 647 WRN("Message rid (%d) differs from expected rid (open_rid: %d)", answer->rid, ie->open_rid);
492 return; 648 return EINA_TRUE;
493 } 649 }
494 ie->open_rid = 0; 650 ie->open_rid = 0;
495 651
@@ -505,14 +661,14 @@ _image_opened_cb(void *data, const void *msg_received, int size)
505 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__); 661 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
506 free(ie->data1); 662 free(ie->data1);
507 ie->data1 = NULL; 663 ie->data1 = NULL;
508 return; 664 return EINA_TRUE;
509 } 665 }
510 else if (size < (int) sizeof(*msg)) 666 else if (size < (int) sizeof(*msg))
511 { 667 {
512 ERR("Received message is too small"); 668 ERR("Received message is too small");
513 free(ie->data1); 669 free(ie->data1);
514 ie->data1 = NULL; 670 ie->data1 = NULL;
515 return; 671 return EINA_TRUE;
516 } 672 }
517 673
518 ie->w = msg->image.w; 674 ie->w = msg->image.w;
@@ -522,6 +678,8 @@ _image_opened_cb(void *data, const void *msg_received, int size)
522 ie->animated.loop_count = msg->image.loop_count; 678 ie->animated.loop_count = msg->image.loop_count;
523 ie->animated.frame_count = msg->image.frame_count; 679 ie->animated.frame_count = msg->image.frame_count;
524 ie->animated.animated = msg->image.animated; 680 ie->animated.animated = msg->image.animated;
681
682 return EINA_TRUE;
525} 683}
526 684
527static void 685static void
@@ -575,29 +733,29 @@ fail:
575 ie->data2 = NULL; 733 ie->data2 = NULL;
576} 734}
577 735
578static void 736static Eina_Bool
579_image_loaded_cb(void *data, const void *msg_received, int size) 737_image_loaded_cb(void *data, const void *msg_received, int size)
580{ 738{
581 const Msg_Base *answer = msg_received; 739 const Msg_Base *answer = msg_received;
582 const Msg_Loaded *msg = msg_received; 740 const Msg_Loaded *msg = msg_received;
583 Image_Entry *ie = data; 741 Image_Entry *ie = data;
584 742
585 //DBG("Received LOADED for RID: %d [load_rid: %d]", answer->rid, ie->load_rid); 743 DBG("Received LOADED for RID: %d [load_rid: %d]", answer->rid, ie->load_rid);
586 744
587 if (!ie->load_rid) 745 if (!ie->load_rid)
588 return; 746 return EINA_TRUE;
589 747
590 if (answer->rid != ie->load_rid) 748 if (answer->rid != ie->load_rid)
591 { 749 {
592 WRN("Message rid (%d) differs from expected rid (load_rid: %d)", answer->rid, ie->load_rid); 750 WRN("Message rid (%d) differs from expected rid (load_rid: %d)", answer->rid, ie->load_rid);
593 return; 751 return EINA_TRUE;
594 } 752 }
595 ie->load_rid = 0; 753 ie->load_rid = 0;
596 754
597 if (!ie->data2) 755 if (!ie->data2)
598 { 756 {
599 ERR("No data2 for loaded file"); 757 ERR("No data2 for loaded file");
600 return; 758 return EINA_TRUE;
601 } 759 }
602 760
603 if (answer->type != CSERVE2_LOADED) 761 if (answer->type != CSERVE2_LOADED)
@@ -607,18 +765,29 @@ _image_loaded_cb(void *data, const void *msg_received, int size)
607 const Msg_Error *msg_error = msg_received; 765 const Msg_Error *msg_error = msg_received;
608 ERR("Couldn't load image: '%s':'%s'; error: %d", 766 ERR("Couldn't load image: '%s':'%s'; error: %d",
609 ie->file, ie->key, msg_error->error); 767 ie->file, ie->key, msg_error->error);
768
769 if (msg_error->error == CSERVE2_NOT_LOADED)
770 {
771#warning Code path to check
772 DBG("Trying to reopen the image");
773 ie->open_rid = _image_open_server_send(ie);
774 if (_server_dispatch_until(ie->open_rid))
775 if (_request_resend(answer->rid))
776 return EINA_TRUE;
777 }
610 } 778 }
611 else 779 else
612 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__); 780 ERR("Invalid message type received: %d (%s)", answer->type, __FUNCTION__);
613 free(ie->data2); 781 free(ie->data2);
614 ie->data2 = NULL; 782 ie->data2 = NULL;
615 return; 783 return EINA_TRUE;
616 } 784 }
617 785
618 _loaded_handle(ie, msg, size); 786 _loaded_handle(ie, msg, size);
787 return EINA_TRUE;
619} 788}
620 789
621static void 790static Eina_Bool
622_image_preloaded_cb(void *data, const void *msg_received, int size) 791_image_preloaded_cb(void *data, const void *msg_received, int size)
623{ 792{
624 const Msg_Base *answer = msg_received; 793 const Msg_Base *answer = msg_received;
@@ -633,7 +802,7 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
633 if (!ie->data2) 802 if (!ie->data2)
634 { 803 {
635 ERR("No data2 for preloaded file"); 804 ERR("No data2 for preloaded file");
636 return; 805 return EINA_TRUE;
637 } 806 }
638 807
639 if (answer->type != CSERVE2_PRELOAD && 808 if (answer->type != CSERVE2_PRELOAD &&
@@ -650,7 +819,7 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
650 if (dentry->preloaded_cb) 819 if (dentry->preloaded_cb)
651 dentry->preloaded_cb(data, EINA_FALSE); 820 dentry->preloaded_cb(data, EINA_FALSE);
652 dentry->preloaded_cb = NULL; 821 dentry->preloaded_cb = NULL;
653 return; 822 return EINA_TRUE;
654 } 823 }
655 824
656 _loaded_handle(ie, msg_received, size); 825 _loaded_handle(ie, msg_received, size);
@@ -661,6 +830,8 @@ _image_preloaded_cb(void *data, const void *msg_received, int size)
661 dentry->preloaded_cb(data, EINA_TRUE); 830 dentry->preloaded_cb(data, EINA_TRUE);
662 dentry->preloaded_cb = NULL; 831 dentry->preloaded_cb = NULL;
663 } 832 }
833
834 return EINA_TRUE;
664} 835}
665 836
666static int 837static int
@@ -716,7 +887,11 @@ _evas_image_load_opts_empty(Evas_Image_Load_Opts *lo)
716 && (lo->w == 0) && (lo->h == 0) 887 && (lo->w == 0) && (lo->h == 0)
717 && (lo->region.x == 0) && (lo->region.y == 0) 888 && (lo->region.x == 0) && (lo->region.y == 0)
718 && (lo->region.w == 0) && (lo->region.h == 0) 889 && (lo->region.w == 0) && (lo->region.h == 0)
719 && (lo->orientation == 0)); 890 && (lo->orientation == 0)
891 && (lo->scale_load.src_x == 0) && (lo->scale_load.src_y == 0)
892 && (lo->scale_load.src_w == 0) && (lo->scale_load.src_h == 0)
893 && (lo->scale_load.dst_w == 0) && (lo->scale_load.dst_h == 0)
894 && (lo->scale_load.scale_hint == 0)); // Skip smooth
720} 895}
721 896
722static void 897static void
@@ -747,8 +922,7 @@ _file_hkey_get(char *buf, size_t sz, const char *path, const char *key,
747} 922}
748 923
749static unsigned int 924static unsigned int
750_image_open_server_send(Image_Entry *ie, const char *file, const char *key, 925_image_open_server_send(Image_Entry *ie)
751 Evas_Image_Load_Opts *opts)
752{ 926{
753 int flen, klen; 927 int flen, klen;
754 int size, hkey_len; 928 int size, hkey_len;
@@ -758,6 +932,8 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
758 Msg_Open msg_open; 932 Msg_Open msg_open;
759 File_Entry *fentry; 933 File_Entry *fentry;
760 Data_Entry *dentry; 934 Data_Entry *dentry;
935 const char *file, *key;
936 Evas_Image_Load_Opts *opts = NULL;
761 937
762 if (cserve2_init == 0) 938 if (cserve2_init == 0)
763 { 939 {
@@ -765,9 +941,15 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
765 return 0; 941 return 0;
766 } 942 }
767 943
944 if (!_evas_image_load_opts_empty(&ie->load_opts))
945 opts = &ie->load_opts;
946
768 ie->data1 = NULL; 947 ie->data1 = NULL;
769 ie->data2 = NULL; 948 ie->data2 = NULL;
770 949
950 file = ie->file;
951 key = ie->key;
952
771 flen = _build_absolute_path(file, filebuf, sizeof(filebuf)); 953 flen = _build_absolute_path(file, filebuf, sizeof(filebuf));
772 if (!flen) 954 if (!flen)
773 { 955 {
@@ -833,16 +1015,13 @@ _image_open_server_send(Image_Entry *ie, const char *file, const char *key,
833 if (!_server_send(buf, size, _image_opened_cb, ie)) 1015 if (!_server_send(buf, size, _image_opened_cb, ie))
834 { 1016 {
835 ERR("Couldn't send message to server."); 1017 ERR("Couldn't send message to server.");
836 free(buf);
837 free(dentry); 1018 free(dentry);
838 if (!(--fentry->refcount)) 1019 if (!(--fentry->refcount))
839 eina_hash_del(_file_entries, fentry->hkey, fentry); 1020 eina_hash_del(_file_entries, fentry->hkey, fentry);
840 return 0; 1021 return 0;
841 } 1022 }
842 1023
843 free(buf);
844 ie->data1 = fentry; 1024 ie->data1 = fentry;
845
846 dentry->image_id = msg_open.image_id; 1025 dentry->image_id = msg_open.image_id;
847 ie->data2 = dentry; 1026 ie->data2 = dentry;
848 1027
@@ -853,7 +1032,8 @@ unsigned int
853_image_load_server_send(Image_Entry *ie) 1032_image_load_server_send(Image_Entry *ie)
854{ 1033{
855 Data_Entry *dentry; 1034 Data_Entry *dentry;
856 Msg_Load msg; 1035 Msg_Load *msg;
1036 unsigned int rid;
857 1037
858 if (cserve2_init == 0) 1038 if (cserve2_init == 0)
859 return 0; 1039 return 0;
@@ -871,23 +1051,24 @@ _image_load_server_send(Image_Entry *ie)
871 return 0; 1051 return 0;
872 } 1052 }
873 1053
874 memset(&msg, 0, sizeof(msg)); 1054 msg = calloc(1, sizeof(Msg_Load));
875 1055 msg->base.rid = _next_rid();
876 msg.base.rid = _next_rid(); 1056 msg->base.type = CSERVE2_LOAD;
877 msg.base.type = CSERVE2_LOAD; 1057 msg->image_id = dentry->image_id;
878 msg.image_id = dentry->image_id;
879 1058
880 if (!_server_send(&msg, sizeof(msg), _image_loaded_cb, ie)) 1059 rid = msg->base.rid;
1060 if (!_server_send(msg, sizeof(Msg_Load), _image_loaded_cb, ie))
881 return 0; 1061 return 0;
882 1062
883 return msg.base.rid; 1063 return rid;
884} 1064}
885 1065
886unsigned int 1066unsigned int
887_image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success)) 1067_image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_Bool success))
888{ 1068{
889 Data_Entry *dentry; 1069 Data_Entry *dentry;
890 Msg_Preload msg; 1070 Msg_Preload *msg;
1071 unsigned int rid;
891 1072
892 if (cserve2_init == 0) 1073 if (cserve2_init == 0)
893 return 0; 1074 return 0;
@@ -900,23 +1081,24 @@ _image_preload_server_send(Image_Entry *ie, void (*preloaded_cb)(void *im, Eina_
900 } 1081 }
901 dentry->preloaded_cb = preloaded_cb; 1082 dentry->preloaded_cb = preloaded_cb;
902 1083
903 memset(&msg, 0, sizeof(msg)); 1084 msg = calloc(1, sizeof(Msg_Preload));
904 1085 msg->base.rid = _next_rid();
905 msg.base.rid = _next_rid(); 1086 msg->base.type = CSERVE2_PRELOAD;
906 msg.base.type = CSERVE2_PRELOAD; 1087 msg->image_id = dentry->image_id;
907 msg.image_id = dentry->image_id;
908 1088
909 if (!_server_send(&msg, sizeof(msg), _image_preloaded_cb, ie)) 1089 rid = msg->base.rid;
1090 if (!_server_send(msg, sizeof(Msg_Preload), _image_preloaded_cb, ie))
910 return 0; 1091 return 0;
911 1092
912 return msg.base.rid; 1093 return rid;
913} 1094}
914 1095
915unsigned int 1096unsigned int
916_image_close_server_send(Image_Entry *ie) 1097_image_close_server_send(Image_Entry *ie)
917{ 1098{
918 Msg_Close msg; 1099 Msg_Close *msg;
919 File_Entry *fentry; 1100 File_Entry *fentry;
1101 unsigned int rid;
920 1102
921 if (cserve2_init == 0) 1103 if (cserve2_init == 0)
922 return 0; 1104 return 0;
@@ -937,26 +1119,28 @@ _image_close_server_send(Image_Entry *ie)
937 ie->data2 = NULL; 1119 ie->data2 = NULL;
938 } 1120 }
939 1121
940 memset(&msg, 0, sizeof(msg)); 1122 msg = calloc(1, sizeof(Msg_Close));
941 msg.base.rid = _next_rid(); 1123 msg->base.rid = _next_rid();
942 msg.base.type = CSERVE2_CLOSE; 1124 msg->base.type = CSERVE2_CLOSE;
943 msg.file_id = fentry->file_id; 1125 msg->file_id = fentry->file_id;
944 1126
945 if (!(--fentry->refcount)) 1127 if (!(--fentry->refcount))
946 eina_hash_del(_file_entries, fentry->hkey, fentry); 1128 eina_hash_del(_file_entries, fentry->hkey, fentry);
947 ie->data1 = NULL; 1129 ie->data1 = NULL;
948 1130
949 if (!_server_send(&msg, sizeof(msg), NULL, NULL)) 1131 rid = msg->base.rid;
1132 if (!_server_send(msg, sizeof(Msg_Close), NULL, NULL))
950 return 0; 1133 return 0;
951 1134
952 return msg.base.rid; 1135 return rid;
953} 1136}
954 1137
955unsigned int 1138unsigned int
956_image_unload_server_send(Image_Entry *ie) 1139_image_unload_server_send(Image_Entry *ie)
957{ 1140{
958 Msg_Unload msg; 1141 Msg_Unload *msg;
959 Data_Entry *dentry; 1142 Data_Entry *dentry;
1143 unsigned int rid;
960 1144
961 if (cserve2_init == 0) 1145 if (cserve2_init == 0)
962 return 0; 1146 return 0;
@@ -971,37 +1155,30 @@ _image_unload_server_send(Image_Entry *ie)
971 if (dentry->shm.f) 1155 if (dentry->shm.f)
972 eina_file_close(dentry->shm.f); 1156 eina_file_close(dentry->shm.f);
973 1157
974 // if (dentry->shm.path) 1158 msg = calloc(1, sizeof(Msg_Unload));
975 // free(dentry->shm.path); 1159 msg->base.rid = _next_rid();
976 memset(&msg, 0, sizeof(msg)); 1160 msg->base.type = CSERVE2_UNLOAD;
977 msg.base.rid = _next_rid(); 1161 msg->image_id = dentry->image_id;
978 msg.base.type = CSERVE2_UNLOAD;
979 msg.image_id = dentry->image_id;
980 1162
981 free(dentry); 1163 free(dentry);
982 ie->data2 = NULL; 1164 ie->data2 = NULL;
983 1165
984 if (!_server_send(&msg, sizeof(msg), NULL, NULL)) 1166 rid = msg->base.rid;
1167 if (!_server_send(msg, sizeof(Msg_Unload), NULL, NULL))
985 return 0; 1168 return 0;
986 1169
987 return msg.base.rid; 1170 return rid;
988} 1171}
989 1172
990Eina_Bool 1173Eina_Bool
991evas_cserve2_image_load(Image_Entry *ie) 1174evas_cserve2_image_load(Image_Entry *ie)
992{ 1175{
993 unsigned int rid; 1176 unsigned int rid;
994 const char *file, *key;
995 Evas_Image_Load_Opts *opts = NULL;
996 1177
997 if (!ie) 1178 if (!ie)
998 return EINA_FALSE; 1179 return EINA_FALSE;
999 1180
1000 file = ie->file; 1181 rid = _image_open_server_send(ie);
1001 key = ie->key;
1002 if (!_memory_zero_cmp(&ie->load_opts, sizeof(ie->load_opts)))
1003 opts = &ie->load_opts;
1004 rid = _image_open_server_send(ie, file, key, opts);
1005 if (!rid) 1182 if (!rid)
1006 return EINA_FALSE; 1183 return EINA_FALSE;
1007 1184
@@ -1282,7 +1459,7 @@ _font_entry_free(Font_Entry *fe)
1282 free(fe); 1459 free(fe);
1283} 1460}
1284 1461
1285static void 1462static Eina_Bool
1286_font_loaded_cb(void *data, const void *msg, int size) 1463_font_loaded_cb(void *data, const void *msg, int size)
1287{ 1464{
1288 const Msg_Base *m = msg; 1465 const Msg_Base *m = msg;
@@ -1293,6 +1470,8 @@ _font_loaded_cb(void *data, const void *msg, int size)
1293 if ((size < (int) sizeof(*m)) 1470 if ((size < (int) sizeof(*m))
1294 || (m->type == CSERVE2_ERROR)) 1471 || (m->type == CSERVE2_ERROR))
1295 fe->failed = EINA_TRUE; 1472 fe->failed = EINA_TRUE;
1473
1474 return EINA_TRUE;
1296} 1475}
1297 1476
1298static unsigned int 1477static unsigned int
@@ -1330,10 +1509,9 @@ _font_load_server_send(Font_Entry *fe, Message_Type type)
1330 if (type == CSERVE2_FONT_LOAD) 1509 if (type == CSERVE2_FONT_LOAD)
1331 cb = _font_loaded_cb; 1510 cb = _font_loaded_cb;
1332 1511
1333 if (_server_send(msg, size, cb, fe)) 1512 ret = msg->base.rid;
1334 ret = msg->base.rid; 1513 if (!_server_send(msg, size, cb, fe))
1335 1514 return 0;
1336 free(msg);
1337 1515
1338 return ret; 1516 return ret;
1339} 1517}
@@ -1465,6 +1643,23 @@ _glyph_map_remap_check(Glyph_Map *map)
1465{ 1643{
1466 Eina_Bool changed = EINA_FALSE; 1644 Eina_Bool changed = EINA_FALSE;
1467 int oldcount; 1645 int oldcount;
1646 const void *oldmap = map->mempool.data;
1647
1648 if (!map->mempool.f)
1649 {
1650 WRN("The glyph mempool has been closed.");
1651 if (!map->mempool.path)
1652 return EINA_FALSE;
1653
1654 DBG("Remapping from %s", map->mempool.path);
1655 map->mempool.f = eina_file_open(map->mempool.path, EINA_TRUE);
1656 if (!map->mempool.f)
1657 {
1658 ERR("Could not open shm file: %d %m", errno);
1659 return EINA_FALSE;
1660 }
1661 map->mempool.size = 0;
1662 }
1468 1663
1469 if (eina_file_refresh(map->mempool.f) 1664 if (eina_file_refresh(map->mempool.f)
1470 || (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size)) 1665 || (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size))
@@ -1481,6 +1676,7 @@ _glyph_map_remap_check(Glyph_Map *map)
1481 changed = EINA_TRUE; 1676 changed = EINA_TRUE;
1482 1677
1483 // Remap loaded glyphs 1678 // Remap loaded glyphs
1679#warning Infinite loop again here. FONT RELOAD IS STILL BROKEN.
1484 EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs, 1680 EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs,
1485 CS_Glyph_Out, map_entry) 1681 CS_Glyph_Out, map_entry)
1486 { 1682 {
@@ -1496,6 +1692,7 @@ _glyph_map_remap_check(Glyph_Map *map)
1496 oldcount = map->index.count; 1692 oldcount = map->index.count;
1497 _shared_index_remap_check(&map->index, sizeof(Glyph_Data)); 1693 _shared_index_remap_check(&map->index, sizeof(Glyph_Data));
1498 changed |= (oldcount != map->index.count); 1694 changed |= (oldcount != map->index.count);
1695 changed |= (oldmap != map->mempool.data);
1499 1696
1500 return changed; 1697 return changed;
1501} 1698}
@@ -1571,7 +1768,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
1571 return cnt; 1768 return cnt;
1572} 1769}
1573 1770
1574static void 1771static Eina_Bool
1575_glyph_request_cb(void *data, const void *msg, int size) 1772_glyph_request_cb(void *data, const void *msg, int size)
1576{ 1773{
1577 const Msg_Font_Glyphs_Loaded *resp = msg; 1774 const Msg_Font_Glyphs_Loaded *resp = msg;
@@ -1583,11 +1780,56 @@ _glyph_request_cb(void *data, const void *msg, int size)
1583 const char *name; 1780 const char *name;
1584 int pos; 1781 int pos;
1585 1782
1586 if (resp->base.type == CSERVE2_ERROR) 1783 if (!fe || !fe->fash[grd->hints])
1587 goto end; 1784 goto end;
1588 1785
1589 if (!fe->fash[grd->hints]) 1786 if (resp->base.type == CSERVE2_ERROR)
1590 goto end; 1787 {
1788 const Msg_Error *err = msg;
1789 ERR("We got an error message when waiting for glyphs: %d", err->error);
1790
1791 if (err->error == CSERVE2_NOT_LOADED)
1792 {
1793 DBG("Reloading the font: %s from %s", fe->name, fe->source);
1794
1795 // This will crash for sure.
1796 /*
1797 for (i = 0; i < 3; i++)
1798 {
1799 if (fe->fash[i])
1800 fash_gl_free(fe->fash[i]);
1801 fe->fash[i] = NULL;
1802 }
1803 _glyphs_map_free(fe->map);
1804 fe->map = NULL;
1805 */
1806
1807 if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD)))
1808 {
1809 ERR("Failed to send font load message");
1810 free(data);
1811 return EINA_TRUE;
1812 }
1813
1814#warning Code path to check
1815
1816 if (fe->glyphs_queue_count)
1817 _glyph_request_server_send(fe, grd->hints, EINA_FALSE);
1818
1819 if (fe->glyphs_used_count)
1820 _glyph_request_server_send(fe, grd->hints, EINA_TRUE);
1821
1822 DBG("Resending glyph load message now...");
1823 if (!_request_resend(err->base.rid))
1824 {
1825 free(data);
1826 return EINA_TRUE;
1827 }
1828 return EINA_FALSE;
1829 }
1830 free(data);
1831 return EINA_TRUE;
1832 }
1591 1833
1592 if (size <= (int) sizeof(*resp)) goto end; 1834 if (size <= (int) sizeof(*resp)) goto end;
1593 1835
@@ -1686,15 +1928,23 @@ _glyph_request_cb(void *data, const void *msg, int size)
1686 { 1928 {
1687 ERR("Failed to remap glyph mempool!"); 1929 ERR("Failed to remap glyph mempool!");
1688 gl->base.bitmap.buffer = NULL; 1930 gl->base.bitmap.buffer = NULL;
1931 //gl->base.bitmap.rows = 0;
1932 //gl->base.bitmap.width = 0;
1689 } 1933 }
1690 } 1934 }
1691 1935
1692 eina_clist_add_head(&fe->map->glyphs, &gl->map_entry); 1936 if (!eina_clist_element_is_linked(&gl->map_entry))
1937 eina_clist_add_head(&fe->map->glyphs, &gl->map_entry);
1693 } 1938 }
1694 } 1939 }
1695 1940
1941 free(grd);
1942 return EINA_TRUE;
1943
1696end: 1944end:
1945 ERR("An unknown error occured when waiting for glyph data!");
1697 free(grd); 1946 free(grd);
1947 return EINA_TRUE;
1698} 1948}
1699 1949
1700static unsigned int 1950static unsigned int
@@ -1782,12 +2032,12 @@ _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used
1782 else 2032 else
1783 cb = NULL; 2033 cb = NULL;
1784 2034
1785 if (_server_send(msg, size, cb, grd)) 2035 ret = msg->base.rid;
1786 ret = msg->base.rid; 2036 if (!_server_send(msg, size, cb, grd))
1787 else 2037 {
1788 free(grd); 2038 free(grd);
1789 2039 return 0;
1790 free(msg); 2040 }
1791 2041
1792 return ret; 2042 return ret;
1793} 2043}
@@ -1916,7 +2166,12 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx,
1916#endif 2166#endif
1917 2167
1918 if (out->rid) 2168 if (out->rid)
1919 _server_dispatch_until(out->rid); 2169 if (!_server_dispatch_until(out->rid))
2170 {
2171 ERR("failed to load the requested glyphs");
2172 //fe->failed = EINA_TRUE;
2173 //return NULL;
2174 }
1920 2175
1921 // promote shm and font entry in lru or something 2176 // promote shm and font entry in lru or something
1922 2177
@@ -2050,10 +2305,7 @@ _server_index_list_set(Msg_Base *data, int size)
2050 SHARED_BUFFER_PATH_MAX) != 0) 2305 SHARED_BUFFER_PATH_MAX) != 0)
2051 { 2306 {
2052 DBG("Updating string indexes shm to: '%s'", msg->strings_index_path); 2307 DBG("Updating string indexes shm to: '%s'", msg->strings_index_path);
2053 eina_file_map_free(_index.strings_index.f, _index.strings_index.data); 2308 _shared_index_close(&_index.strings_index);
2054 eina_file_close(_index.strings_index.f);
2055 _index.strings_index.f = NULL;
2056 _index.strings_index.data = NULL;
2057 } 2309 }
2058 2310
2059 eina_strlcpy(_index.strings_entries.path, msg->strings_entries_path, SHARED_BUFFER_PATH_MAX); 2311 eina_strlcpy(_index.strings_entries.path, msg->strings_entries_path, SHARED_BUFFER_PATH_MAX);