| 1201 | } |
| 1202 | |
| 1203 | int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, |
| 1204 | double* userTimeout) |
| 1205 | { |
| 1206 | kwsysProcessTime userStartTime; |
| 1207 | kwsysProcessTime timeoutLength; |
| 1208 | kwsysProcessTime timeoutTime; |
| 1209 | DWORD timeout; |
| 1210 | int user; |
| 1211 | int done = 0; |
| 1212 | int expired = 0; |
| 1213 | int pipeId = kwsysProcess_Pipe_None; |
| 1214 | DWORD w; |
| 1215 | |
| 1216 | /* Make sure we are executing a process. */ |
| 1217 | if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed || |
| 1218 | cp->TimeoutExpired) { |
| 1219 | return kwsysProcess_Pipe_None; |
| 1220 | } |
| 1221 | |
| 1222 | /* Record the time at which user timeout period starts. */ |
| 1223 | userStartTime = kwsysProcessTimeGetCurrent(); |
| 1224 | |
| 1225 | /* Calculate the time at which a timeout will expire, and whether it |
| 1226 | is the user or process timeout. */ |
| 1227 | user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime); |
| 1228 | |
| 1229 | /* Loop until we have a reason to return. */ |
| 1230 | while (!done && cp->PipesLeft > 0) { |
| 1231 | /* If we previously got data from a thread, let it know we are |
| 1232 | done with the data. */ |
| 1233 | if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { |
| 1234 | KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); |
| 1235 | ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); |
| 1236 | cp->CurrentIndex = KWSYSPE_PIPE_COUNT; |
| 1237 | } |
| 1238 | |
| 1239 | /* Setup a timeout if required. */ |
| 1240 | if (kwsysProcessGetTimeoutLeft(&timeoutTime, user ? userTimeout : 0, |
| 1241 | &timeoutLength)) { |
| 1242 | /* Timeout has already expired. */ |
| 1243 | expired = 1; |
| 1244 | break; |
| 1245 | } |
| 1246 | if (timeoutTime.QuadPart < 0) { |
| 1247 | timeout = INFINITE; |
| 1248 | } else { |
| 1249 | timeout = kwsysProcessTimeToDWORD(timeoutLength); |
| 1250 | } |
| 1251 | |
| 1252 | /* Wait for a pipe's thread to signal or a process to terminate. */ |
| 1253 | w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents, 0, |
| 1254 | timeout); |
| 1255 | if (w == WAIT_TIMEOUT) { |
| 1256 | /* Timeout has expired. */ |
| 1257 | expired = 1; |
| 1258 | done = 1; |
| 1259 | } else if (w == WAIT_OBJECT_0) { |
| 1260 | /* Save the index of the reporting thread and release the mutex. |
no test coverage detected
searching dependent graphs…