summaryrefslogtreecommitdiff
path: root/legacy/ecore/src/lib/ecore/ecore_main.c
diff options
context:
space:
mode:
authorMike McCormack <mj.mccormack@samsung.com>2011-07-28 12:01:16 +0000
committerMike McCormack <mikem@ring3k.org>2011-07-28 12:01:16 +0000
commit5c8256e337e00c66eaa65a0d7802af91b237d2f1 (patch)
treedec210bd9084d759eba7ffab77898823e22b356e /legacy/ecore/src/lib/ecore/ecore_main.c
parentf46934e94fc1e956fc6fb45455767e963e1ce19a (diff)
ecore: Add main loop thread safety
Thread safety is disabled by default. Enable it with --enable-thread-safety Should cover timers, events, animators, idlers and fd handlers. Tested with Enlightenment and elementary_test. Signed-off-by: Mike McCormack <mj.mccormack@samsung.com> SVN revision: 61851
Diffstat (limited to '')
-rw-r--r--legacy/ecore/src/lib/ecore/ecore_main.c109
1 files changed, 86 insertions, 23 deletions
diff --git a/legacy/ecore/src/lib/ecore/ecore_main.c b/legacy/ecore/src/lib/ecore/ecore_main.c
index 53d7a8aa32..688c2c5895 100644
--- a/legacy/ecore/src/lib/ecore/ecore_main.c
+++ b/legacy/ecore/src/lib/ecore/ecore_main.c
@@ -488,6 +488,7 @@ _ecore_main_gsource_prepare(GSource *source __UNUSED__, gint *next_time)
488{ 488{
489 gboolean ready = FALSE; 489 gboolean ready = FALSE;
490 490
491 _ecore_lock();
491 in_main_loop++; 492 in_main_loop++;
492 493
493 if (!ecore_idling && !_ecore_glib_idle_enterer_called) 494 if (!ecore_idling && !_ecore_glib_idle_enterer_called)
@@ -566,6 +567,7 @@ _ecore_main_gsource_prepare(GSource *source __UNUSED__, gint *next_time)
566 567
567 in_main_loop--; 568 in_main_loop--;
568 INF("leave, timeout = %d", *next_time); 569 INF("leave, timeout = %d", *next_time);
570 _ecore_unlock();
569 571
570 /* ready if we're not running (about to quit) */ 572 /* ready if we're not running (about to quit) */
571 return ready; 573 return ready;
@@ -576,6 +578,7 @@ _ecore_main_gsource_check(GSource *source __UNUSED__)
576{ 578{
577 gboolean ret = FALSE; 579 gboolean ret = FALSE;
578 580
581 _ecore_lock();
579 in_main_loop++; 582 in_main_loop++;
580 583
581 /* check if old timers expired */ 584 /* check if old timers expired */
@@ -615,6 +618,7 @@ _ecore_main_gsource_check(GSource *source __UNUSED__)
615 ret = (0.0 == _ecore_timer_next_get()); 618 ret = (0.0 == _ecore_timer_next_get());
616 619
617 in_main_loop--; 620 in_main_loop--;
621 _ecore_unlock();
618 622
619 return ret; 623 return ret;
620} 624}
@@ -626,6 +630,7 @@ _ecore_main_gsource_dispatch(GSource *source __UNUSED__, GSourceFunc callback __
626 gboolean events_ready, timers_ready, idlers_ready; 630 gboolean events_ready, timers_ready, idlers_ready;
627 double next_time; 631 double next_time;
628 632
633 _ecore_lock();
629 _ecore_time_loop_time = ecore_time_get(); 634 _ecore_time_loop_time = ecore_time_get();
630 _ecore_timer_enable_new(); 635 _ecore_timer_enable_new();
631 next_time = _ecore_timer_next_get(); 636 next_time = _ecore_timer_next_get();
@@ -684,6 +689,7 @@ _ecore_main_gsource_dispatch(GSource *source __UNUSED__, GSourceFunc callback __
684 } 689 }
685 690
686 in_main_loop--; 691 in_main_loop--;
692 _ecore_unlock();
687 693
688 return TRUE; /* what should be returned here? */ 694 return TRUE; /* what should be returned here? */
689} 695}
@@ -822,9 +828,10 @@ _ecore_main_loop_shutdown(void)
822EAPI void 828EAPI void
823ecore_main_loop_iterate(void) 829ecore_main_loop_iterate(void)
824{ 830{
825 ECORE_MAIN_LOOP_ASSERT();
826#ifndef USE_G_MAIN_LOOP 831#ifndef USE_G_MAIN_LOOP
832 _ecore_lock();
827 _ecore_main_loop_iterate_internal(1); 833 _ecore_main_loop_iterate_internal(1);
834 _ecore_unlock();
828#else 835#else
829 g_main_context_iteration(NULL, 1); 836 g_main_context_iteration(NULL, 1);
830#endif 837#endif
@@ -851,12 +858,13 @@ ecore_main_loop_iterate(void)
851EAPI void 858EAPI void
852ecore_main_loop_begin(void) 859ecore_main_loop_begin(void)
853{ 860{
854 ECORE_MAIN_LOOP_ASSERT();
855#ifndef USE_G_MAIN_LOOP 861#ifndef USE_G_MAIN_LOOP
862 _ecore_lock();
856 in_main_loop++; 863 in_main_loop++;
857 while (do_quit == 0) _ecore_main_loop_iterate_internal(0); 864 while (do_quit == 0) _ecore_main_loop_iterate_internal(0);
858 do_quit = 0; 865 do_quit = 0;
859 in_main_loop--; 866 in_main_loop--;
867 _ecore_unlock();
860#else 868#else
861 ecore_main_loop = g_main_loop_new(NULL, FALSE); 869 ecore_main_loop = g_main_loop_new(NULL, FALSE);
862 g_main_loop_run(ecore_main_loop); 870 g_main_loop_run(ecore_main_loop);
@@ -968,11 +976,11 @@ EAPI Ecore_Fd_Handler *
968ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, 976ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data,
969 Ecore_Fd_Cb buf_func, const void *buf_data) 977 Ecore_Fd_Cb buf_func, const void *buf_data)
970{ 978{
971 Ecore_Fd_Handler *fdh; 979 Ecore_Fd_Handler *fdh = NULL;
972 980
973 ECORE_MAIN_LOOP_ASSERT(); 981 _ecore_lock();
974 982
975 if ((fd < 0) || (flags == 0) || (!func)) return NULL; 983 if ((fd < 0) || (flags == 0) || (!func)) goto unlock;
976 984
977 fdh = calloc(1, sizeof(Ecore_Fd_Handler)); 985 fdh = calloc(1, sizeof(Ecore_Fd_Handler));
978 if (!fdh) return NULL; 986 if (!fdh) return NULL;
@@ -985,7 +993,7 @@ ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func
985 int err = errno; 993 int err = errno;
986 ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); 994 ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err));
987 free(fdh); 995 free(fdh);
988 return NULL; 996 goto unlock;
989 } 997 }
990 fdh->read_active = EINA_FALSE; 998 fdh->read_active = EINA_FALSE;
991 fdh->write_active = EINA_FALSE; 999 fdh->write_active = EINA_FALSE;
@@ -1000,6 +1008,9 @@ ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func
1000 fd_handlers = (Ecore_Fd_Handler *) 1008 fd_handlers = (Ecore_Fd_Handler *)
1001 eina_inlist_append(EINA_INLIST_GET(fd_handlers), 1009 eina_inlist_append(EINA_INLIST_GET(fd_handlers),
1002 EINA_INLIST_GET(fdh)); 1010 EINA_INLIST_GET(fdh));
1011unlock:
1012 _ecore_unlock();
1013
1003 return fdh; 1014 return fdh;
1004} 1015}
1005 1016
@@ -1047,18 +1058,20 @@ ecore_main_win32_handler_add(void *h __UNUSED__, Ecore_Win32_Handle_Cb func __UN
1047EAPI void * 1058EAPI void *
1048ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) 1059ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
1049{ 1060{
1050 ECORE_MAIN_LOOP_ASSERT(); 1061 void *ret = NULL;
1062
1063 _ecore_lock();
1051 1064
1052 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) 1065 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1053 { 1066 {
1054 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, 1067 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1055 "ecore_main_fd_handler_del"); 1068 "ecore_main_fd_handler_del");
1056 return NULL; 1069 goto unlock;
1057 } 1070 }
1058 if (fd_handler->delete_me) 1071 if (fd_handler->delete_me)
1059 { 1072 {
1060 ERR("fdh %p deleted twice", fd_handler); 1073 ERR("fdh %p deleted twice", fd_handler);
1061 return NULL; 1074 goto unlock;
1062 } 1075 }
1063 1076
1064 _ecore_main_fdh_poll_del(fd_handler); 1077 _ecore_main_fdh_poll_del(fd_handler);
@@ -1068,7 +1081,10 @@ ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
1068 fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler); 1081 fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler);
1069 if (fd_handler->buf_func && fd_handlers_with_buffer) 1082 if (fd_handler->buf_func && fd_handlers_with_buffer)
1070 fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler); 1083 fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler);
1071 return fd_handler->data; 1084 ret = fd_handler->data;
1085unlock:
1086 _ecore_unlock();
1087 return ret;
1072} 1088}
1073 1089
1074#ifdef _WIN32 1090#ifdef _WIN32
@@ -1114,13 +1130,13 @@ ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
1114EAPI void 1130EAPI void
1115ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data) 1131ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data)
1116{ 1132{
1117 ECORE_MAIN_LOOP_ASSERT(); 1133 _ecore_lock();
1118 1134
1119 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) 1135 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1120 { 1136 {
1121 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, 1137 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1122 "ecore_main_fd_handler_prepare_callback_set"); 1138 "ecore_main_fd_handler_prepare_callback_set");
1123 return; 1139 goto unlock;
1124 } 1140 }
1125 fd_handler->prep_func = func; 1141 fd_handler->prep_func = func;
1126 fd_handler->prep_data = (void *)data; 1142 fd_handler->prep_data = (void *)data;
@@ -1128,6 +1144,8 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_F
1128 (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler)))) 1144 (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
1129 /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */ 1145 /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
1130 fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler); 1146 fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
1147unlock:
1148 _ecore_unlock();
1131} 1149}
1132 1150
1133/** 1151/**
@@ -1139,13 +1157,20 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_F
1139EAPI int 1157EAPI int
1140ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) 1158ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
1141{ 1159{
1160 int fd = -1;
1161
1162 _ecore_lock();
1163
1142 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) 1164 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1143 { 1165 {
1144 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, 1166 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1145 "ecore_main_fd_handler_fd_get"); 1167 "ecore_main_fd_handler_fd_get");
1146 return -1; 1168 goto unlock;
1147 } 1169 }
1148 return fd_handler->fd; 1170 fd = fd_handler->fd;
1171unlock:
1172 _ecore_unlock();
1173 return fd;
1149} 1174}
1150 1175
1151/** 1176/**
@@ -1162,17 +1187,19 @@ ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_
1162{ 1187{
1163 int ret = EINA_FALSE; 1188 int ret = EINA_FALSE;
1164 1189
1165 ECORE_MAIN_LOOP_ASSERT(); 1190 _ecore_lock();
1166 1191
1167 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) 1192 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1168 { 1193 {
1169 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, 1194 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1170 "ecore_main_fd_handler_active_get"); 1195 "ecore_main_fd_handler_active_get");
1171 return EINA_FALSE; 1196 goto unlock;
1172 } 1197 }
1173 if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE; 1198 if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
1174 if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE; 1199 if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
1175 if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE; 1200 if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
1201unlock:
1202 _ecore_unlock();
1176 return ret; 1203 return ret;
1177} 1204}
1178 1205
@@ -1187,13 +1214,13 @@ ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_
1187{ 1214{
1188 int ret; 1215 int ret;
1189 1216
1190 ECORE_MAIN_LOOP_ASSERT(); 1217 _ecore_lock();
1191 1218
1192 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) 1219 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1193 { 1220 {
1194 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, 1221 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1195 "ecore_main_fd_handler_active_set"); 1222 "ecore_main_fd_handler_active_set");
1196 return; 1223 goto unlock;
1197 } 1224 }
1198 fd_handler->flags = flags; 1225 fd_handler->flags = flags;
1199 ret = _ecore_main_fdh_poll_modify(fd_handler); 1226 ret = _ecore_main_fdh_poll_modify(fd_handler);
@@ -1201,6 +1228,8 @@ ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_
1201 { 1228 {
1202 ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret)); 1229 ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret));
1203 } 1230 }
1231unlock:
1232 _ecore_unlock();
1204} 1233}
1205 1234
1206/** 1235/**
@@ -1275,8 +1304,15 @@ _ecore_main_prepare_handlers(void)
1275 } 1304 }
1276 if (!fdh->delete_me && fdh->prep_func) 1305 if (!fdh->delete_me && fdh->prep_func)
1277 { 1306 {
1307 Ecore_Fd_Prep_Cb prep_func;
1308 void *prep_data;
1309
1310 prep_func = fdh->prep_func;
1311 prep_data = fdh->prep_data;
1278 fdh->references++; 1312 fdh->references++;
1279 fdh->prep_func(fdh->prep_data, fdh); 1313 _ecore_unlock();
1314 prep_func(prep_data, fdh);
1315 _ecore_lock();
1280 fdh->references--; 1316 fdh->references--;
1281 } 1317 }
1282 else 1318 else
@@ -1360,7 +1396,9 @@ _ecore_main_select(double timeout)
1360 1396
1361 if (_ecore_signal_count_get()) return -1; 1397 if (_ecore_signal_count_get()) return -1;
1362 1398
1399 _ecore_unlock();
1363 ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); 1400 ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
1401 _ecore_lock();
1364 1402
1365 _ecore_time_loop_time = ecore_time_get(); 1403 _ecore_time_loop_time = ecore_time_get();
1366 if (ret < 0) 1404 if (ret < 0)
@@ -1424,9 +1462,13 @@ _ecore_main_fd_handlers_bads_rem(void)
1424 ERR("Found bad fd at index %d", fdh->fd); 1462 ERR("Found bad fd at index %d", fdh->fd);
1425 if (fdh->flags & ECORE_FD_ERROR) 1463 if (fdh->flags & ECORE_FD_ERROR)
1426 { 1464 {
1465 Eina_Bool ret;
1427 ERR("Fd set for error! calling user"); 1466 ERR("Fd set for error! calling user");
1428 fdh->references++; 1467 fdh->references++;
1429 if (!fdh->func(fdh->data, fdh)) 1468 _ecore_unlock();
1469 ret = fdh->func(fdh->data, fdh);
1470 _ecore_lock();
1471 if (!ret)
1430 { 1472 {
1431 ERR("Fd function err returned 0, remove it"); 1473 ERR("Fd function err returned 0, remove it");
1432 if (!fdh->delete_me) 1474 if (!fdh->delete_me)
@@ -1546,8 +1588,12 @@ _ecore_main_fd_handlers_call(void)
1546 (fdh->write_active) || 1588 (fdh->write_active) ||
1547 (fdh->error_active)) 1589 (fdh->error_active))
1548 { 1590 {
1591 Eina_Bool ret;
1549 fdh->references++; 1592 fdh->references++;
1550 if (!fdh->func(fdh->data, fdh)) 1593 _ecore_unlock();
1594 ret = fdh->func(fdh->data, fdh);
1595 _ecore_lock();
1596 if (!ret)
1551 { 1597 {
1552 if (!fdh->delete_me) 1598 if (!fdh->delete_me)
1553 { 1599 {
@@ -1595,10 +1641,27 @@ _ecore_main_fd_handlers_buf_call(void)
1595 } 1641 }
1596 if ((!fdh->delete_me) && fdh->buf_func) 1642 if ((!fdh->delete_me) && fdh->buf_func)
1597 { 1643 {
1644 Ecore_Fd_Cb buf_func;
1645 void *buf_data;
1646 Eina_Bool r;
1647
1648 /* copy data before releasing lock */
1649 buf_func = fdh->buf_func;
1650 buf_data = fdh->buf_data;
1598 fdh->references++; 1651 fdh->references++;
1599 if (fdh->buf_func(fdh->buf_data, fdh)) 1652 _ecore_unlock();
1653 r = buf_func(buf_data, fdh);
1654 _ecore_lock();
1655 if (r)
1600 { 1656 {
1601 ret |= fdh->func(fdh->data, fdh); 1657 Ecore_Fd_Cb func;
1658 void *data;
1659
1660 func = fdh->func;
1661 data = fdh->data;
1662 _ecore_unlock();
1663 ret |= func(data, fdh);
1664 _ecore_lock();
1602 fdh->read_active = EINA_TRUE; 1665 fdh->read_active = EINA_TRUE;
1603 _ecore_try_add_to_call_list(fdh); 1666 _ecore_try_add_to_call_list(fdh);
1604 } 1667 }