diff options
author | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-26 13:50:51 +0100 |
---|---|---|
committer | Guillaume Friloux <guillaume.friloux@gmail.com> | 2013-12-26 13:50:51 +0100 |
commit | 8dd79bb90e2ccbcd71eeab9c203e563f0a547050 (patch) | |
tree | 3e49e4689a2892f607a171857bb1df49b5f5d95f | |
parent | ee723d9fd84c80c1abb8997c470f7f39d43b723c (diff) |
Simplify code & avoid a behavior with ecore_timer_pause.
Even if you pause a timer, you may have pending calls to that timer that
wont get stopped.
This led to multiple threads working on the same spy_file.
-rw-r--r-- | src/lib/spy/spy_file.c | 102 | ||||
-rw-r--r-- | src/lib/spy/spy_main.c | 4 | ||||
-rw-r--r-- | src/lib/spy/spy_private.h | 12 |
3 files changed, 64 insertions, 54 deletions
diff --git a/src/lib/spy/spy_file.c b/src/lib/spy/spy_file.c index 944f326..307e133 100644 --- a/src/lib/spy/spy_file.c +++ b/src/lib/spy/spy_file.c | |||
@@ -1,5 +1,10 @@ | |||
1 | #include "spy_private.h" | 1 | #include "spy_private.h" |
2 | 2 | ||
3 | #include <sys/stat.h> | ||
4 | #include <fcntl.h> | ||
5 | #include <sys/types.h> | ||
6 | #include <unistd.h> | ||
7 | |||
3 | void | 8 | void |
4 | _spy_file_line_free(void *d1, | 9 | _spy_file_line_free(void *d1, |
5 | void *d2 EINA_UNUSED) | 10 | void *d2 EINA_UNUSED) |
@@ -28,85 +33,82 @@ _spy_file_job(void *data) | |||
28 | void | 33 | void |
29 | _spy_file_line_extract(Spy_File *sf) | 34 | _spy_file_line_extract(Spy_File *sf) |
30 | { | 35 | { |
31 | const char *s, | ||
32 | *p, | ||
33 | *p1; | ||
34 | size_t rm = 0; | ||
35 | Spy_Line *sl; | 36 | Spy_Line *sl; |
36 | 37 | ||
37 | s = eina_strbuf_string_get(sf->read.buf); | 38 | DBG("sf[%p]", sf); |
38 | p = s; | ||
39 | 39 | ||
40 | while ((p1=strchr(p, '\n'))) | 40 | while (1) |
41 | { | 41 | { |
42 | size_t l = p1 - p; | 42 | if (!eina_strbuf_length_get(sf->read.buf)) |
43 | char *line; | 43 | break; |
44 | 44 | ||
45 | rm += l; | 45 | sf->extract.s = eina_strbuf_string_get(sf->read.buf); |
46 | sf->extract.p = strchr(sf->extract.s, '\n'); | ||
47 | if (!sf->extract.p) | ||
48 | break; | ||
46 | 49 | ||
47 | if (!l) | 50 | if (sf->extract.p == sf->extract.s) |
48 | goto end; | 51 | { |
52 | eina_strbuf_remove(sf->read.buf, 0, 1); | ||
53 | continue; | ||
54 | } | ||
49 | 55 | ||
50 | line = strndup(p, l); | 56 | sf->extract.l = sf->extract.p - sf->extract.s; |
51 | 57 | ||
52 | DBG("Line = %s len=%zd", line, l); | ||
53 | sl = calloc(1, sizeof(Spy_Line)); | 58 | sl = calloc(1, sizeof(Spy_Line)); |
54 | if (!sl) | 59 | if (!sl) |
55 | { | 60 | { |
56 | ERR("Failed to allocate Spy_Line"); | 61 | ERR("Failed to allocate Spy_Line"); |
57 | free(line); | 62 | return; |
58 | } | 63 | } |
59 | 64 | ||
60 | sl->sf = sf; | 65 | sl->sf = sf; |
61 | sl->line = line; | 66 | sl->line = strndup(sf->extract.s, sf->extract.l); |
62 | ecore_main_loop_thread_safe_call_async(_spy_file_event, sl); | 67 | ecore_main_loop_thread_safe_call_async(_spy_file_event, sl); |
63 | end: | 68 | eina_strbuf_remove(sf->read.buf, 0, sf->extract.l); |
64 | p = p1 + 1; | ||
65 | } | 69 | } |
66 | |||
67 | eina_strbuf_remove(sf->read.buf, 0, rm); | ||
68 | } | 70 | } |
69 | 71 | ||
70 | void | 72 | void |
71 | _spy_file_cb(void *data, | 73 | _spy_file_cb(void *data, |
72 | Ecore_Thread *thread EINA_UNUSED) | 74 | Ecore_Thread *thread EINA_UNUSED) |
73 | { | 75 | { |
74 | Spy_File *sf; | 76 | Spy_File *sf = data; |
75 | size_t nbr = 0, | ||
76 | toread = 0, | ||
77 | left = 0; | ||
78 | char buf[512]; | ||
79 | 77 | ||
80 | sf = data; | 78 | sf = data; |
81 | DBG("sf[%p]", sf); | 79 | DBG("sf[%p]", sf); |
82 | 80 | ||
83 | sf->read.fd = fopen(sf->name, "r"); | 81 | sf->read.nbr = 0; |
84 | if (!sf->read.fd) | 82 | |
83 | sf->read.fd = open(sf->name, O_RDONLY); | ||
84 | if (sf->read.fd == -1) | ||
85 | { | 85 | { |
86 | ERR("Failed to open %s : %s", sf->name, strerror(errno)); | 86 | ERR("Failed to open %s : %s", sf->name, strerror(errno)); |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | 89 | ||
90 | fseeko(sf->read.fd, sf->read.offset - 1, SEEK_SET); | 90 | sf->read.databuf = calloc(1, sf->read.length + 1); |
91 | left = sf->read.length; | ||
92 | 91 | ||
93 | while (nbr != (size_t)sf->read.length) | 92 | errno = 0; |
93 | sf->read.nbr = pread(sf->read.fd, sf->read.databuf, | ||
94 | sf->read.length, sf->read.offset); | ||
95 | if (sf->read.nbr == -1) | ||
94 | { | 96 | { |
95 | toread = (left < 512) ? left : 512; | 97 | ERR("Error while reading file %s : %s", |
96 | 98 | sf->name, strerror(errno)); | |
97 | if (fread(buf, toread, 1, sf->read.fd) != 1) | 99 | close(sf->read.fd); |
98 | { | 100 | free(sf->read.databuf); |
99 | ERR("Error while reading file %s : %s", | 101 | sf->read.databuf = NULL; |
100 | sf->name, strerror(errno)); | 102 | return; |
101 | fclose(sf->read.fd); | ||
102 | return; | ||
103 | } | ||
104 | eina_strbuf_append_length(sf->read.buf, buf, toread); | ||
105 | _spy_file_line_extract(sf); | ||
106 | nbr += toread; | ||
107 | } | 103 | } |
108 | fclose(sf->read.fd); | 104 | |
109 | sf->read.fd = NULL; | 105 | eina_strbuf_append_length(sf->read.buf, sf->read.databuf, sf->read.nbr); |
106 | _spy_file_line_extract(sf); | ||
107 | |||
108 | free(sf->read.databuf); | ||
109 | sf->read.databuf = NULL; | ||
110 | close(sf->read.fd); | ||
111 | sf->poll.size += sf->read.nbr; | ||
110 | } | 112 | } |
111 | 113 | ||
112 | void | 114 | void |
@@ -118,8 +120,7 @@ _spy_file_end_cb(void *data, | |||
118 | sf = data; | 120 | sf = data; |
119 | DBG("sf[%p]", sf); | 121 | DBG("sf[%p]", sf); |
120 | 122 | ||
121 | ecore_timer_thaw(sf->poll.timer); | 123 | sf->poll.running = EINA_FALSE; |
122 | ecore_timer_reset(sf->poll.timer); | ||
123 | 124 | ||
124 | ecore_job_add(_spy_file_job, sf); | 125 | ecore_job_add(_spy_file_job, sf); |
125 | } | 126 | } |
@@ -139,7 +140,8 @@ spy_file_poll(void *data) | |||
139 | Ecore_Thread *et; | 140 | Ecore_Thread *et; |
140 | 141 | ||
141 | sf = data; | 142 | sf = data; |
142 | DBG("spy_file[%p] file[%s]", sf, sf->name); | 143 | if (sf->poll.running) |
144 | return EINA_TRUE; | ||
143 | 145 | ||
144 | /* We should have different actions made depending on error type. */ | 146 | /* We should have different actions made depending on error type. */ |
145 | if (stat(sf->name, &st)) | 147 | if (stat(sf->name, &st)) |
@@ -168,7 +170,7 @@ spy_file_poll(void *data) | |||
168 | sf->read.offset = sf->poll.size; | 170 | sf->read.offset = sf->poll.size; |
169 | sf->read.length = toread; | 171 | sf->read.length = toread; |
170 | 172 | ||
171 | 173 | sf->poll.running = EINA_TRUE; | |
172 | et = ecore_thread_run(_spy_file_cb, | 174 | et = ecore_thread_run(_spy_file_cb, |
173 | _spy_file_end_cb, | 175 | _spy_file_end_cb, |
174 | _spy_file_cancel_cb, | 176 | _spy_file_cancel_cb, |
@@ -178,9 +180,6 @@ spy_file_poll(void *data) | |||
178 | ERR("Failed to create reading thread"); | 180 | ERR("Failed to create reading thread"); |
179 | return EINA_TRUE; | 181 | return EINA_TRUE; |
180 | } | 182 | } |
181 | |||
182 | ecore_timer_freeze(sf->poll.timer); | ||
183 | sf->poll.size = size; | ||
184 | return EINA_TRUE; | 183 | return EINA_TRUE; |
185 | } | 184 | } |
186 | 185 | ||
@@ -195,6 +194,7 @@ void | |||
195 | spy_file_data_set(Spy_File *sf, | 194 | spy_file_data_set(Spy_File *sf, |
196 | const void *data) | 195 | const void *data) |
197 | { | 196 | { |
197 | EINA_SAFETY_ON_NULL_RETURN(sf); | ||
198 | sf->data = (const void *)data; | 198 | sf->data = (const void *)data; |
199 | } | 199 | } |
200 | 200 | ||
diff --git a/src/lib/spy/spy_main.c b/src/lib/spy/spy_main.c index bb171b3..b4ca263 100644 --- a/src/lib/spy/spy_main.c +++ b/src/lib/spy/spy_main.c | |||
@@ -90,7 +90,8 @@ spy_file_new(Spy *spy, const char *file) | |||
90 | } | 90 | } |
91 | 91 | ||
92 | sf->poll.size = st.st_size; | 92 | sf->poll.size = st.st_size; |
93 | sf->poll.timer = ecore_timer_add(0.3, spy_file_poll, sf); | 93 | sf->poll.timer = ecore_timer_loop_add(0.3, spy_file_poll, sf); |
94 | ecore_timer_precision_set(1.0); | ||
94 | 95 | ||
95 | spy->files = eina_inlist_append(spy->files, EINA_INLIST_GET(sf)); | 96 | spy->files = eina_inlist_append(spy->files, EINA_INLIST_GET(sf)); |
96 | DBG("spy_file[%p] size[%zd]", sf, st.st_size); | 97 | DBG("spy_file[%p] size[%zd]", sf, st.st_size); |
@@ -154,7 +155,6 @@ spy_shutdown(void) | |||
154 | if (--_spy_init_count != 0) | 155 | if (--_spy_init_count != 0) |
155 | return _spy_init_count; | 156 | return _spy_init_count; |
156 | 157 | ||
157 | eio_shutdown(); | ||
158 | ecore_shutdown(); | 158 | ecore_shutdown(); |
159 | eina_log_domain_unregister(_spy_log_dom_global); | 159 | eina_log_domain_unregister(_spy_log_dom_global); |
160 | _spy_log_dom_global = -1; | 160 | _spy_log_dom_global = -1; |
diff --git a/src/lib/spy/spy_private.h b/src/lib/spy/spy_private.h index 287ea44..ad32258 100644 --- a/src/lib/spy/spy_private.h +++ b/src/lib/spy/spy_private.h | |||
@@ -24,15 +24,25 @@ struct _Spy_File | |||
24 | { | 24 | { |
25 | Ecore_Timer *timer; | 25 | Ecore_Timer *timer; |
26 | off_t size; | 26 | off_t size; |
27 | Eina_Bool running; | ||
27 | } poll; | 28 | } poll; |
28 | 29 | ||
29 | struct | 30 | struct |
30 | { | 31 | { |
31 | FILE *fd; | 32 | int fd; |
32 | off_t offset, | 33 | off_t offset, |
33 | length; | 34 | length; |
34 | Eina_Strbuf *buf; | 35 | Eina_Strbuf *buf; |
36 | char *databuf; | ||
37 | ssize_t nbr; | ||
35 | } read; | 38 | } read; |
39 | |||
40 | struct | ||
41 | { | ||
42 | const char *p, | ||
43 | *s; | ||
44 | size_t l; | ||
45 | } extract; | ||
36 | }; | 46 | }; |
37 | 47 | ||
38 | struct _Spy_Line | 48 | struct _Spy_Line |