Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Corrected small bug in network model host_number is used instead of card_number.
[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         while(!command->failed && !command->interrupted && !command->successeded && ! writer->failed && ! writer->broken_pipe && number_of_bytes_to_write)\r
78         {\r
79                 if(!WriteFile(writer->command->stdin_fd, input, number_of_bytes_to_write, &number_of_bytes_written, NULL))\r
80                 {\r
81                         if(GetLastError() ==  ERROR_NO_DATA)\r
82                                 writer->broken_pipe = 1;\r
83                         else\r
84                         writer->failed = 1;\r
85                                 \r
86                 }\r
87                 else\r
88                 {\r
89                         input += number_of_bytes_written;\r
90                         number_of_bytes_to_write -= number_of_bytes_written;\r
91                 }\r
92         }\r
93         \r
94         command->context->input->data[0]='\0';\r
95         command->context->input->used=0;\r
96         \r
97         if(writer->failed  && !command->successeded && !command->failed && !command->interrupted)\r
98         {\r
99                 ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
100                 unit_set_error(command->unit, (int)GetLastError(), 0);\r
101                 command_handle_failure(command, csr_write_failure);\r
102         }\r
103         /*else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
104         {\r
105 \r
106                 ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
107                 unit_set_error(command->unit, (int)GetLastError(), 0);\r
108                 command_kill(command);\r
109                 command_handle_failure(command, csr_write_pipe_broken);\r
110         }*/\r
111         \r
112         CloseHandle(command->stdin_fd);\r
113         command->stdin_fd = INDEFINITE_FD;\r
114 \r
115         return NULL;\r
116 }\r
117 #else\r
118 static void* \r
119 writer_start_routine(void* p) \r
120 {\r
121         writer_t writer = (writer_t)p;\r
122         command_t command = writer->command;\r
123         int number_of_bytes_to_write = command->context->input->used;\r
124         char* input = (char*)(command->context->input->data);\r
125         int got;\r
126         int released = 0;\r
127         \r
128         while(!command->failed && !command->interrupted && !command->successeded && number_of_bytes_to_write > 0)\r
129         {\r
130                 got = number_of_bytes_to_write > PIPE_BUF ? PIPE_BUF : number_of_bytes_to_write;\r
131                 got = write(writer->command->stdin_fd, input, got );\r
132                 \r
133                 if(got < 0) \r
134                 {\r
135                         if(EINTR == errno)\r
136                                 continue;\r
137                                 \r
138                         else if(EAGAIN == errno)\r
139                         {/* the pipe is full */\r
140                                 if(!released)\r
141                                 {\r
142                                         xbt_os_sem_release(writer->written);\r
143                                         released = 1;\r
144                                         xbt_os_thread_yield();\r
145                                 }\r
146                                 \r
147                                 continue;\r
148                         }\r
149                         else if(EPIPE == errno) \r
150                         {\r
151                                 writer->broken_pipe = 1;\r
152                                 break;\r
153                         } \r
154                         else\r
155                         {\r
156                                 writer->failed = 1;\r
157                                 break;\r
158                         }\r
159                         \r
160                 }\r
161                 \r
162                 number_of_bytes_to_write -= got;\r
163                 input += got;\r
164                 \r
165                 if(got == 0)\r
166                         xbt_os_thread_yield();\r
167                 \r
168         }\r
169         \r
170         if(!released)\r
171                 xbt_os_sem_release(writer->written);\r
172         \r
173         \r
174         if(close(command->stdin_fd) < 0)\r
175         {\r
176                 /* TODO */\r
177         }\r
178         else\r
179                 command->stdin_fd = INDEFINITE_FD;\r
180         \r
181         command->context->input->data[0]='\0';\r
182         command->context->input->used=0;\r
183         \r
184         if(writer->failed && !command->successeded && !command->failed && !command->interrupted)\r
185         {\r
186                 command_kill(command);\r
187                 ERROR2("[%s] Error while writing input to child `%s'", command->context->pos, command->context->command_line);\r
188                 \r
189                 unit_set_error(command->unit, errno, 0);\r
190                 command_handle_failure(command, csr_write_failure);\r
191         }\r
192         else if(writer->broken_pipe && !command->successeded && !command->failed && !command->interrupted)\r
193         {\r
194                 ERROR2("[%s] Pipe broken while writing input to child `%s'", command->context->pos, command->context->command_line);\r
195 \r
196                 unit_set_error(command->unit, errno, 0);\r
197                 command_kill(command);\r
198                 command_handle_failure(command, csr_write_pipe_broken);\r
199         }\r
200         \r
201         writer->done = 1;\r
202         \r
203         return NULL;\r
204         \r
205 }\r
206 \r
207 #endif\r
208 void\r
209 writer_wait(writer_t writer)\r
210 {\r
211         xbt_os_thread_join(writer->thread, NULL);\r
212 \r
213 }\r