📄 asyncreceiver.cpp
字号:
/************************************************************************
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
************************************************************************/
/************************************************************************
*
* Module: AsyncReceiver.h
* Long name: CAsyncReceiver class implementation
* Description: Simple class that continuously receives data transferred
* by asynchronous WRITE requests (based on CVhpdDataSlave).
*
* Runtime Env.: Win32
* Author(s): Frank Senf
* Company: Thesycon GmbH, Ilmenau
************************************************************************/
#include "AsyncReceiver.h"
// constructor
CAsyncReceiver::CAsyncReceiver()
{
// init members
m_File = NULL;
m_ThreadExited = false;
m_BufferError = 0;
m_LastError = 0;
} // ctor
// destructor
CAsyncReceiver::~CAsyncReceiver()
{
CloseFile();
} // dtor
// open the destination file
unsigned long CAsyncReceiver::OpenFile(const char *Filename)
{
unsigned long retval;
if ( m_File == NULL ) {
// open the file, if it already exists it will be overwritten
m_File = ::CreateFile(
Filename, // name of file
GENERIC_WRITE, // access mode
FILE_SHARE_READ, // share mode (0=not shared)
NULL, // security descriptor
CREATE_ALWAYS, // how to create
FILE_FLAG_WRITE_THROUGH, // file flags and attributes
NULL // handle to template file
);
if ( m_File == INVALID_HANDLE_VALUE ) {
// opening output file failed
retval = ::GetLastError();
m_File = NULL;
} else {
// file successfully opened
retval = 0;
}
} else {
// an output file was already opened
retval = 1;
}
return retval;
} // OpenFile
// close the destination file
void CAsyncReceiver::CloseFile()
{
if ( m_File!=NULL ) {
::CloseHandle(m_File);
m_File = NULL;
}
} // CloseFile
// overloaded CVhpdThread::TerminateThread() function
// NOTE 1: called in the context of the main thread
// NOTE 2: TerminateThread() is overloaded to ensure that the
// thread will exit. This is done by trying to terminate the
// thread until it really terminates. For future version of VHPDLib
// this will be implemented by the base class
void CAsyncReceiver::TerminateThread()
{
// cancel all pending notification buffers, this forces the worker thread
// to resume from a wait state and check for termination
AbortIoBuffers();
// now wait for the thread to terminate
if ( mThreadHandle != NULL ) {
// loop until thread has terminated
for (;;) {
// wait on thread handle, 40 ms timeout
DWORD err = WaitForSingleObject(mThreadHandle,40);
if ( err==WAIT_OBJECT_0 ) {
// handle is signaled, done
break;
}
if ( err==WAIT_TIMEOUT ) {
// wait timed out
// cancel all pending notification buffers again, should force the worker thread
// to resume from the wait state and check for termination
AbortIoBuffers();
// loop and wait again
continue;
}
// neither WAIT_OBJECT_0 nor WAIT_TIMEOUT returned -> error during wait
break;
} // for()
}
} // TerminateThread
// overloaded CVhpdThread::OnThreadExit() function
// NOTE: It is called in the context of the worker thread.
void CAsyncReceiver::OnThreadExit()
{
// store new thread state
m_ThreadExited = true;
} // OnThreadExit
// overloaded CVhpdDataSlave::PostProcessBuffer() function
// NOTE: It is called in the context of the worker thread.
BOOL CAsyncReceiver::PostProcessBuffer(CVhpdBuf *Buf)
{
if ( Buf->mStatus == VHPD_STATUS_SUCCESS ) {
if ( Buf->mBytesTransferred != 0 ) {
// test for an output file
if ( m_File != NULL ) {
// output file is available
// write buffer data to output file
unsigned long bytecount = 0;
BOOL succ = ::WriteFile(m_File, Buf->Buffer(), Buf->mBytesTransferred, &bytecount, NULL);
if ( (!succ) || (bytecount != Buf->mBytesTransferred) ) {
// serious error, stop reception
return FALSE;
}
} else {
// no output file, just discard buffer data
}
} else {
// empty buffer received, just continue
}
} else {
// completed with error, store error and continue
m_BufferError++;
m_LastError = Buf->mStatus;
}
return TRUE;
} // PostProcessBuffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -