diff options
author | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2013-08-09 00:02:04 -0300 |
---|---|---|
committer | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2013-08-09 12:14:00 -0300 |
commit | ca39ff976e576dd917becf989f28fdf149c9f1d0 (patch) | |
tree | c6a9c7afd5fa82af8ac8222562c467b88c7b6c43 /src/lib/ecore | |
parent | 0a9c78896b875c265c80177a6b5fde16b7820339 (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.c | 72 |
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 |
131 | static inline int | 138 | static inline int |
132 | timerfd_create(int clockid EINA_UNUSED, | 139 | timerfd_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 | ||
774 | static int realtime_fd = -1; | ||
775 | |||
776 | static void detect_time_changes_start(void); | ||
777 | static 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 | |||
794 | static void | ||
795 | detect_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 | |||
822 | static void | ||
823 | detect_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 | |||
766 | void | 834 | void |
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 | ||
823 | void | 893 | void |
@@ -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); |