summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/ecore/ecore_main.c6
-rw-r--r--src/lib/eina/eina_file.c58
-rw-r--r--src/lib/eina/eina_file.h32
-rw-r--r--src/lib/eina/eina_file_common.c44
-rw-r--r--src/lib/eina/eina_file_common.h1
5 files changed, 115 insertions, 26 deletions
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index f7d248fc27..e898b6e0f3 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -331,6 +331,7 @@ _ecore_main_uv_poll_cb(uv_poll_t *handle, int status, int events)
331 { 331 {
332 DBG("not IDLE anymore"); 332 DBG("not IDLE anymore");
333 _ecore_main_uv_idling = EINA_FALSE; 333 _ecore_main_uv_idling = EINA_FALSE;
334 eina_file_statgen_next();
334 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 335 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
335 _ecore_animator_run_reset(); 336 _ecore_animator_run_reset();
336 } 337 }
@@ -794,6 +795,7 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
794 if (ecore_idling && events_ready) 795 if (ecore_idling && events_ready)
795 { 796 {
796 _ecore_animator_run_reset(); 797 _ecore_animator_run_reset();
798 eina_file_statgen_next();
797 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 799 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
798 ecore_idling = 0; 800 ecore_idling = 0;
799 } 801 }
@@ -808,6 +810,7 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
808 if (ecore_fds_ready || events_ready || timers_ready) 810 if (ecore_fds_ready || events_ready || timers_ready)
809 { 811 {
810 _ecore_animator_run_reset(); 812 _ecore_animator_run_reset();
813 eina_file_statgen_next();
811 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 814 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
812 ecore_idling = 0; 815 ecore_idling = 0;
813 } 816 }
@@ -867,6 +870,7 @@ _ecore_main_loop_timer_run(uv_timer_t *timer EINA_UNUSED)
867 if (_ecore_main_uv_idling) 870 if (_ecore_main_uv_idling)
868 { 871 {
869 _ecore_main_uv_idling = EINA_FALSE; 872 _ecore_main_uv_idling = EINA_FALSE;
873 eina_file_statgen_next();
870 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 874 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
871 _ecore_animator_run_reset(); 875 _ecore_animator_run_reset();
872 } 876 }
@@ -2243,6 +2247,7 @@ _ecore_main_loop_uv_prepare(uv_prepare_t *handle EINA_UNUSED)
2243 2247
2244 if (_ecore_main_uv_idling) 2248 if (_ecore_main_uv_idling)
2245 { 2249 {
2250 eina_file_statgen_next();
2246 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 2251 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
2247 _ecore_animator_run_reset(); 2252 _ecore_animator_run_reset();
2248 _ecore_main_uv_idling = EINA_FALSE; 2253 _ecore_main_uv_idling = EINA_FALSE;
@@ -2473,6 +2478,7 @@ process_all: //-*********************************************************
2473 if (!once_only) 2478 if (!once_only)
2474 { 2479 {
2475 _ecore_animator_run_reset(); // XXX: 2480 _ecore_animator_run_reset(); // XXX:
2481 eina_file_statgen_next();
2476 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL); 2482 efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
2477 } 2483 }
2478 // call the fd handler per fd that became alive... 2484 // call the fd handler per fd that became alive...
diff --git a/src/lib/eina/eina_file.c b/src/lib/eina/eina_file.c
index 068aa12e14..e334beaf21 100644
--- a/src/lib/eina/eina_file.c
+++ b/src/lib/eina/eina_file.c
@@ -795,46 +795,51 @@ eina_file_open(const char *path, Eina_Bool shared)
795 Eina_Stringshare *filename; 795 Eina_Stringshare *filename;
796 struct stat file_stat; 796 struct stat file_stat;
797 int fd = -1; 797 int fd = -1;
798 Eina_Statgen statgen;
798 799
799 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); 800 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
800 801
801 filename = eina_file_sanitize(path); 802 filename = eina_file_sanitize(path);
802 if (!filename) return NULL; 803 if (!filename) return NULL;
803 804
804 if (shared) 805 statgen = eina_file_statgen_get();
806 eina_lock_take(&_eina_file_lock_cache);
807 file = eina_hash_find(_eina_file_cache, filename);
808 statgen = eina_file_statgen_get();
809 if ((!file) || (file->statgen != statgen) || (statgen == 0))
805 { 810 {
811 if (shared)
812 {
806#ifdef HAVE_SHM_OPEN 813#ifdef HAVE_SHM_OPEN
807 fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); 814 fd = shm_open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
808 if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE))) 815 if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
809 goto on_error; 816 goto on_error;
810#else 817#else
811 goto on_error; 818 goto on_error;
812#endif 819#endif
813 } 820 }
814 else 821 else
815 { 822 {
816#ifdef HAVE_OPEN_CLOEXEC 823#ifdef HAVE_OPEN_CLOEXEC
817 fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO | O_CLOEXEC); 824 fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO | O_CLOEXEC);
818#else 825#else
819 fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); 826 fd = open(filename, O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO);
820 if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE))) 827 if ((fd != -1) && (!eina_file_close_on_exec(fd, EINA_TRUE)))
821 goto on_error; 828 goto on_error;
822#endif 829#endif
823 } 830 }
824 831 if (fd < 0) goto on_error;
825 if (fd < 0) goto on_error;
826
827 if (fstat(fd, &file_stat))
828 goto on_error;
829 832
830 eina_lock_take(&_eina_file_lock_cache); 833 if (fstat(fd, &file_stat))
834 goto on_error;
835 if (file) file->statgen = statgen;
831 836
832 file = eina_hash_find(_eina_file_cache, filename); 837 if ((file) && !_eina_file_timestamp_compare(file, &file_stat))
833 if ((file) && !_eina_file_timestamp_compare(file, &file_stat)) 838 {
834 { 839 file->delete_me = EINA_TRUE;
835 file->delete_me = EINA_TRUE; 840 eina_hash_del(_eina_file_cache, file->filename, file);
836 eina_hash_del(_eina_file_cache, file->filename, file); 841 file = NULL;
837 file = NULL; 842 }
838 } 843 }
839 844
840 if (!file) 845 if (!file)
@@ -874,7 +879,7 @@ eina_file_open(const char *path, Eina_Bool shared)
874 } 879 }
875 else 880 else
876 { 881 {
877 close(fd); 882 if (fd >= 0) close(fd);
878 n = file; 883 n = file;
879 } 884 }
880 eina_lock_take(&n->lock); 885 eina_lock_take(&n->lock);
@@ -886,6 +891,7 @@ eina_file_open(const char *path, Eina_Bool shared)
886 return n; 891 return n;
887 892
888 on_error: 893 on_error:
894 eina_lock_release(&_eina_file_lock_cache);
889 INF("Could not open file [%s].", filename); 895 INF("Could not open file [%s].", filename);
890 eina_stringshare_del(filename); 896 eina_stringshare_del(filename);
891 897
diff --git a/src/lib/eina/eina_file.h b/src/lib/eina/eina_file.h
index bc1543e26e..07a045e1b4 100644
--- a/src/lib/eina/eina_file.h
+++ b/src/lib/eina/eina_file.h
@@ -769,6 +769,38 @@ EAPI Eina_Bool eina_file_close_on_exec(int fd, Eina_Bool on);
769#include "eina_inline_file.x" 769#include "eina_inline_file.x"
770 770
771/** 771/**
772 * @typedef Eina_Statgen
773 * @brief Stat Generation count state with it being 0 when disabled or some other value that is comparable (== or !=) to a stored value and if it is not equal, then do the actual stat i/o work
774 * @since 1.23
775 */
776typedef unsigned int Eina_Statgen;
777
778/**
779 * @brief Force the stat generation counter to tick over so any following i/o does real i/o and stat calls
780 * @since 1.23
781 */
782EAPI void eina_file_statgen_next(void);
783
784/**
785 * @brief Get the current stat generation counter value
786 * @return 0 if you should always do stat calls and compare, or some other value that changes like a generation counter
787 * @since 1.23
788 */
789EAPI Eina_Statgen eina_file_statgen_get(void);
790
791/**
792 * @brief Enable stat generation count optimiziing to only stat/do file i/o between generation counts changing
793 * @since 1.23
794 */
795EAPI void eina_file_statgen_enable(void);
796
797/**
798 * @brief Disable stat generation count optimiziing to only stat/do file i/o between generation counts changing
799 * @since 1.23
800 */
801EAPI void eina_file_statgen_bisable(void);
802
803/**
772 * @} 804 * @}
773 */ 805 */
774 806
diff --git a/src/lib/eina/eina_file_common.c b/src/lib/eina/eina_file_common.c
index b62fc22b80..9369cb2cc5 100644
--- a/src/lib/eina/eina_file_common.c
+++ b/src/lib/eina/eina_file_common.c
@@ -74,6 +74,47 @@ Eina_Lock _eina_file_lock_cache;
74# define EINA_FILE_MAGIC_CHECK(f, ...) do {} while(0) 74# define EINA_FILE_MAGIC_CHECK(f, ...) do {} while(0)
75#endif 75#endif
76 76
77static Eina_Spinlock _eina_statgen_lock;
78static Eina_Statgen _eina_statgen = 0;
79
80EAPI void
81eina_file_statgen_next(void)
82{
83 eina_spinlock_take(&_eina_statgen_lock);
84 if (_eina_statgen != 0)
85 {
86 _eina_statgen++;
87 if (_eina_statgen == 0) _eina_statgen = 1;
88 }
89 eina_spinlock_release(&_eina_statgen_lock);
90}
91
92EAPI Eina_Statgen
93eina_file_statgen_get(void)
94{
95 Eina_Statgen s;
96 eina_spinlock_take(&_eina_statgen_lock);
97 s = _eina_statgen;
98 eina_spinlock_release(&_eina_statgen_lock);
99 return s;
100}
101
102EAPI void
103eina_file_statgen_enable(void)
104{
105 eina_spinlock_take(&_eina_statgen_lock);
106 if (_eina_statgen != 0) _eina_statgen = 1;
107 eina_spinlock_release(&_eina_statgen_lock);
108}
109
110EAPI void
111eina_file_statgen_bisable(void)
112{
113 eina_spinlock_take(&_eina_statgen_lock);
114 _eina_statgen = 0;
115 eina_spinlock_release(&_eina_statgen_lock);
116}
117
77static char * 118static char *
78_eina_file_escape(char *path, size_t len) 119_eina_file_escape(char *path, size_t len)
79{ 120{
@@ -1072,6 +1113,8 @@ eina_file_init(void)
1072 return EINA_FALSE; 1113 return EINA_FALSE;
1073 } 1114 }
1074 1115
1116 if (getenv("EINA_STATGEN")) _eina_statgen = 1;
1117 eina_spinlock_new(&_eina_statgen_lock);
1075 eina_lock_recursive_new(&_eina_file_lock_cache); 1118 eina_lock_recursive_new(&_eina_file_lock_cache);
1076 eina_magic_string_set(EINA_FILE_MAGIC, "Eina_File"); 1119 eina_magic_string_set(EINA_FILE_MAGIC, "Eina_File");
1077 1120
@@ -1102,6 +1145,7 @@ eina_file_shutdown(void)
1102 1145
1103 eina_log_domain_unregister(_eina_file_log_dom); 1146 eina_log_domain_unregister(_eina_file_log_dom);
1104 _eina_file_log_dom = -1; 1147 _eina_file_log_dom = -1;
1148 eina_spinlock_free(&_eina_statgen_lock);
1105 return EINA_TRUE; 1149 return EINA_TRUE;
1106} 1150}
1107 1151
diff --git a/src/lib/eina/eina_file_common.h b/src/lib/eina/eina_file_common.h
index 142ee2d852..38c1a3c4ee 100644
--- a/src/lib/eina/eina_file_common.h
+++ b/src/lib/eina/eina_file_common.h
@@ -89,6 +89,7 @@ struct _Eina_File
89 89
90 int refcount; /**< Keeps track of references to #map. */ 90 int refcount; /**< Keeps track of references to #map. */
91 int global_refcount; /**< Keeps track of references to #global_map. */ 91 int global_refcount; /**< Keeps track of references to #global_map. */
92 Eina_Statgen statgen;/**< For inexact stats a stat gen count to rate limit syscalls to stat file */
92 93
93#ifndef _WIN32 94#ifndef _WIN32
94 int fd; /**< The file descriptor. */ 95 int fd; /**< The file descriptor. */