diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-10-10 09:26:42 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-10-28 15:47:16 +0900 |
commit | c8e6f9e5f9d20d67b49a0355b1b42b1ba8689291 (patch) | |
tree | 1040a3df18f7b8a893745516d0c6cadf43a06f10 /src/lib/evas/cserve2 | |
parent | 660ad6e4a414c42364ab555f6f77354a97d04610 (diff) |
evas/cserve2: Fix font reloading after cserve2 restart.
Well it LOOKS like it's working properly.
Clients can safely keep running after cserve2 crashed and
restarted.
Diffstat (limited to 'src/lib/evas/cserve2')
-rw-r--r-- | src/lib/evas/cserve2/evas_cs2_client.c | 316 | ||||
-rw-r--r-- | src/lib/evas/cserve2/evas_cs2_utils.c | 2 |
2 files changed, 212 insertions, 106 deletions
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c index 64e335afdf..6fc1a4a112 100644 --- a/src/lib/evas/cserve2/evas_cs2_client.c +++ b/src/lib/evas/cserve2/evas_cs2_client.c | |||
@@ -60,6 +60,9 @@ typedef struct _Client_Request Client_Request; | |||
60 | 60 | ||
61 | static int cserve2_init = 0; | 61 | static int cserve2_init = 0; |
62 | static int socketfd = -1; | 62 | static int socketfd = -1; |
63 | static int sr_size = 0; | ||
64 | static int sr_got = 0; | ||
65 | static char *sr_buf = NULL; | ||
63 | 66 | ||
64 | static unsigned int _rid_count = 0; | 67 | static unsigned int _rid_count = 0; |
65 | static unsigned int _file_id = 0; | 68 | static unsigned int _file_id = 0; |
@@ -206,6 +209,7 @@ _server_connect(void) | |||
206 | #endif | 209 | #endif |
207 | 210 | ||
208 | socketfd = s; | 211 | socketfd = s; |
212 | sr_size = 0; | ||
209 | 213 | ||
210 | DBG("connected to cserve2 server."); | 214 | DBG("connected to cserve2 server."); |
211 | return EINA_TRUE; | 215 | return EINA_TRUE; |
@@ -217,6 +221,7 @@ _server_disconnect(void) | |||
217 | if (socketfd != -1) | 221 | if (socketfd != -1) |
218 | close(socketfd); | 222 | close(socketfd); |
219 | socketfd = -1; | 223 | socketfd = -1; |
224 | sr_size = 0; | ||
220 | } | 225 | } |
221 | 226 | ||
222 | static void | 227 | static void |
@@ -415,10 +420,6 @@ on_error: | |||
415 | } | 420 | } |
416 | } | 421 | } |
417 | 422 | ||
418 | static int sr_size = 0; | ||
419 | static int sr_got = 0; | ||
420 | static char *sr_buf = NULL; | ||
421 | |||
422 | static void * | 423 | static void * |
423 | _server_read(int *size) | 424 | _server_read(int *size) |
424 | { | 425 | { |
@@ -773,7 +774,6 @@ _image_loaded_cb(void *data, const void *msg_received, int size) | |||
773 | 774 | ||
774 | if (msg_error->error == CSERVE2_NOT_LOADED) | 775 | if (msg_error->error == CSERVE2_NOT_LOADED) |
775 | { | 776 | { |
776 | #warning Code path to check: cserve2 restart | ||
777 | DBG("Trying to reopen the image"); | 777 | DBG("Trying to reopen the image"); |
778 | ie->open_rid = _image_open_server_send(ie); | 778 | ie->open_rid = _image_open_server_send(ie); |
779 | if (_server_dispatch_until(ie->open_rid)) | 779 | if (_server_dispatch_until(ie->open_rid)) |
@@ -1418,6 +1418,7 @@ struct _CS_Glyph_Out | |||
1418 | Shared_Buffer *sb; | 1418 | Shared_Buffer *sb; |
1419 | unsigned int offset; | 1419 | unsigned int offset; |
1420 | unsigned int size; | 1420 | unsigned int size; |
1421 | unsigned int hint; | ||
1421 | Eina_Bool used; | 1422 | Eina_Bool used; |
1422 | int refcount; | 1423 | int refcount; |
1423 | int pending_ref; | 1424 | int pending_ref; |
@@ -1450,6 +1451,9 @@ _glyph_out_free(void *gl) | |||
1450 | { | 1451 | { |
1451 | CS_Glyph_Out *glout = gl; | 1452 | CS_Glyph_Out *glout = gl; |
1452 | 1453 | ||
1454 | if (glout->used) | ||
1455 | eina_clist_remove(&glout->used_list); | ||
1456 | |||
1453 | if (glout->map) | 1457 | if (glout->map) |
1454 | { | 1458 | { |
1455 | eina_clist_remove(&glout->map_entry); | 1459 | eina_clist_remove(&glout->map_entry); |
@@ -1657,16 +1661,72 @@ _glyph_map_open(Font_Entry *fe, const char *indexpath, const char *datapath) | |||
1657 | } | 1661 | } |
1658 | 1662 | ||
1659 | static Eina_Bool | 1663 | static Eina_Bool |
1660 | _glyph_map_remap_check(Glyph_Map *map) | 1664 | _glyph_map_remap_check(Glyph_Map *map, const char *idxpath, const char *datapath) |
1661 | { | 1665 | { |
1662 | Eina_Bool changed = EINA_FALSE; | 1666 | Eina_Bool changed = EINA_FALSE; |
1667 | Shared_Buffer *oldbuf = NULL; | ||
1663 | int oldcount; | 1668 | int oldcount; |
1664 | 1669 | ||
1665 | if (eina_file_refresh(map->mempool.f) | 1670 | // Note: Since the shm name contains cserve2's PID it should most likely |
1666 | || (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size)) | 1671 | // always change in case of crash/restart |
1672 | |||
1673 | if ((datapath && strcmp(datapath, map->mempool.path)) | ||
1674 | || (idxpath && strcmp(idxpath, map->index.path))) | ||
1675 | { | ||
1676 | CS_Glyph_Out *gl, *cursor; | ||
1677 | |||
1678 | WRN("Glyph pool has changed location."); | ||
1679 | |||
1680 | // Force reopening index | ||
1681 | _shared_index_close(&map->index); | ||
1682 | eina_strlcpy(map->index.path, idxpath, SHARED_BUFFER_PATH_MAX); | ||
1683 | |||
1684 | // Reopen mempool | ||
1685 | if (map->mempool.refcount > 0) | ||
1686 | { | ||
1687 | oldbuf = calloc(1, sizeof(Glyph_Map)); | ||
1688 | oldbuf->f = map->mempool.f; | ||
1689 | oldbuf->data = map->mempool.data; | ||
1690 | oldbuf->size = map->mempool.size; | ||
1691 | oldbuf->refcount = map->mempool.refcount; | ||
1692 | eina_strlcpy(oldbuf->path, map->mempool.path, SHARED_BUFFER_PATH_MAX); | ||
1693 | map->mempool_lru = eina_list_append(map->mempool_lru, oldbuf); | ||
1694 | } | ||
1695 | else | ||
1696 | { | ||
1697 | eina_file_map_free(map->mempool.f, map->mempool.data); | ||
1698 | eina_file_close(map->mempool.f); | ||
1699 | } | ||
1700 | |||
1701 | eina_strlcpy(map->mempool.path, datapath, SHARED_BUFFER_PATH_MAX); | ||
1702 | map->mempool.f = eina_file_open(datapath, EINA_TRUE); | ||
1703 | map->mempool.data = eina_file_map_all(map->mempool.f, EINA_FILE_RANDOM); | ||
1704 | map->mempool.size = eina_file_size_get(map->mempool.f); | ||
1705 | map->mempool.refcount = 0; | ||
1706 | |||
1707 | EINA_CLIST_FOR_EACH_ENTRY_SAFE(gl, cursor, &map->glyphs, | ||
1708 | CS_Glyph_Out, map_entry) | ||
1709 | { | ||
1710 | if (!gl->refcount) | ||
1711 | { | ||
1712 | gl->sb = NULL; | ||
1713 | gl->base.bitmap.buffer = NULL; | ||
1714 | } | ||
1715 | else | ||
1716 | gl->sb = oldbuf; | ||
1717 | } | ||
1718 | |||
1719 | if (!eina_clist_count(&map->glyphs)) | ||
1720 | return EINA_TRUE; | ||
1721 | |||
1722 | map->index.generation_id = _index.generation_id; | ||
1723 | _shared_index_remap_check(&map->index, sizeof(Glyph_Data)); | ||
1724 | return EINA_TRUE; | ||
1725 | } | ||
1726 | else if (eina_file_refresh(map->mempool.f) || | ||
1727 | (eina_file_size_get(map->mempool.f) != (size_t) map->mempool.size)) | ||
1667 | { | 1728 | { |
1668 | CS_Glyph_Out *gl; | 1729 | CS_Glyph_Out *gl; |
1669 | Shared_Buffer *oldbuf = NULL; | ||
1670 | 1730 | ||
1671 | WRN("Glyph pool has been resized."); | 1731 | WRN("Glyph pool has been resized."); |
1672 | 1732 | ||
@@ -1682,21 +1742,18 @@ _glyph_map_remap_check(Glyph_Map *map) | |||
1682 | oldbuf->f = eina_file_dup(map->mempool.f); | 1742 | oldbuf->f = eina_file_dup(map->mempool.f); |
1683 | oldbuf->data = map->mempool.data; | 1743 | oldbuf->data = map->mempool.data; |
1684 | oldbuf->size = map->mempool.size; | 1744 | oldbuf->size = map->mempool.size; |
1685 | oldbuf->refcount = map->mempool.refcount; | 1745 | //oldbuf->refcount = map->mempool.refcount; |
1686 | eina_strlcpy(oldbuf->path, map->mempool.path, SHARED_BUFFER_PATH_MAX); | 1746 | eina_strlcpy(oldbuf->path, map->mempool.path, SHARED_BUFFER_PATH_MAX); |
1687 | map->mempool_lru = eina_list_append(map->mempool_lru, oldbuf); | 1747 | map->mempool_lru = eina_list_append(map->mempool_lru, oldbuf); |
1688 | } | 1748 | } |
1689 | else | 1749 | else |
1690 | { | 1750 | eina_file_map_free(map->mempool.f, map->mempool.data); |
1691 | eina_file_map_free(map->mempool.f, map->mempool.data); | ||
1692 | } | ||
1693 | map->mempool.data = eina_file_map_all(map->mempool.f, EINA_FILE_RANDOM); | 1751 | map->mempool.data = eina_file_map_all(map->mempool.f, EINA_FILE_RANDOM); |
1694 | map->mempool.size = eina_file_size_get(map->mempool.f); | 1752 | map->mempool.size = eina_file_size_get(map->mempool.f); |
1695 | map->mempool.refcount = 0; | 1753 | map->mempool.refcount = 0; |
1696 | changed = EINA_TRUE; | ||
1697 | 1754 | ||
1698 | // Remap unused but loaded glyphs | 1755 | // Remap unused but loaded glyphs |
1699 | EINA_CLIST_FOR_EACH_ENTRY(gl, &map->fe->map->glyphs, | 1756 | EINA_CLIST_FOR_EACH_ENTRY(gl, &map->glyphs, |
1700 | CS_Glyph_Out, map_entry) | 1757 | CS_Glyph_Out, map_entry) |
1701 | { | 1758 | { |
1702 | if (!gl->refcount) | 1759 | if (!gl->refcount) |
@@ -1705,9 +1762,15 @@ _glyph_map_remap_check(Glyph_Map *map) | |||
1705 | gl->base.bitmap.buffer = (unsigned char *) gl->sb->data + gl->offset; | 1762 | gl->base.bitmap.buffer = (unsigned char *) gl->sb->data + gl->offset; |
1706 | } | 1763 | } |
1707 | else if (oldbuf) | 1764 | else if (oldbuf) |
1708 | gl->sb = oldbuf; | 1765 | { |
1709 | else CRIT("Invalid refcount state"); | 1766 | gl->sb = oldbuf; |
1767 | gl->sb->refcount++; | ||
1768 | } | ||
1769 | else | ||
1770 | ERR("Invalid refcounting here."); | ||
1710 | } | 1771 | } |
1772 | |||
1773 | changed = EINA_TRUE; | ||
1711 | } | 1774 | } |
1712 | 1775 | ||
1713 | map->index.generation_id = _index.generation_id; | 1776 | map->index.generation_id = _index.generation_id; |
@@ -1723,11 +1786,11 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints) | |||
1723 | { | 1786 | { |
1724 | Eina_Bool changed = EINA_FALSE; | 1787 | Eina_Bool changed = EINA_FALSE; |
1725 | int cnt = 0; | 1788 | int cnt = 0; |
1789 | const char *idxpath = NULL, *datapath = NULL; | ||
1726 | 1790 | ||
1727 | if (!fe->map) | 1791 | if (!fe->map) |
1728 | { | 1792 | { |
1729 | const Font_Data *fd; | 1793 | const Font_Data *fd; |
1730 | const char *idxpath, *datapath; | ||
1731 | 1794 | ||
1732 | fd = _shared_font_entry_data_find(fe); | 1795 | fd = _shared_font_entry_data_find(fe); |
1733 | if (!fd) return -1; | 1796 | if (!fd) return -1; |
@@ -1740,7 +1803,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints) | |||
1740 | changed = EINA_TRUE; | 1803 | changed = EINA_TRUE; |
1741 | } | 1804 | } |
1742 | 1805 | ||
1743 | changed |= _glyph_map_remap_check(fe->map); | 1806 | changed |= _glyph_map_remap_check(fe->map, idxpath, datapath); |
1744 | if (changed && fe->map && fe->map->index.data && fe->map->mempool.data) | 1807 | if (changed && fe->map && fe->map->index.data && fe->map->mempool.data) |
1745 | { | 1808 | { |
1746 | CS_Glyph_Out *gl; | 1809 | CS_Glyph_Out *gl; |
@@ -1762,12 +1825,16 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints) | |||
1762 | if (!gl) | 1825 | if (!gl) |
1763 | { | 1826 | { |
1764 | gl = calloc(1, sizeof(*gl)); | 1827 | gl = calloc(1, sizeof(*gl)); |
1828 | gl->idx = gd->index; | ||
1765 | eina_clist_element_init(&gl->map_entry); | 1829 | eina_clist_element_init(&gl->map_entry); |
1830 | eina_clist_element_init(&gl->used_list); | ||
1831 | fash_gl_add(fe->fash[hints], gl->idx, gl); | ||
1766 | } | 1832 | } |
1767 | gl->map = fe->map; | 1833 | gl->map = fe->map; |
1768 | gl->sb = &fe->map->mempool; | 1834 | gl->sb = &fe->map->mempool; |
1769 | gl->offset = gd->offset; | 1835 | gl->offset = gd->offset; |
1770 | gl->size = gd->size; | 1836 | gl->size = gd->size; |
1837 | gl->hint = gd->hint; | ||
1771 | gl->base.bitmap.rows = gd->rows; | 1838 | gl->base.bitmap.rows = gd->rows; |
1772 | gl->base.bitmap.width = gd->width; | 1839 | gl->base.bitmap.width = gd->width; |
1773 | gl->base.bitmap.pitch = gd->pitch; | 1840 | gl->base.bitmap.pitch = gd->pitch; |
@@ -1798,8 +1865,8 @@ _glyph_request_cb(void *data, const void *msg, int size) | |||
1798 | Font_Entry *fe = grd->fe; | 1865 | Font_Entry *fe = grd->fe; |
1799 | const char *buf; | 1866 | const char *buf; |
1800 | int i, nglyphs; | 1867 | int i, nglyphs; |
1801 | int namelen; | 1868 | int shmname_len, idxname_len; |
1802 | const char *name; | 1869 | const char *shmname, *idxname; |
1803 | int pos; | 1870 | int pos; |
1804 | 1871 | ||
1805 | if (!fe || !fe->fash[grd->hints]) | 1872 | if (!fe || !fe->fash[grd->hints]) |
@@ -1822,8 +1889,6 @@ _glyph_request_cb(void *data, const void *msg, int size) | |||
1822 | return EINA_TRUE; | 1889 | return EINA_TRUE; |
1823 | } | 1890 | } |
1824 | 1891 | ||
1825 | #warning Code path to check: cserve2 restart | ||
1826 | |||
1827 | if (fe->glyphs_queue_count) | 1892 | if (fe->glyphs_queue_count) |
1828 | _glyph_request_server_send(fe, grd->hints, EINA_FALSE); | 1893 | _glyph_request_server_send(fe, grd->hints, EINA_FALSE); |
1829 | 1894 | ||
@@ -1850,35 +1915,32 @@ _glyph_request_cb(void *data, const void *msg, int size) | |||
1850 | pos += sizeof(int); | 1915 | pos += sizeof(int); |
1851 | if (pos > size) goto end; | 1916 | if (pos > size) goto end; |
1852 | 1917 | ||
1853 | memcpy(&namelen, buf, sizeof(int)); | 1918 | memcpy(&shmname_len, buf, sizeof(int)); |
1919 | buf += sizeof(int); | ||
1920 | |||
1921 | pos += shmname_len + sizeof(int); | ||
1922 | if (pos > size) goto end; | ||
1923 | |||
1924 | shmname = buf; | ||
1925 | buf += shmname_len; | ||
1926 | |||
1927 | memcpy(&idxname_len, buf, sizeof(int)); | ||
1854 | buf += sizeof(int); | 1928 | buf += sizeof(int); |
1855 | 1929 | ||
1856 | pos += namelen + sizeof(int); | 1930 | pos += idxname_len + sizeof(int); |
1857 | if (pos > size) goto end; | 1931 | if (pos > size) goto end; |
1858 | 1932 | ||
1859 | name = buf; //eina_stringshare_add_length(buf, namelen); | 1933 | idxname = buf; |
1860 | buf += namelen; | 1934 | buf += idxname_len; |
1861 | 1935 | ||
1862 | memcpy(&nglyphs, buf, sizeof(int)); | 1936 | memcpy(&nglyphs, buf, sizeof(int)); |
1863 | buf += sizeof(int); | 1937 | buf += sizeof(int); |
1864 | 1938 | ||
1865 | if (!fe->map) | 1939 | if (fe->map) |
1866 | { | 1940 | _glyph_map_remap_check(fe->map, idxname, shmname); |
1867 | const Font_Data *fd; | ||
1868 | const char *idxpath = NULL, *datapath; | ||
1869 | 1941 | ||
1870 | fd = _shared_font_entry_data_find(fe); | 1942 | if (!fe->map) |
1871 | if (fd) | 1943 | fe->map = _glyph_map_open(fe, idxname, shmname); |
1872 | { | ||
1873 | idxpath = _shared_string_get(fd->glyph_index_shm); | ||
1874 | datapath = _shared_string_get(fd->mempool_shm); | ||
1875 | } | ||
1876 | else | ||
1877 | datapath = name; | ||
1878 | fe->map = _glyph_map_open(fe, idxpath, datapath); | ||
1879 | } | ||
1880 | else | ||
1881 | _glyph_map_remap_check(fe->map); | ||
1882 | 1944 | ||
1883 | for (i = 0; i < nglyphs; i++) | 1945 | for (i = 0; i < nglyphs; i++) |
1884 | { | 1946 | { |
@@ -1918,42 +1980,30 @@ _glyph_request_cb(void *data, const void *msg, int size) | |||
1918 | } | 1980 | } |
1919 | 1981 | ||
1920 | gl = fash_gl_find(fe->fash[hints], idx); | 1982 | gl = fash_gl_find(fe->fash[hints], idx); |
1921 | if (gl) | 1983 | if (!gl) |
1922 | { | 1984 | { |
1923 | gl->map = fe->map; | 1985 | gl = calloc(1, sizeof(*gl)); |
1924 | gl->sb = &fe->map->mempool; | 1986 | gl->idx = idx; |
1925 | gl->offset = offset; | 1987 | eina_clist_element_init(&gl->map_entry); |
1926 | gl->size = glsize; | 1988 | eina_clist_element_init(&gl->used_list); |
1927 | gl->base.bitmap.rows = rows; | 1989 | fash_gl_add(fe->fash[hints], idx, gl); |
1928 | gl->base.bitmap.width = width; | ||
1929 | gl->base.bitmap.pitch = pitch; | ||
1930 | gl->base.bitmap.buffer = | ||
1931 | (unsigned char *) gl->map->mempool.data + gl->offset; | ||
1932 | gl->base.bitmap.num_grays = num_grays; | ||
1933 | gl->base.bitmap.pixel_mode = pixel_mode; | ||
1934 | gl->rid = 0; | ||
1935 | |||
1936 | if (gl->offset + glsize > (size_t) fe->map->mempool.size) | ||
1937 | { | ||
1938 | WRN("Glyph offset out of the buffer. Refreshing map."); | ||
1939 | if (!_glyph_map_remap_check(fe->map)) | ||
1940 | { | ||
1941 | // This is very problematic. Evas expects the glyph to | ||
1942 | // be valid after this point. | ||
1943 | // We could set rows & width to 0 to avoid crashes but | ||
1944 | // then display might be b0rken. | ||
1945 | // Also, all the previous glyphs might be out of the | ||
1946 | // memory range now, so we're in a pretty bad situation. | ||
1947 | CRIT("Failed to remap glyph mempool!"); | ||
1948 | gl->base.bitmap.buffer = NULL; | ||
1949 | //gl->base.bitmap.rows = 0; | ||
1950 | //gl->base.bitmap.width = 0; | ||
1951 | } | ||
1952 | } | ||
1953 | |||
1954 | if (!eina_clist_element_is_linked(&gl->map_entry)) | ||
1955 | eina_clist_add_head(&fe->map->glyphs, &gl->map_entry); | ||
1956 | } | 1990 | } |
1991 | gl->map = fe->map; | ||
1992 | gl->sb = &fe->map->mempool; | ||
1993 | gl->offset = offset; | ||
1994 | gl->size = glsize; | ||
1995 | gl->hint = hints; | ||
1996 | gl->base.bitmap.rows = rows; | ||
1997 | gl->base.bitmap.width = width; | ||
1998 | gl->base.bitmap.pitch = pitch; | ||
1999 | gl->base.bitmap.buffer = | ||
2000 | (unsigned char *) gl->map->mempool.data + gl->offset; | ||
2001 | gl->base.bitmap.num_grays = num_grays; | ||
2002 | gl->base.bitmap.pixel_mode = pixel_mode; | ||
2003 | gl->rid = 0; | ||
2004 | |||
2005 | if (!eina_clist_element_is_linked(&gl->map_entry)) | ||
2006 | eina_clist_add_head(&fe->map->glyphs, &gl->map_entry); | ||
1957 | } | 2007 | } |
1958 | 2008 | ||
1959 | free(grd); | 2009 | free(grd); |
@@ -2023,14 +2073,14 @@ _glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used | |||
2023 | if (!used) | 2073 | if (!used) |
2024 | { | 2074 | { |
2025 | gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, map_entry); | 2075 | gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, map_entry); |
2026 | gl->rid = msg->base.rid; | ||
2027 | eina_clist_remove(&gl->map_entry); | 2076 | eina_clist_remove(&gl->map_entry); |
2077 | gl->rid = msg->base.rid; | ||
2028 | } | 2078 | } |
2029 | else | 2079 | else |
2030 | { | 2080 | { |
2031 | gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, used_list); | 2081 | gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, used_list); |
2032 | gl->used = EINA_FALSE; | ||
2033 | eina_clist_remove(&gl->used_list); | 2082 | eina_clist_remove(&gl->used_list); |
2083 | gl->used = EINA_FALSE; | ||
2034 | } | 2084 | } |
2035 | glyphs[nglyphs++] = gl->idx; | 2085 | glyphs[nglyphs++] = gl->idx; |
2036 | } | 2086 | } |
@@ -2082,6 +2132,17 @@ evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flag | |||
2082 | } | 2132 | } |
2083 | 2133 | ||
2084 | glyph = fash_gl_find(fash, idx); | 2134 | glyph = fash_gl_find(fash, idx); |
2135 | |||
2136 | // Check map is still valid, otherwise we want to request the glyph again | ||
2137 | if (glyph && glyph->map && (&glyph->map->mempool != glyph->sb)) | ||
2138 | { | ||
2139 | if (!glyph->refcount) | ||
2140 | { | ||
2141 | fash_gl_del(fash, idx); | ||
2142 | glyph = NULL; | ||
2143 | } | ||
2144 | } | ||
2145 | |||
2085 | if (!glyph) | 2146 | if (!glyph) |
2086 | { | 2147 | { |
2087 | glyph = calloc(1, sizeof(*glyph)); | 2148 | glyph = calloc(1, sizeof(*glyph)); |
@@ -2092,8 +2153,7 @@ evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flag | |||
2092 | } | 2153 | } |
2093 | else if (!glyph->used) | 2154 | else if (!glyph->used) |
2094 | { | 2155 | { |
2095 | // FIXME: This code path seems unused (not logical) | 2156 | // This can happen in case of cserve2 restart. (corner case) |
2096 | CRIT("Is this code path even valid?"); | ||
2097 | eina_clist_add_head(&fe->glyphs_used, &glyph->used_list); | 2157 | eina_clist_add_head(&fe->glyphs_used, &glyph->used_list); |
2098 | fe->glyphs_used_count++; | 2158 | fe->glyphs_used_count++; |
2099 | glyph->used = EINA_TRUE; | 2159 | glyph->used = EINA_TRUE; |
@@ -2135,6 +2195,21 @@ evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags h | |||
2135 | if (!glyph->map) | 2195 | if (!glyph->map) |
2136 | return EINA_TRUE; | 2196 | return EINA_TRUE; |
2137 | 2197 | ||
2198 | // Glyph was stored in a dead buffer. Need to reload it :) | ||
2199 | if (&glyph->map->mempool != glyph->sb) | ||
2200 | { | ||
2201 | if (!glyph->refcount) | ||
2202 | { | ||
2203 | fash_gl_del(fash, idx); | ||
2204 | return EINA_FALSE; | ||
2205 | } | ||
2206 | else | ||
2207 | { | ||
2208 | // Keep old buffer, it is still valid. | ||
2209 | return EINA_TRUE; | ||
2210 | } | ||
2211 | } | ||
2212 | |||
2138 | if (glyph->used) | 2213 | if (glyph->used) |
2139 | return EINA_TRUE; | 2214 | return EINA_TRUE; |
2140 | 2215 | ||
@@ -2170,6 +2245,7 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, | |||
2170 | return NULL; | 2245 | return NULL; |
2171 | } | 2246 | } |
2172 | 2247 | ||
2248 | try_again: | ||
2173 | out = fash_gl_find(fash, idx); | 2249 | out = fash_gl_find(fash, idx); |
2174 | if (!out) | 2250 | if (!out) |
2175 | { | 2251 | { |
@@ -2179,17 +2255,35 @@ evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, | |||
2179 | return NULL; | 2255 | return NULL; |
2180 | } | 2256 | } |
2181 | 2257 | ||
2258 | if (out->map && (&out->map->mempool != out->sb)) | ||
2259 | { | ||
2260 | // If the map is not valid, this is a good time to reload the glyph. | ||
2261 | if (!out->refcount) | ||
2262 | { | ||
2263 | fash_gl_del(fash, idx); | ||
2264 | if (!evas_cserve2_font_glyph_request(fe, idx, hints)) | ||
2265 | return NULL; | ||
2266 | |||
2267 | DBG("Requesting again this glyph: %d", idx); | ||
2268 | goto try_again; | ||
2269 | } | ||
2270 | else // Can't reload now since the map is used. | ||
2271 | return &out->base; | ||
2272 | } | ||
2273 | |||
2274 | |||
2182 | #if USE_SHARED_INDEX | 2275 | #if USE_SHARED_INDEX |
2183 | #warning TODO MUST REIMPLEMENT THIS FUNCTION | 2276 | // FIXME/TODO: Reimplement the following function. |
2277 | // This is probably not the best point to call it, though. | ||
2184 | //_font_entry_glyph_map_rebuild_check(fe, hints); | 2278 | //_font_entry_glyph_map_rebuild_check(fe, hints); |
2185 | #endif | 2279 | #endif |
2186 | 2280 | ||
2187 | if (out->rid) | 2281 | if (out->rid) |
2188 | if (!_server_dispatch_until(out->rid)) | 2282 | if (!_server_dispatch_until(out->rid)) |
2189 | { | 2283 | { |
2190 | ERR("failed to load the requested glyphs"); | 2284 | ERR("failed to load the requested glyphs, resending request"); |
2191 | //fe->failed = EINA_TRUE; | 2285 | if (!_request_resend(out->rid)) |
2192 | //return NULL; | 2286 | return NULL; |
2193 | } | 2287 | } |
2194 | 2288 | ||
2195 | // promote shm and font entry in lru or something | 2289 | // promote shm and font entry in lru or something |
@@ -2203,10 +2297,6 @@ evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref) | |||
2203 | 2297 | ||
2204 | EINA_SAFETY_ON_FALSE_RETURN(evas_cserve2_use_get()); | 2298 | EINA_SAFETY_ON_FALSE_RETURN(evas_cserve2_use_get()); |
2205 | 2299 | ||
2206 | // For debugging only. | ||
2207 | static int inc = 0, dec = 0; | ||
2208 | if (incref) inc++; else dec++; | ||
2209 | |||
2210 | // glout = (CS_Glyph_Out *) glyph; | 2300 | // glout = (CS_Glyph_Out *) glyph; |
2211 | glout = (CS_Glyph_Out *) (((char *) glyph) - offsetof(CS_Glyph_Out, base)); | 2301 | glout = (CS_Glyph_Out *) (((char *) glyph) - offsetof(CS_Glyph_Out, base)); |
2212 | 2302 | ||
@@ -2229,13 +2319,19 @@ evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref) | |||
2229 | return; | 2319 | return; |
2230 | } | 2320 | } |
2231 | 2321 | ||
2232 | EINA_SAFETY_ON_FALSE_RETURN(glout->refcount > 0); | 2322 | EINA_SAFETY_ON_FALSE_RETURN((glout->refcount + glout->pending_ref) > 0); |
2233 | EINA_SAFETY_ON_NULL_RETURN(glout->sb); | 2323 | if (!glout->sb) |
2324 | { | ||
2325 | glout->pending_ref--; | ||
2326 | return; | ||
2327 | } | ||
2328 | |||
2234 | if (glout->pending_ref) | 2329 | if (glout->pending_ref) |
2235 | { | 2330 | { |
2331 | if (!glout->refcount && (glout->pending_ref > 0)) | ||
2332 | glout->sb->refcount++; | ||
2236 | glout->refcount += glout->pending_ref; | 2333 | glout->refcount += glout->pending_ref; |
2237 | glout->pending_ref = 0; | 2334 | glout->pending_ref = 0; |
2238 | glout->sb->refcount++; | ||
2239 | } | 2335 | } |
2240 | 2336 | ||
2241 | glout->refcount--; | 2337 | glout->refcount--; |
@@ -2244,24 +2340,19 @@ evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref) | |||
2244 | EINA_SAFETY_ON_FALSE_RETURN(glout->sb->refcount > 0); | 2340 | EINA_SAFETY_ON_FALSE_RETURN(glout->sb->refcount > 0); |
2245 | glout->sb->refcount--; | 2341 | glout->sb->refcount--; |
2246 | 2342 | ||
2247 | if (!glout->sb->refcount) | ||
2248 | DBG("Shared buffer %p reached refcount ZERO. %d/%d", glout->sb, dec, inc); | ||
2249 | |||
2250 | //if (glout->sb->data != glout->map->mempool.data) | ||
2251 | if (glout->sb != &glout->map->mempool) | 2343 | if (glout->sb != &glout->map->mempool) |
2252 | { | 2344 | { |
2253 | if (!glout->sb->refcount) | 2345 | if (!glout->sb->refcount) |
2254 | { | 2346 | { |
2255 | DBG("Glyph shared buffer reached refcount 0. Unmapping."); | 2347 | DBG("Glyph shared buffer reached refcount 0. Unmapping %p from %s", |
2348 | glout->sb->data, glout->sb->path); | ||
2256 | glout->map->mempool_lru = | 2349 | glout->map->mempool_lru = |
2257 | eina_list_remove(glout->map->mempool_lru, glout->sb); | 2350 | eina_list_remove(glout->map->mempool_lru, glout->sb); |
2258 | eina_file_map_free(glout->sb->f, glout->sb->data); | 2351 | eina_file_map_free(glout->sb->f, glout->sb->data); |
2259 | eina_file_close(glout->sb->f); | 2352 | eina_file_close(glout->sb->f); |
2260 | free(glout->sb); | 2353 | free(glout->sb); |
2261 | } | 2354 | } |
2262 | glout->sb = &glout->map->mempool; | 2355 | fash_gl_del(glout->map->fe->fash[glout->hint], glout->idx); |
2263 | glout->base.bitmap.buffer = | ||
2264 | (unsigned char *) glout->sb->data + glout->offset; | ||
2265 | } | 2356 | } |
2266 | } | 2357 | } |
2267 | } | 2358 | } |
@@ -2281,14 +2372,17 @@ _string_index_refresh(void) | |||
2281 | && _index.strings_index.path[0]) | 2372 | && _index.strings_index.path[0]) |
2282 | { | 2373 | { |
2283 | _index.strings_entries.f = eina_file_open(_index.strings_entries.path, EINA_TRUE); | 2374 | _index.strings_entries.f = eina_file_open(_index.strings_entries.path, EINA_TRUE); |
2284 | _index.strings_entries.size = eina_file_size_get(_index.strings_entries.f); | 2375 | if (_index.strings_entries.f) |
2376 | _index.strings_entries.size = eina_file_size_get(_index.strings_entries.f); | ||
2377 | else | ||
2378 | _index.strings_entries.size = 0; | ||
2285 | if (_index.strings_entries.size > 0) | 2379 | if (_index.strings_entries.size > 0) |
2286 | _index.strings_entries.data = eina_file_map_all(_index.strings_entries.f, EINA_FILE_RANDOM); | 2380 | _index.strings_entries.data = eina_file_map_all(_index.strings_entries.f, EINA_FILE_RANDOM); |
2287 | 2381 | ||
2288 | if (!_index.strings_entries.data) | 2382 | if (!_index.strings_entries.data) |
2289 | { | 2383 | { |
2290 | ERR("Could not map strings entries from: '%s'", _index.strings_entries.path); | 2384 | ERR("Could not map strings entries from: '%s'", _index.strings_entries.path); |
2291 | eina_file_close(_index.strings_entries.f); | 2385 | if (_index.strings_entries.f) eina_file_close(_index.strings_entries.f); |
2292 | _index.strings_entries.f = NULL; | 2386 | _index.strings_entries.f = NULL; |
2293 | _index.strings_entries.data = NULL; | 2387 | _index.strings_entries.data = NULL; |
2294 | ret = EINA_FALSE; | 2388 | ret = EINA_FALSE; |
@@ -2304,7 +2398,13 @@ _string_index_refresh(void) | |||
2304 | (!_index.strings_index.data && _index.strings_index.path[0])) | 2398 | (!_index.strings_index.data && _index.strings_index.path[0])) |
2305 | { | 2399 | { |
2306 | _index.strings_index.f = eina_file_open(_index.strings_index.path, EINA_TRUE); | 2400 | _index.strings_index.f = eina_file_open(_index.strings_index.path, EINA_TRUE); |
2307 | sz = eina_file_size_get(_index.strings_index.f); | 2401 | if (_index.strings_index.f) |
2402 | sz = eina_file_size_get(_index.strings_index.f); | ||
2403 | else | ||
2404 | { | ||
2405 | sz = 0; | ||
2406 | _index.strings_index.data = NULL; | ||
2407 | } | ||
2308 | if (sz >= sizeof(Shared_Array_Header)) | 2408 | if (sz >= sizeof(Shared_Array_Header)) |
2309 | _index.strings_index.data = eina_file_map_all(_index.strings_index.f, EINA_FILE_RANDOM); | 2409 | _index.strings_index.data = eina_file_map_all(_index.strings_index.f, EINA_FILE_RANDOM); |
2310 | 2410 | ||
@@ -2324,9 +2424,13 @@ _string_index_refresh(void) | |||
2324 | else | 2424 | else |
2325 | { | 2425 | { |
2326 | ERR("Could not map string indexes from %s", _index.strings_index.path); | 2426 | ERR("Could not map string indexes from %s", _index.strings_index.path); |
2327 | eina_file_close(_index.strings_index.f); | 2427 | if (_index.strings_index.f) eina_file_close(_index.strings_index.f); |
2328 | eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data); | 2428 | if (_index.strings_entries.f) |
2329 | eina_file_close(_index.strings_entries.f); | 2429 | { |
2430 | if (_index.strings_entries.data) | ||
2431 | eina_file_map_free(_index.strings_entries.f, _index.strings_entries.data); | ||
2432 | eina_file_close(_index.strings_entries.f); | ||
2433 | } | ||
2330 | _index.strings_index.f = NULL; | 2434 | _index.strings_index.f = NULL; |
2331 | _index.strings_entries.f = NULL; | 2435 | _index.strings_entries.f = NULL; |
2332 | _index.strings_entries.data = NULL; | 2436 | _index.strings_entries.data = NULL; |
diff --git a/src/lib/evas/cserve2/evas_cs2_utils.c b/src/lib/evas/cserve2/evas_cs2_utils.c index 5f738cad2c..cc4a99b5d5 100644 --- a/src/lib/evas/cserve2/evas_cs2_utils.c +++ b/src/lib/evas/cserve2/evas_cs2_utils.c | |||
@@ -56,6 +56,8 @@ fash_gl_free(Fash_Glyph2 *fash) | |||
56 | { | 56 | { |
57 | int i; | 57 | int i; |
58 | 58 | ||
59 | if (!fash) return; | ||
60 | |||
59 | for (i = 0; i < 256; i++) | 61 | for (i = 0; i < 256; i++) |
60 | if (fash->bucket[i]) _fash_gl2_free(fash, fash->bucket[i]); | 62 | if (fash->bucket[i]) _fash_gl2_free(fash, fash->bucket[i]); |
61 | free(fash); | 63 | free(fash); |