Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Delete unused -fprofile-arcs flags.
[simgrid.git] / tools / tesh2 / src / writer.c
1 /*\r
2  * src/writer.c - type representing a stdin writer.\r
3  *\r
4  * Copyright 2008,2009 Martin Quinson, Malek Cherier All right reserved. \r
5  *\r
6  * This program is free software; you can redistribute it and/or modify it \r
7  * under the terms of the license (GNU LGPL) which comes with this package.\r
8  *\r
9  * Purpose:\r
10  *              This file contains all the definitions of the functions related with\r
11  *              the tesh writer type.\r
12  *\r
13  */\r
14  \r
15 #include <writer.h>\r
16 #include <command.h>\r
17 #include <unit.h>\r
18 \r
19 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(tesh);\r
20 \r
21 static void*\r
22 writer_start_routine(void* p);\r
23 \r
24 writer_t\r
25 writer_new(command_t command)\r
26 {\r
27         writer_t writer;\r
28         /* TODO : check the parameter */\r
29         \r
30         writer = xbt_new0(s_writer_t, 1);\r
31 \r
32         writer->thread = NULL;\r
33         writer->command = command;\r
34         writer->written = xbt_os_sem_init(0);\r
35         writer->can_write = xbt_os_sem_init(0);\r
36         \r
37         writer->done = 0;\r
38 \r
39         return writer;\r
40 }\r
41 \r
42 int\r
43 writer_free(writer_t* ptr)\r
44 {\r
45 \r
46         if((*ptr)->written)\r
47                 xbt_os_sem_destroy((*ptr)->written);\r
48         \r
49         if((*ptr)->can_write)\r
50                 xbt_os_sem_destroy((*ptr)->can_write);\r
51         \r
52         free(*ptr);\r
53 \r
54         *ptr = NULL;\r
55         \r
56         return 0;\r
57 }\r
58 \r
59 void\r
60 writer_write(writer_t writer)\r
61 {\r
62         writer->thread = xbt_os_thread_create("", writer_start_routine, writer);\r
63 }\r
64 \r
65 #ifdef WIN32\r
66 static void*\r
67 writer_start_routine(void* p)\r
68 {\r
69         writer_t writer = (writer_t)p;\r
70         command_t command = writer->command;\r
71         \r
72         char* input = (char*)(command->context->input->data);\r
73         \r
74         DWORD number_of_bytes_to_write = command->context->input->used;\r
75         DWORD number_of_bytes_written = 0;\r
76 \r
77         xbt_os_sem_release(writer->written);\r
78 \r
79         while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)\r
80         {\r
81                 if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))\r
82                 {\r
83                         if(GetLastError() ==  ERROR_NO_DATA)\r
84                                 writer->broken_pipe = 1;\r
85                         else\r
86                         writer->failed = 1;\r
87                                 \r
88                 }\r
89                 else\r
90                 {\r
91                         input += number_of_bytes_written;\r
92                         number_of_bytes_to_write -= number_of_bytes_written;\r
93                 }\r
94         }\r
95         \r
96         command->context->input->data[0]='\0';\r
97         command->context->input->used=0;\r
98         \r
99         if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)\r
100         {\r
101                 ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
102                 unit_set_error(command->unit, (int)GetLastError(), 0, command->context->pos);\r
103                 command_handle_failure(command, csr_write_failure);\r
104         }\r
105         /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
106         {\r
107 \r
108                 ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
109                 unit_set_error(command->unit, (int)GetLastError(), 0);\r
110                 command_kill(command);\r
111                 command_handle_failure(command, csr_write_pipe_broken);\r
112         }*/\r
113 \r
114         CloseHandle(command->stdin_fd);\r
115         command->stdin_fd = INDEFINITE_FD;\r
116 \r
117         return NULL;\r
118 }\r
119 #else\r
120 static void* \r
121 writer_start_routine(void* p) \r
122 {\r
123         writer_t writer = (writer_t)p;\r
124         command_t command = writer->command;\r
125         int number_of_bytes_to_write = command->context->input->used;\r
126         char* input = (char*)(command->context->input->data);\r
127         int got;\r
128         int released = 0;\r
129         \r
130         while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)\r
131         {\r
132                 got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;\r
133                 got = write(writer->command->stdin_fd, input, got );\r
134                 \r
135                 if(got < 0) \r
136                 {\r
137                         if(EINTR == errno)\r
138                                 continue;\r
139                                 \r
140                         else if(EAGAIN == errno)\r
141                         {/* the pipe is full */\r
142                                 if(!released)\r
143                                 {\r
144                                         xbt_os_sem_release(writer->written);\r
145                                         released = 1;\r
146                                         xbt_os_thread_yield();\r
147                                 }\r
148                                 \r
149                                 continue;\r
150                         }\r
151                         else if(EPIPE == errno) \r
152                         {\r
153                                 writer->broken_pipe = 1;\r
154                                 break;\r
155                         } \r
156                         else\r
157                         {\r
158                                 writer->failed = 1;\r
159                                 break;\r
160                         }\r
161                         \r
162                 }\r
163                 \r
164                 number_of_bytes_to_write -= got;\r
165                 input += got;\r
166                 \r
167                 if(got == 0)\r
168                         xbt_os_thread_yield();\r
169                 \r
170         }\r
171         \r
172         if(!released)\r
173                 xbt_os_sem_release(writer->written);\r
174         \r
175         \r
176         if(close(command->stdin_fd) < 0)\r
177         {\r
178                 /* TODO */\r
179         }\r
180         else\r
181                 command->stdin_fd = INDEFINITE_FD;\r
182         \r
183         command->context->input->data[0]='\0';\r
184         command->context->input->used=0;\r
185         \r
186         if(writer->failed && !command->successeded && !command->failed && !command->interrupted)\r
187         {\r
188                 command_kill(command);\r
189                 ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
190                 \r
191                 unit_set_error(command->unit, errno, 0, command->context->pos);\r
192                 command_handle_failure(command, csr_write_failure);\r
193         }\r
194         else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
195         {\r
196                 ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
197 \r
198                 unit_set_error(command->unit, errno, 0, command->context->pos);\r
199                 command_kill(command);\r
200                 command_handle_failure(command, csr_write_pipe_broken);\r
201         }\r
202         \r
203         writer->done = 1;\r
204         \r
205         return NULL;\r
206         \r
207 }\r
208 \r
209 #endif\r
210 void\r
211 writer_wait(writer_t writer)\r
212 {\r
213         xbt_os_thread_join(writer->thread, NULL);\r
214 \r
215 }\r