summaryrefslogtreecommitdiff
path: root/src/lib/ecore
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-08-09 00:02:04 -0300
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-08-09 12:14:00 -0300
commitca39ff976e576dd917becf989f28fdf149c9f1d0 (patch)
treec6a9c7afd5fa82af8ac8222562c467b88c7b6c43 /src/lib/ecore
parent0a9c78896b875c265c80177a6b5fde16b7820339 (diff)
ecore: detect and emit event on system time changed.
If we have timerfd then we can set a timer with special features (ABSTIME | CANCELON) to be notified if its offset to monotonic time change, effectively this will alert us if user called settimeofday() or similar method to change system time. This code was inspired by Enlightenment's clock module.
Diffstat (limited to 'src/lib/ecore')
-rw-r--r--src/lib/ecore/ecore_main.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 0500052a73..3a6210d71b 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -127,6 +127,13 @@ epoll_ctl(int epfd EINA_UNUSED,
127# endif 127# endif
128#endif /* HAVE_SYS_TIMERFD_H */ 128#endif /* HAVE_SYS_TIMERFD_H */
129 129
130#ifndef TFD_TIMER_ABSTIME
131# define TFD_TIMER_ABSTIME (1 << 0)
132#endif
133#ifndef TFD_TIMER_CANCELON_SET
134# define TFD_TIMER_CANCELON_SET (1 << 1)
135#endif
136
130#ifndef HAVE_TIMERFD_CREATE 137#ifndef HAVE_TIMERFD_CREATE
131static inline int 138static inline int
132timerfd_create(int clockid EINA_UNUSED, 139timerfd_create(int clockid EINA_UNUSED,
@@ -763,6 +770,67 @@ static GSourceFuncs ecore_gsource_funcs =
763 770
764#endif 771#endif
765 772
773#ifdef HAVE_SYS_TIMERFD_H
774static int realtime_fd = -1;
775
776static void detect_time_changes_start(void);
777static Eina_Bool
778_realtime_update(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
779{
780 char buf[64];
781
782 if (read(realtime_fd, buf, sizeof(buf)) >= 0) return EINA_TRUE;
783
784 DBG("system clock changed");
785 ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
786
787 close(realtime_fd);
788 realtime_fd = -1;
789 detect_time_changes_start();
790 return EINA_FALSE;
791}
792#endif
793
794static void
795detect_time_changes_start(void)
796{
797#ifdef HAVE_SYS_TIMERFD_H
798 struct itimerspec its;
799
800 if (realtime_fd >= 0) return;
801
802 realtime_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
803 if (realtime_fd < 0) return;
804
805 memset(&its, 0, sizeof(its));
806 if (timerfd_settime(realtime_fd,
807 TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET,
808 &its, NULL) < 0)
809 {
810 WRN("Couldn't arm timerfd to detect clock changes: %s",
811 strerror(errno));
812 close(realtime_fd);
813 realtime_fd = -1;
814 return;
815 }
816
817 ecore_main_fd_handler_add(realtime_fd, ECORE_FD_READ,
818 _realtime_update, NULL, NULL, NULL);
819#endif
820}
821
822static void
823detect_time_changes_stop(void)
824{
825#ifdef HAVE_SYS_TIMERFD_H
826 if (realtime_fd > 0)
827 {
828 close(realtime_fd);
829 realtime_fd = -1;
830 }
831#endif
832}
833
766void 834void
767_ecore_main_loop_init(void) 835_ecore_main_loop_init(void)
768{ 836{
@@ -818,6 +886,8 @@ _ecore_main_loop_init(void)
818 CRIT("Failed to attach glib source to default context"); 886 CRIT("Failed to attach glib source to default context");
819 } 887 }
820#endif 888#endif
889
890 detect_time_changes_start();
821} 891}
822 892
823void 893void
@@ -831,6 +901,8 @@ _ecore_main_loop_shutdown(void)
831 } 901 }
832#endif 902#endif
833 903
904 detect_time_changes_stop();
905
834 if (epoll_fd >= 0) 906 if (epoll_fd >= 0)
835 { 907 {
836 close(epoll_fd); 908 close(epoll_fd);