Apache sendfile OVERLAPPED overlapped;
memset(&overlapped,'\0', sizeof(overlapped));
#ifdef WAIT_FOR_EVENT
wait_event = overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#else
wait_event = (HANDLE) sock->socketdes;
#endif
overlapped.Offset = (DWORD)(curoff);
overlapped.OffsetHigh = (DWORD)(curoff >> 32); /* XXX BoundsChecker claims dwFlags must not be zero. */
rv = TransmitFile(sock->socketdes, /* socket */
file->filehand, /* open file descriptor of the file to be sent */
nbytes, /* number of bytes to send. 0=send all */
0, /* Number of bytes per send. 0=use default */
&overlapped, /* OVERLAPPED structure */
ptfb, /* header and trailer buffers */
dwFlags); /* flags to control various aspects of TransmitFile */
if (!rv)
{
status = apr_get_netos_error();
if ((status == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) ||
(status == APR_FROM_OS_ERROR(WSA_IO_PENDING)))
{
rv = WaitForSingleObject(wait_event,
(DWORD)(sock->timeout >= 0
? sock->timeout_ms : INFINITE));
if (rv == WAIT_OBJECT_0)
status = APR_SUCCESS;
else if (rv == WAIT_TIMEOUT)
status = APR_FROM_OS_ERROR(WAIT_TIMEOUT);
else if (rv == WAIT_ABANDONED)
status = APR_FROM_OS_ERROR(WAIT_TIMEOUT);
else
status = apr_get_os_error();
}
}Atl ZEvtSyncSocket::Write WSAOVERLAPPED o;
o.hEvent = m_hEventWrite;
WSAResetEvent(o.hEvent);
if (WSASend(m_socket, pBuffers, nCount, pdwSize, 0, &o, 0))
{
DWORD dwLastError = WSAGetLastError();
if (dwLastError != WSA_IO_PENDING)
{
m_dwLastError = dwLastError;
bRet = false;
}
} // wait for write to complete
if (bRet)
{
if (WaitForSingleObject((HANDLE)m_hEventWrite, m_dwSocketTimeout) == WAIT_OBJECT_0)
{
DWORD dwFlags = 0;
if (WSAGetOverlappedResult(m_socket, &o, pdwSize, FALSE, &dwFlags))
bRet = true;
else
{
m_dwLastError = ::GetLastError();
bRet = false;
}
}
else
bRet = false;
}
return bRet;这两个片段都使用了重叠IO,并利用Event等待操作完成.
它们的OVERLAPPED变量都存放在栈上,它们都等待指定的时间,如果没有完成返回超时错误.它们在超时错误发生后都未进行CancelIo操作,也就是说重叠操作仍在进行,完成后不管是否有错,系统都会对OVERLAPPED变量做修改(错误值和传输字节数).而OVERLAPPED变量早已被销毁,也许已做后来进行操作的变量使用,这样修改后就造成了不确定的错误.如果以上理解正确的话,它们都不约而同的出现同样的错误,事实上还有许多代码也这样使用过.是设计者没有考虑到,还是有其它的原因使这个错误不会发生.我认为没考虑到的可能性较大些,希望有编写经验的或也写过类似代码的朋友来做个合理的解答.
memset(&overlapped,'\0', sizeof(overlapped));
#ifdef WAIT_FOR_EVENT
wait_event = overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#else
wait_event = (HANDLE) sock->socketdes;
#endif
overlapped.Offset = (DWORD)(curoff);
overlapped.OffsetHigh = (DWORD)(curoff >> 32); /* XXX BoundsChecker claims dwFlags must not be zero. */
rv = TransmitFile(sock->socketdes, /* socket */
file->filehand, /* open file descriptor of the file to be sent */
nbytes, /* number of bytes to send. 0=send all */
0, /* Number of bytes per send. 0=use default */
&overlapped, /* OVERLAPPED structure */
ptfb, /* header and trailer buffers */
dwFlags); /* flags to control various aspects of TransmitFile */
if (!rv)
{
status = apr_get_netos_error();
if ((status == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) ||
(status == APR_FROM_OS_ERROR(WSA_IO_PENDING)))
{
rv = WaitForSingleObject(wait_event,
(DWORD)(sock->timeout >= 0
? sock->timeout_ms : INFINITE));
if (rv == WAIT_OBJECT_0)
status = APR_SUCCESS;
else if (rv == WAIT_TIMEOUT)
status = APR_FROM_OS_ERROR(WAIT_TIMEOUT);
else if (rv == WAIT_ABANDONED)
status = APR_FROM_OS_ERROR(WAIT_TIMEOUT);
else
status = apr_get_os_error();
}
}Atl ZEvtSyncSocket::Write WSAOVERLAPPED o;
o.hEvent = m_hEventWrite;
WSAResetEvent(o.hEvent);
if (WSASend(m_socket, pBuffers, nCount, pdwSize, 0, &o, 0))
{
DWORD dwLastError = WSAGetLastError();
if (dwLastError != WSA_IO_PENDING)
{
m_dwLastError = dwLastError;
bRet = false;
}
} // wait for write to complete
if (bRet)
{
if (WaitForSingleObject((HANDLE)m_hEventWrite, m_dwSocketTimeout) == WAIT_OBJECT_0)
{
DWORD dwFlags = 0;
if (WSAGetOverlappedResult(m_socket, &o, pdwSize, FALSE, &dwFlags))
bRet = true;
else
{
m_dwLastError = ::GetLastError();
bRet = false;
}
}
else
bRet = false;
}
return bRet;这两个片段都使用了重叠IO,并利用Event等待操作完成.
它们的OVERLAPPED变量都存放在栈上,它们都等待指定的时间,如果没有完成返回超时错误.它们在超时错误发生后都未进行CancelIo操作,也就是说重叠操作仍在进行,完成后不管是否有错,系统都会对OVERLAPPED变量做修改(错误值和传输字节数).而OVERLAPPED变量早已被销毁,也许已做后来进行操作的变量使用,这样修改后就造成了不确定的错误.如果以上理解正确的话,它们都不约而同的出现同样的错误,事实上还有许多代码也这样使用过.是设计者没有考虑到,还是有其它的原因使这个错误不会发生.我认为没考虑到的可能性较大些,希望有编写经验的或也写过类似代码的朋友来做个合理的解答.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货