summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorVincent Torri <vincent dot torri at gmail dot com>2015-09-27 09:31:44 +0200
committerCedric BAIL <cedric@osg.samsung.com>2015-10-12 17:21:59 -0700
commitf1a2c22dc35db870cd5eb16031fb2143100413eb (patch)
treefc8e44c8c703fc15b333c967a12343645f38c0d9 /src/lib
parentd4de2a2d879e284dd0892fa60cdbe8f9b4ba46f8 (diff)
ecore_exe: read remaining data when the child application has closed
Output and error threads could not read all the data sent by the child. Based on a patch by Guillaume Friloux @fix Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ecore/ecore_exe_win32.c144
1 files changed, 84 insertions, 60 deletions
diff --git a/src/lib/ecore/ecore_exe_win32.c b/src/lib/ecore/ecore_exe_win32.c
index f03b05b94f..24782e2dfa 100644
--- a/src/lib/ecore/ecore_exe_win32.c
+++ b/src/lib/ecore/ecore_exe_win32.c
@@ -36,6 +36,40 @@
36 36
37static int run_pri = NORMAL_PRIORITY_CLASS; 37static int run_pri = NORMAL_PRIORITY_CLASS;
38 38
39static void
40_ecore_exe_threads_terminate(Ecore_Exe *obj)
41{
42 Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
43 HANDLE threads[2] = { NULL, NULL };
44 int i = 0;
45
46 if (exe->pipe_read.thread)
47 {
48 threads[i] = exe->pipe_read.thread;
49 i++;
50 }
51 if (exe->pipe_error.thread)
52 {
53 threads[i] = exe->pipe_error.thread;
54 i++;
55 }
56 if (i > 0)
57 {
58 exe->close_threads = 1;
59 WaitForMultipleObjects(i, threads, TRUE, INFINITE);
60 if (exe->pipe_error.thread)
61 {
62 CloseHandle(exe->pipe_error.thread);
63 exe->pipe_error.thread = NULL;
64 }
65 if (exe->pipe_read.thread)
66 {
67 CloseHandle(exe->pipe_read.thread);
68 exe->pipe_read.thread = NULL;
69 }
70 }
71}
72
39static Eina_Bool 73static Eina_Bool
40_ecore_exe_close_cb(void *data, 74_ecore_exe_close_cb(void *data,
41 Ecore_Win32_Handler *wh EINA_UNUSED) 75 Ecore_Win32_Handler *wh EINA_UNUSED)
@@ -45,6 +79,8 @@ _ecore_exe_close_cb(void *data,
45 Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS); 79 Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
46 DWORD exit_code = 0; 80 DWORD exit_code = 0;
47 81
82 _ecore_exe_threads_terminate(obj);
83
48 e = calloc(1, sizeof(Ecore_Exe_Event_Del)); 84 e = calloc(1, sizeof(Ecore_Exe_Event_Del));
49 if (!e) return 0; 85 if (!e) return 0;
50 86
@@ -83,16 +119,22 @@ _ecore_exe_pipe_read_thread_cb(void *data)
83 DWORD current_size = 0; 119 DWORD current_size = 0;
84 BOOL res; 120 BOOL res;
85 121
86 while (!exe->close_threads) 122 while (1)
87 { 123 {
88 if (!PeekNamedPipe(exe->pipe_read.child_pipe, 124 res = PeekNamedPipe(exe->pipe_read.child_pipe,
89 buf, sizeof(buf) - 1, &size, &current_size, NULL)) 125 buf, sizeof(buf) - 1, &size, &current_size, NULL);
90 continue; 126 if (!res || (size == 0))
91 if (size == 0) 127 {
92 continue; 128 if (exe->close_threads)
129 break;
130
131 continue;
132 }
133
93 current_buf = (char *)malloc(current_size); 134 current_buf = (char *)malloc(current_size);
94 if (!current_buf) 135 if (!current_buf)
95 continue; 136 continue;
137
96 res = ReadFile(exe->pipe_read.child_pipe, current_buf, current_size, &size, NULL); 138 res = ReadFile(exe->pipe_read.child_pipe, current_buf, current_size, &size, NULL);
97 if (!res || (size == 0)) 139 if (!res || (size == 0))
98 { 140 {
@@ -100,16 +142,21 @@ _ecore_exe_pipe_read_thread_cb(void *data)
100 current_buf = NULL; 142 current_buf = NULL;
101 continue; 143 continue;
102 } 144 }
103 if (current_size != size) 145
146 current_size = size;
147
148 if (!exe->pipe_read.data_buf)
149 {
150 exe->pipe_read.data_buf = current_buf;
151 exe->pipe_read.data_size = current_size;
152 }
153 else
104 { 154 {
155 exe->pipe_read.data_buf = realloc(exe->pipe_read.data_buf, exe->pipe_read.data_size + current_size);
156 memcpy((unsigned char *)exe->pipe_read.data_buf + exe->pipe_read.data_size, current_buf, current_size);
157 exe->pipe_read.data_size += current_size;
105 free(current_buf); 158 free(current_buf);
106 current_buf = NULL;
107 continue;
108 } 159 }
109 current_size = size;
110
111 exe->pipe_read.data_buf = current_buf;
112 exe->pipe_read.data_size = current_size;
113 160
114 event_data = ecore_exe_event_data_get(obj, ECORE_EXE_PIPE_READ); 161 event_data = ecore_exe_event_data_get(obj, ECORE_EXE_PIPE_READ);
115 if (event_data) 162 if (event_data)
@@ -141,16 +188,22 @@ _ecore_exe_pipe_error_thread_cb(void *data)
141 DWORD current_size = 0; 188 DWORD current_size = 0;
142 BOOL res; 189 BOOL res;
143 190
144 while (!exe->close_threads) 191 while (1)
145 { 192 {
146 if (!PeekNamedPipe(exe->pipe_error.child_pipe, 193 res = PeekNamedPipe(exe->pipe_error.child_pipe,
147 buf, sizeof(buf) - 1, &size, &current_size, NULL)) 194 buf, sizeof(buf) - 1, &size, &current_size, NULL);
148 continue; 195 if (!res || (size == 0))
149 if (size == 0) 196 {
150 continue; 197 if (exe->close_threads)
198 break;
199
200 continue;
201 }
202
151 current_buf = (char *)malloc(current_size); 203 current_buf = (char *)malloc(current_size);
152 if (!current_buf) 204 if (!current_buf)
153 continue; 205 continue;
206
154 res = ReadFile(exe->pipe_error.child_pipe, current_buf, current_size, &size, NULL); 207 res = ReadFile(exe->pipe_error.child_pipe, current_buf, current_size, &size, NULL);
155 if (!res || (size == 0)) 208 if (!res || (size == 0))
156 { 209 {
@@ -158,16 +211,21 @@ _ecore_exe_pipe_error_thread_cb(void *data)
158 current_buf = NULL; 211 current_buf = NULL;
159 continue; 212 continue;
160 } 213 }
161 if (current_size != size) 214
215 current_size = size;
216
217 if (!exe->pipe_error.data_buf)
162 { 218 {
219 exe->pipe_error.data_buf = current_buf;
220 exe->pipe_error.data_size = current_size;
221 }
222 else
223 {
224 exe->pipe_error.data_buf = realloc(exe->pipe_error.data_buf, exe->pipe_error.data_size + current_size);
225 memcpy((unsigned char *)exe->pipe_error.data_buf + exe->pipe_error.data_size, current_buf, current_size);
226 exe->pipe_error.data_size += current_size;
163 free(current_buf); 227 free(current_buf);
164 current_buf = NULL;
165 continue;
166 } 228 }
167 current_size = size;
168
169 exe->pipe_error.data_buf = current_buf;
170 exe->pipe_error.data_size = current_size;
171 229
172 event_data = ecore_exe_event_data_get(obj, ECORE_EXE_PIPE_ERROR); 230 event_data = ecore_exe_event_data_get(obj, ECORE_EXE_PIPE_ERROR);
173 if (event_data) 231 if (event_data)
@@ -187,40 +245,6 @@ _ecore_exe_pipe_error_thread_cb(void *data)
187 return 0; 245 return 0;
188} 246}
189 247
190static void
191_ecore_exe_threads_terminate(Ecore_Exe *obj)
192{
193 Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
194 HANDLE threads[2] = { NULL, NULL };
195 int i = 0;
196
197 if (exe->pipe_read.thread)
198 {
199 threads[i] = exe->pipe_read.thread;
200 i++;
201 }
202 if (exe->pipe_error.thread)
203 {
204 threads[i] = exe->pipe_error.thread;
205 i++;
206 }
207 if (i > 0)
208 {
209 exe->close_threads = 1;
210 WaitForMultipleObjects(i, threads, TRUE, INFINITE);
211 if (exe->pipe_error.thread)
212 {
213 CloseHandle(exe->pipe_error.thread);
214 exe->pipe_error.thread = NULL;
215 }
216 if (exe->pipe_read.thread)
217 {
218 CloseHandle(exe->pipe_read.thread);
219 exe->pipe_read.thread = NULL;
220 }
221 }
222}
223
224static DWORD WINAPI 248static DWORD WINAPI
225_ecore_exe_thread_procedure(LPVOID data EINA_UNUSED) 249_ecore_exe_thread_procedure(LPVOID data EINA_UNUSED)
226{ 250{