summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derek.foreman.samsung@gmail.com>2018-07-26 15:37:00 -0500
committerDerek Foreman <derek.foreman.samsung@gmail.com>2019-02-13 10:33:40 -0600
commit66ce295fc9d09a0ba1454d25ca7b4e32a51c9553 (patch)
tree4b7bbff08919f2e69f1d92824e7aaf6e9c86216a
parent46885653bc0467f88042bb110fdc973b2258f69c (diff)
ecore_main: Add ECORE_FD_ALWAYS flag
This allows an fd handler to be called after select exits unconditionally. Our wayland client code needs this to be thread safe, as it needs to call prepare_read before entering select, and then either read or cancel_read after select. Signed-off-by: Derek Foreman <derek.foreman.samsung@gmail.com> Reviewed-by: Chris Michael <cp.michael@samsung.com> Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D7914
Diffstat (limited to '')
-rw-r--r--src/lib/ecore/Ecore_Common.h8
-rw-r--r--src/lib/ecore/ecore_main.c50
-rw-r--r--src/lib/ecore/ecore_private.h1
3 files changed, 46 insertions, 13 deletions
diff --git a/src/lib/ecore/Ecore_Common.h b/src/lib/ecore/Ecore_Common.h
index 9b777d7364..de515c57ed 100644
--- a/src/lib/ecore/Ecore_Common.h
+++ b/src/lib/ecore/Ecore_Common.h
@@ -1388,7 +1388,13 @@ enum _Ecore_Fd_Handler_Flags
1388{ 1388{
1389 ECORE_FD_READ = 1, /**< Fd Read mask */ 1389 ECORE_FD_READ = 1, /**< Fd Read mask */
1390 ECORE_FD_WRITE = 2, /**< Fd Write mask */ 1390 ECORE_FD_WRITE = 2, /**< Fd Write mask */
1391 ECORE_FD_ERROR = 4 /**< Fd Error mask */ 1391 ECORE_FD_ERROR = 4, /**< Fd Error mask */
1392 /* ECORE_FD_ALWAYS is intended to fix a problem with wayland
1393 * and threads. It causes the fd handler to be called
1394 * in any state, so wayland libs can call read_cancel
1395 * if nothing is available to read. Everyone else should
1396 * stay away. */
1397 ECORE_FD_ALWAYS = 8, /**< Fd Always mask - DO NOT USE! */
1392}; 1398};
1393typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags; 1399typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
1394 1400
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 2c1a2ef868..42d554cf0f 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -248,7 +248,7 @@ _ecore_try_add_to_call_list(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, Ecore_Fd_Han
248 DBG("next_ready"); 248 DBG("next_ready");
249 return; 249 return;
250 } 250 }
251 if (fdh->read_active || fdh->write_active || fdh->error_active) 251 if (fdh->read_active || fdh->write_active || fdh->error_active || (fdh->flags & ECORE_FD_ALWAYS))
252 { 252 {
253 DBG("added"); 253 DBG("added");
254 // make sure next_ready is non-null by pointing to ourselves 254 // make sure next_ready is non-null by pointing to ourselves
@@ -583,6 +583,10 @@ _ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
583 fdh->write_active = EINA_TRUE; 583 fdh->write_active = EINA_TRUE;
584 fdh->error_active = EINA_TRUE; 584 fdh->error_active = EINA_TRUE;
585 } 585 }
586 /* We'll add this one anyway outside this function,
587 don't want it twice */
588 if (fdh->flags & ECORE_FD_ALWAYS)
589 continue;
586 590
587 _ecore_try_add_to_call_list(obj, pd, fdh); 591 _ecore_try_add_to_call_list(obj, pd, fdh);
588 } 592 }
@@ -1357,6 +1361,9 @@ _ecore_main_fd_handler_add(Eo *obj,
1357 if (is_file) 1361 if (is_file)
1358 pd->file_fd_handlers = eina_list_append 1362 pd->file_fd_handlers = eina_list_append
1359 (pd->file_fd_handlers, fdh); 1363 (pd->file_fd_handlers, fdh);
1364 if (fdh->flags & ECORE_FD_ALWAYS)
1365 pd->always_fd_handlers = eina_list_append
1366 (pd->always_fd_handlers, fdh);
1360 pd->fd_handlers = (Ecore_Fd_Handler *) 1367 pd->fd_handlers = (Ecore_Fd_Handler *)
1361 eina_inlist_append(EINA_INLIST_GET(pd->fd_handlers), 1368 eina_inlist_append(EINA_INLIST_GET(pd->fd_handlers),
1362 EINA_INLIST_GET(fdh)); 1369 EINA_INLIST_GET(fdh));
@@ -1664,6 +1671,9 @@ _ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd)
1664 if (pd->file_fd_handlers) 1671 if (pd->file_fd_handlers)
1665 pd->file_fd_handlers = 1672 pd->file_fd_handlers =
1666 eina_list_free(pd->file_fd_handlers); 1673 eina_list_free(pd->file_fd_handlers);
1674 if (pd->always_fd_handlers)
1675 pd->always_fd_handlers =
1676 eina_list_free(pd->always_fd_handlers);
1667 if (pd->fd_handlers_to_delete) 1677 if (pd->fd_handlers_to_delete)
1668 pd->fd_handlers_to_delete = 1678 pd->fd_handlers_to_delete =
1669 eina_list_free(pd->fd_handlers_to_delete); 1679 eina_list_free(pd->fd_handlers_to_delete);
@@ -1741,7 +1751,7 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
1741 fd_set rfds, wfds, exfds; 1751 fd_set rfds, wfds, exfds;
1742 Ecore_Fd_Handler *fdh; 1752 Ecore_Fd_Handler *fdh;
1743 Eina_List *l; 1753 Eina_List *l;
1744 int max_fd, ret; 1754 int max_fd, ret, outval;
1745#ifndef _WIN32 1755#ifndef _WIN32
1746 int err_no; 1756 int err_no;
1747#endif 1757#endif
@@ -1785,17 +1795,17 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
1785 { 1795 {
1786 if (!fdh->delete_me) 1796 if (!fdh->delete_me)
1787 { 1797 {
1788 if (fdh->flags & ECORE_FD_READ) 1798 if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
1789 { 1799 {
1790 FD_SET(fdh->fd, &rfds); 1800 FD_SET(fdh->fd, &rfds);
1791 if (fdh->fd > max_fd) max_fd = fdh->fd; 1801 if (fdh->fd > max_fd) max_fd = fdh->fd;
1792 } 1802 }
1793 if (fdh->flags & ECORE_FD_WRITE) 1803 if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
1794 { 1804 {
1795 FD_SET(fdh->fd, &wfds); 1805 FD_SET(fdh->fd, &wfds);
1796 if (fdh->fd > max_fd) max_fd = fdh->fd; 1806 if (fdh->fd > max_fd) max_fd = fdh->fd;
1797 } 1807 }
1798 if (fdh->flags & ECORE_FD_ERROR) 1808 if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
1799 { 1809 {
1800 FD_SET(fdh->fd, &exfds); 1810 FD_SET(fdh->fd, &exfds);
1801 if (fdh->fd > max_fd) max_fd = fdh->fd; 1811 if (fdh->fd > max_fd) max_fd = fdh->fd;
@@ -1815,17 +1825,17 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
1815 { 1825 {
1816 if (!fdh->delete_me) 1826 if (!fdh->delete_me)
1817 { 1827 {
1818 if (fdh->flags & ECORE_FD_READ) 1828 if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
1819 { 1829 {
1820 FD_SET(fdh->fd, &rfds); 1830 FD_SET(fdh->fd, &rfds);
1821 if (fdh->fd > max_fd) max_fd = fdh->fd; 1831 if (fdh->fd > max_fd) max_fd = fdh->fd;
1822 } 1832 }
1823 if (fdh->flags & ECORE_FD_WRITE) 1833 if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
1824 { 1834 {
1825 FD_SET(fdh->fd, &wfds); 1835 FD_SET(fdh->fd, &wfds);
1826 if (fdh->fd > max_fd) max_fd = fdh->fd; 1836 if (fdh->fd > max_fd) max_fd = fdh->fd;
1827 } 1837 }
1828 if (fdh->flags & ECORE_FD_ERROR) 1838 if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
1829 { 1839 {
1830 FD_SET(fdh->fd, &exfds); 1840 FD_SET(fdh->fd, &exfds);
1831 if (fdh->fd > max_fd) max_fd = fdh->fd; 1841 if (fdh->fd > max_fd) max_fd = fdh->fd;
@@ -1851,7 +1861,11 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
1851 if (ret < 0) 1861 if (ret < 0)
1852 { 1862 {
1853#ifndef _WIN32 1863#ifndef _WIN32
1854 if (err_no == EINTR) return -1; 1864 if (err_no == EINTR)
1865 {
1866 outval = -1;
1867 goto BAIL;
1868 }
1855 else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd); 1869 else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd);
1856#endif 1870#endif
1857 } 1871 }
@@ -1890,13 +1904,22 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
1890 _ecore_try_add_to_call_list(obj, pd, fdh); 1904 _ecore_try_add_to_call_list(obj, pd, fdh);
1891 } 1905 }
1892 } 1906 }
1907 outval = 1;
1908 goto BAIL;
1909 }
1910 outval = 0;
1911BAIL:
1912 EINA_LIST_FOREACH(pd->always_fd_handlers, l, fdh)
1913 _ecore_try_add_to_call_list(obj, pd, fdh);
1914
1915 if (ret > 0)
1916 {
1893 _ecore_main_fd_handlers_cleanup(obj, pd); 1917 _ecore_main_fd_handlers_cleanup(obj, pd);
1894#ifdef _WIN32 1918#ifdef _WIN32
1895 _ecore_main_win32_handlers_cleanup(obj, pd); 1919 _ecore_main_win32_handlers_cleanup(obj, pd);
1896#endif 1920#endif
1897 return 1;
1898 } 1921 }
1899 return 0; 1922 return outval || pd->always_fd_handlers;
1900} 1923}
1901 1924
1902#endif 1925#endif
@@ -2017,6 +2040,8 @@ _ecore_main_fd_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
2017 EINA_INLIST_GET(fdh)); 2040 EINA_INLIST_GET(fdh));
2018 if (fdh->file) 2041 if (fdh->file)
2019 pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh); 2042 pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh);
2043 if (fdh->flags & ECORE_FD_ALWAYS)
2044 pd->always_fd_handlers = eina_list_remove(pd->always_fd_handlers, fdh);
2020 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); 2045 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
2021 ecore_fd_handler_mp_free(fdh); 2046 ecore_fd_handler_mp_free(fdh);
2022 pd->fd_handlers_to_delete = eina_list_remove_list 2047 pd->fd_handlers_to_delete = eina_list_remove_list
@@ -2074,7 +2099,8 @@ _ecore_main_fd_handlers_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
2074 { 2099 {
2075 if ((fdh->read_active) || 2100 if ((fdh->read_active) ||
2076 (fdh->write_active) || 2101 (fdh->write_active) ||
2077 (fdh->error_active)) 2102 (fdh->error_active) ||
2103 (fdh->flags & ECORE_FD_ALWAYS))
2078 { 2104 {
2079 fdh->references++; 2105 fdh->references++;
2080 if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) 2106 if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index 4e980d9123..2cb3b36d27 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -138,6 +138,7 @@ struct _Efl_Loop_Data
138 Ecore_Fd_Handler *fd_handlers; 138 Ecore_Fd_Handler *fd_handlers;
139 Eina_List *fd_handlers_with_prep; 139 Eina_List *fd_handlers_with_prep;
140 Eina_List *file_fd_handlers; 140 Eina_List *file_fd_handlers;
141 Eina_List *always_fd_handlers;
141 Eina_List *fd_handlers_with_buffer; 142 Eina_List *fd_handlers_with_buffer;
142 Eina_List *fd_handlers_to_delete; 143 Eina_List *fd_handlers_to_delete;
143 Ecore_Fd_Handler *fd_handlers_to_call; 144 Ecore_Fd_Handler *fd_handlers_to_call;