in modules/fcgid/fcgid_proc_win.c [376:461]
apr_status_t proc_write_ipc(fcgid_ipc * ipc_handle,
apr_bucket_brigade * birgade_send)
{
fcgid_namedpipe_handle *handle_info;
apr_bucket *bucket_request;
apr_status_t rv;
DWORD transferred;
apr_bucket_brigade *tmpbb = apr_brigade_create(birgade_send->p,
birgade_send->bucket_alloc);
handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;
while (!APR_BRIGADE_EMPTY(birgade_send)) {
const char *write_buf;
apr_size_t write_buf_len;
apr_size_t has_write;
bucket_request = APR_BRIGADE_FIRST(birgade_send);
if (APR_BUCKET_IS_METADATA(bucket_request)) {
apr_bucket_delete(bucket_request);
continue;
}
if ((rv = apr_bucket_read(bucket_request, &write_buf, &write_buf_len,
APR_BLOCK_READ)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, ipc_handle->request,
"mod_fcgid: can't read request from bucket");
return rv;
}
APR_BUCKET_REMOVE(bucket_request);
APR_BRIGADE_INSERT_TAIL(tmpbb, bucket_request);
/* Write the buffer to fastcgi server */
has_write = 0;
while (has_write < write_buf_len) {
DWORD byteswrite;
if (WriteFile(handle_info->handle_pipe,
write_buf + has_write,
write_buf_len - has_write,
&byteswrite, &handle_info->overlap_write)) {
has_write += byteswrite;
apr_brigade_cleanup(tmpbb);
continue;
} else if ((rv = GetLastError()) != ERROR_IO_PENDING) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING,
APR_FROM_OS_ERROR(rv), ipc_handle->request,
"mod_fcgid: can't write to pipe");
return rv;
} else {
/*
it's ERROR_IO_PENDING on write
*/
DWORD dwWaitResult =
WaitForSingleObject(handle_info->overlap_write.hEvent,
ipc_handle->communation_timeout * 1000);
if (dwWaitResult == WAIT_OBJECT_0) {
if (!GetOverlappedResult(handle_info->handle_pipe,
&handle_info->overlap_write,
&transferred,
FALSE /* don't wait */ )
|| transferred == 0)
{
ap_log_rerror(APLOG_MARK, APLOG_WARNING,
apr_get_os_error(), ipc_handle->request,
"mod_fcgid: get overlap result error");
return APR_ESPIPE;
}
has_write += transferred;
apr_brigade_cleanup(tmpbb);
continue;
} else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0,
ipc_handle->request,
"mod_fcgid: write timeout to pipe");
return APR_ESPIPE;
}
}
}
}
apr_brigade_destroy(tmpbb);
return APR_SUCCESS;
}