summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorGuillaume Friloux <guillaume.friloux@gmail.com>2013-12-26 13:50:51 +0100
committerGuillaume Friloux <guillaume.friloux@gmail.com>2013-12-26 13:50:51 +0100
commit8dd79bb90e2ccbcd71eeab9c203e563f0a547050 (patch)
tree3e49e4689a2892f607a171857bb1df49b5f5d95f /src/lib
parentee723d9fd84c80c1abb8997c470f7f39d43b723c (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.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/spy/spy_file.c102
-rw-r--r--src/lib/spy/spy_main.c4
-rw-r--r--src/lib/spy/spy_private.h12
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
3void 8void
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)
28void 33void
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
70void 72void
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
112void 114void
@@ -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
195spy_file_data_set(Spy_File *sf, 194spy_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
38struct _Spy_Line 48struct _Spy_Line