Barst  2.0
A server that controls lab hardware.
mcdaq_device.cpp
1 
16 #include "base classses.h"
17 #include "named pipes.h"
18 #include "mcdaq_device.h"
19 #include "misc tools.h"
20 #include "cbw.h"
21 #include "WinError.h"
22 
23 int (EXTCCONV *lpf_cbDOut)(int BoardNum, int PortNum, USHORT DataValue) = NULL;
24 int (EXTCCONV *lpf_cbDIn)(int BoardNum, int PortNum, USHORT *DataValue) = NULL;
25 int (EXTCCONV *lpf_cbGetErrMsg)(int ErrCode, char *ErrMsg) = NULL;
26 int (EXTCCONV *lpf_cbDeclareRevision)(float *RevNum) = NULL;
27 int (EXTCCONV *lpf_cbGetRevision)(float *RevNum, float *VxDRevNum) = NULL;
28 
29 
30 DWORD WINAPI MCDAQProc(LPVOID lpParameter)
31 {
32  return ((CChannelMCDAQ *)lpParameter)->ThreadProc();
33 }
34 
35 
36 CManagerMCDAQ::CManagerMCDAQ(CComm* pcComm, const TCHAR szPipe[], int nChan, int &nError) :
37  m_usChans(GINUMBOARDS + GINUMEXPBOARDS), CManager(MCDAQ_MAN_STR, std::tstring(szPipe), nChan)
38 {
39  nError= 0;
40  m_bError= true;
41  m_pcComm= NULL;
42  m_pcLogBuffer= NULL;
43  m_pcMemPool= new CMemPool;
44  m_hLib= NULL;
45 
46  if (!pcComm || !szPipe)
47  {
48  nError= BAD_INPUT_PARAMS;
49  return;
50  }
51  BOOL bRes= GetProcAddresses(&m_hLib,
52 #ifdef _WIN64
53  _T("CBW64.dll")
54 #else
55  _T("CBW32.dll")
56 #endif
57  , 5, &lpf_cbDOut, "cbDOut", &lpf_cbDIn, "cbDIn", &lpf_cbGetErrMsg, "cbGetErrMsg",
58  &lpf_cbDeclareRevision, "cbDeclareRevision", &lpf_cbGetRevision, "cbGetRevision");
59  if (!bRes || !m_hLib)
60  {
61  nError= DRIVER_ERROR;
62  return;
63  }
64  float fVer = (float)(CURRENTREVNUM);
65  if (nError = MCDAQ_ERROR(lpf_cbDeclareRevision(&fVer), nError))
66  return;
67 
68  m_acDAQDevices.assign(m_usChans, NULL);
69  m_bError= false;
70  m_pcComm= pcComm;
71 }
72 
73 DWORD CManagerMCDAQ::GetInfo(void* pHead, DWORD dwSize)
74 {
75  if (!pHead)
76  return sizeof(SBaseOut);
77  if (dwSize<sizeof(SBaseOut))
78  return 0;
79 
80  ((SBaseOut*)pHead)->sBaseIn.dwSize= sizeof(SBaseOut);
81  ((SBaseOut*)pHead)->sBaseIn.eType= eResponseEx;
82  ((SBaseOut*)pHead)->sBaseIn.nChan= m_nChan;
83  ((SBaseOut*)pHead)->sBaseIn.nError= 0;
84  ((SBaseOut*)pHead)->bActive= true;
85  _tcsncpy_s(((SBaseOut*)pHead)->szName, DEVICE_NAME_SIZE, m_csName.c_str(), _TRUNCATE);
86 
87  return sizeof(SBaseOut);
88 }
89 
90 CManagerMCDAQ::~CManagerMCDAQ()
91 {
92  for (size_t i= 0; i < m_acDAQDevices.size(); ++i)
93  delete m_acDAQDevices[i];
94  if (m_hLib != NULL)
95  FreeLibrary(m_hLib);
96  delete m_pcMemPool;
97 }
98 
99 void CManagerMCDAQ::ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
100 {
101  if (m_bError)
102  return;
103  SBaseIn* pBase;
104  SData sData;
105  sData.pDevice= this;
106  SBaseIn sBase;
107  sBase.dwSize= sizeof(SBaseIn);
108  sBase.nChan= -1;
109  sBase.nError= 0;
110  bool bRes= true;
111  if (!pHead || dwSize < sizeof(SBaseIn) || dwSize != ((SBaseIn*)pHead)->dwSize) // incorrect size read
112  {
113  sBase.nError= SIZE_MISSMATCH;
114  } else if (((SBaseIn*)pHead)->eType == eQuery && dwSize == sizeof(SBaseIn)) // need info
115  {
116  sBase.eType= eQuery;
117  if (((SBaseIn*)pHead)->nChan < 0 || ((SBaseIn*)pHead)->nChan >= m_acDAQDevices.size() ||
118  !m_acDAQDevices[((SBaseIn*)pHead)->nChan]) // invalid channel
119  {
120  sBase.nError= INVALID_CHANN;
121  } else // send info on particular chann
122  {
123  bRes= false;
124  DWORD dwSizeInfo= m_acDAQDevices[((SBaseIn*)pHead)->nChan]->GetInfo(NULL, 0);
125  pBase= (SBaseIn*)m_pcMemPool->PoolAcquire(dwSizeInfo);
126  if (pBase)
127  {
128  m_acDAQDevices[((SBaseIn*)pHead)->nChan]->GetInfo(pBase, dwSizeInfo);
129  sData.dwSize= dwSizeInfo;
130  sData.pHead= pBase;
131  m_pcComm->SendData(&sData, llId);
132  }
133  }
134  } else if (dwSize == sizeof(SBaseIn) && ((SBaseIn*)pHead)->eType == eDelete) // delete a channel
135  {
136  sBase.eType= eDelete;
137  if (((SBaseIn*)pHead)->nChan < 0 || ((SBaseIn*)pHead)->nChan >= m_acDAQDevices.size() ||
138  !m_acDAQDevices[((SBaseIn*)pHead)->nChan])
139  sBase.nError= INVALID_CHANN;
140  else
141  {
142  delete m_acDAQDevices[((SBaseIn*)pHead)->nChan];
143  m_acDAQDevices[((SBaseIn*)pHead)->nChan]= NULL;
144  sBase.nChan= ((SBaseIn*)pHead)->nChan;
145  }
146  } else if (dwSize == sizeof(SBaseIn) && ((SBaseIn*)pHead)->eType == eVersion &&
147  ((SBaseIn*)pHead)->nChan == -1)
148  {
149  float fVer1, fVer2;
150  sBase.nError= MCDAQ_ERROR(lpf_cbGetRevision(&fVer1, &fVer2), sBase.nError);
151  sBase.dwInfo= (DWORD)(fVer1 * 10000);
152  sBase.eType= eVersion;
153  } else if (((SBaseIn*)pHead)->nChan < 0 || ((SBaseIn*)pHead)->nChan >= m_acDAQDevices.size())
154  {
155  sBase.eType= ((SBaseIn*)pHead)->eType;
156  sBase.nError= INVALID_CHANN;
157  } else if (((SBaseIn*)pHead)->eType == eSet && m_acDAQDevices[((SBaseIn*)pHead)->nChan])
158  {
159  sBase.eType= ((SBaseIn*)pHead)->eType;
160  sBase.nError= ALREADY_OPEN;
161  } else if (((SBaseIn*)pHead)->eType == eSet &&
162  ((SBaseIn*)pHead)->dwSize == sizeof(SBaseIn)+sizeof(SBase)+sizeof(SChanInitMCDAQ) &&
163  ((SBase*)((char*)pHead+sizeof(SBaseIn)))->eType == eMCDAQChanInit) // set a channel
164  {
165  bRes= false;
166  LARGE_INTEGER llStart;
167  sBase.eType= eSet; // in case of error we do respond at end
168  SChanInitMCDAQ sChanInit= *(SChanInitMCDAQ*)((char*)pHead+sizeof(SBase)+sizeof(SBaseIn));
169  std::tstringstream ss; // daq channel
170  ss<<((SBaseIn*)pHead)->nChan;
171  std::tstringstream ss2; // daq manager index
172  ss2<<m_nChan;
173  std::tstring csPipeName= m_csPipeName+_T(":")+ss2.str()+_T(":")+ss.str(); // new channel pipe name
174  CChannelMCDAQ* pcChan= NULL;
175  if (!sBase.nError)
176  pcChan= new CChannelMCDAQ(csPipeName.c_str(), ((SBaseIn*)pHead)->nChan, sChanInit, sBase.nError, llStart);
177  if (!sBase.nError)
178  {
179  m_acDAQDevices[((SBaseIn*)pHead)->nChan]= pcChan;
180  SBaseOut* pBaseO= (SBaseOut*)m_pcMemPool->PoolAcquire(sizeof(SBaseOut));
181  if (pBaseO)
182  {
183  pBaseO->sBaseIn.dwSize= sizeof(SBaseOut);
184  pBaseO->sBaseIn.eType= eResponseExL;
185  pBaseO->sBaseIn.nChan= ((SBaseIn*)pHead)->nChan;
186  pBaseO->sBaseIn.nError= 0;
187  pBaseO->llLargeInteger= llStart;
188  pBaseO->bActive= true;
189  sData.pHead= pBaseO;
190  sData.dwSize= pBaseO->sBaseIn.dwSize;
191  m_pcComm->SendData(&sData, llId);
192  }
193  } else
194  delete pcChan;
195  } else
196  sBase.nError= INVALID_COMMAND;
197 
198  if (sBase.nError || bRes)
199  {
200  sData.pHead= (SBaseIn*)m_pcMemPool->PoolAcquire(sizeof(SBaseIn));
201  if (sData.pHead)
202  {
203  sData.dwSize= sizeof(SBaseIn);
204  memcpy(sData.pHead, &sBase, sizeof(SBaseIn));
205  m_pcComm->SendData(&sData, llId);
206  }
207  }
208 }
209 
210 
211 
212 
213 
214 CChannelMCDAQ::CChannelMCDAQ(const TCHAR szPipe[], int nChan, SChanInitMCDAQ &sChanInit, int &nError,
215  LARGE_INTEGER &llStart) : CDevice(MCDAQ_CHAN_STR), m_csPipeName(szPipe),
216  m_sChanInit(sChanInit), m_usChan(nChan), m_hWriteEvent(CreateEvent(NULL,TRUE, FALSE, NULL)),
217  m_asWPackets(m_hWriteEvent)
218 {
219  m_bError= true;
220  m_pcComm= NULL;
221  m_pcMemPool= new CMemPool;
222  m_hStopEvent= NULL;
223  InitializeCriticalSection(&m_hReadSafe);
224  m_hThread= NULL;
225  m_usLastWrite = m_sChanInit.usInitialVal;
226  nError= 0;
227  if (!szPipe || m_sChanInit.ucDirection > 2)
228  {
229  nError= BAD_INPUT_PARAMS;
230  return;
231  }
232  m_hReadEvent = CreateEvent(NULL,TRUE, FALSE, NULL);
233  m_hStopEvent= CreateEvent(NULL,TRUE, FALSE, NULL);
234  if (!m_hStopEvent || !m_hReadEvent || !m_hWriteEvent)
235  {
236  nError= NO_SYS_RESOURCE;
237  return;
238  }
239 
240  unsigned short usRead = 0;
241  if (m_sChanInit.ucDirection)
242  nError= MCDAQ_ERROR(lpf_cbDOut(m_usChan, AUXPORT, m_sChanInit.usInitialVal), nError);
243  if (!nError && m_sChanInit.ucDirection != 1)
244  nError= MCDAQ_ERROR(lpf_cbDIn(m_usChan, AUXPORT, &usRead), nError);
245  if (nError)
246  return;
247 
248  m_pcComm= new CPipeServer; // our pipe over which comm to devices will occur
249  nError= static_cast<CPipeServer*>(m_pcComm)->Init(szPipe, ~0x80000000, MIN_BUFF_IN,
250  MIN_BUFF_OUT, this, NULL);
251  if (nError)
252  return;
253  m_hThread= CreateThread(NULL, 0, MCDAQProc, this, 0, NULL);
254  if (!m_hThread)
255  {
256  nError= NO_SYS_RESOURCE;
257  return;
258  }
259  llStart= m_cTimer.GetStart();
260  m_bError= false;
261 }
262 
263 DWORD CChannelMCDAQ::GetInfo(void* pHead, DWORD dwSize)
264 {
265  if (!pHead)
266  return 2*sizeof(SBaseOut)+sizeof(SBase)+sizeof(SChanInitMCDAQ);
267  if (dwSize<2*sizeof(SBaseOut)+sizeof(SBase)+sizeof(SChanInitMCDAQ))
268  return 0;
269 
270  ((SBaseOut*)pHead)->sBaseIn.dwSize= 2*sizeof(SBaseOut)+sizeof(SBase)+sizeof(SChanInitMCDAQ);
271  ((SBaseOut*)pHead)->sBaseIn.eType= eResponseEx;
272  ((SBaseOut*)pHead)->sBaseIn.nChan= m_usChan;
273  ((SBaseOut*)pHead)->sBaseIn.nError= 0;
274  ((SBaseOut*)pHead)->bActive= true;
275  _tcsncpy_s(((SBaseOut*)pHead)->szName, DEVICE_NAME_SIZE, m_csName.c_str(), _TRUNCATE);
276  pHead= (char*)pHead+ sizeof(SBaseOut);
277 
278  ((SBaseOut*)pHead)->sBaseIn.dwSize = sizeof(SBaseOut);
279  ((SBaseOut*)pHead)->sBaseIn.eType = eResponseExL;
280  ((SBaseOut*)pHead)->sBaseIn.nChan = m_usChan;
281  ((SBaseOut*)pHead)->sBaseIn.nError = 0;
282  ((SBaseOut*)pHead)->bActive = true;
283  ((SBaseOut*)pHead)->llLargeInteger = m_cTimer.GetStart();
284  pHead = (char*)pHead + sizeof(SBaseOut);
285 
286  ((SBase*)pHead)->dwSize= sizeof(SChanInitMCDAQ)+sizeof(SBase);
287  ((SBase*)pHead)->eType= eMCDAQChanInit;
288  pHead= (char*)pHead+ sizeof(SBase);
289  memcpy(pHead, &m_sChanInit, sizeof(SChanInitMCDAQ));
290 
291  return 2*sizeof(SBaseOut)+sizeof(SBase)+sizeof(SChanInitMCDAQ);
292 }
293 
294 CChannelMCDAQ::~CChannelMCDAQ()
295 {
296  if (m_hThread && (WAIT_OBJECT_0 != SignalObjectAndWait(m_hStopEvent, m_hThread, 2000, FALSE)))
297  TerminateThread(m_hThread, 0);
298  if (m_hThread) CloseHandle(m_hThread);
299  if (m_pcComm) m_pcComm->Close();
300 
301  bool bValid;
302  SMCDAQPacket* psPackt;
303  while (m_asWPackets.GetSize())
304  {
305  psPackt= m_asWPackets.Front(true, bValid);
306  if (psPackt && bValid)
307  {
308  delete psPackt->psData;
309  delete psPackt;
310  }
311  }
312 
313  if (m_hStopEvent) CloseHandle(m_hStopEvent);
314  if (m_hWriteEvent) CloseHandle(m_hWriteEvent);
315  if (m_hReadEvent) CloseHandle(m_hReadEvent);
316  DeleteCriticalSection(&m_hReadSafe);
317  delete m_pcComm;
318  delete m_pcMemPool;
319 }
320 
321 void CChannelMCDAQ::ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
322 {
323  if (m_bError)
324  return;
325  int nError= 0;
326  SBaseIn* pBase= (SBaseIn*)pHead;
327  if (!pBase || dwSize < sizeof(SBaseIn) || dwSize != pBase->dwSize) // incorrect size read
328  nError= SIZE_MISSMATCH;
329  else if (!((pBase->eType == eQuery || ((pBase->eType == eTrigger ||
330  pBase->eType == eCancelReadRequest) && m_sChanInit.ucDirection != 1)) &&
331  dwSize == sizeof(SBaseIn)) && !(pBase->eType == eData && m_sChanInit.ucDirection &&
332  ((SBase*)((char*)pBase+sizeof(SBaseIn)))->eType == eMCDAQWriteData && // write
333  dwSize == sizeof(SBaseIn)+sizeof(SBase)+sizeof(SMCDAQWData)))
334  nError= INVALID_COMMAND;
335  else if (pBase->nChan != m_usChan)
336  nError= INVALID_CHANN;
337 
338  SData sData;
339  sData.pDevice= this;
340  sData.dwSize= sizeof(SBaseIn);
341  if (nError) // bad read
342  {
343  pBase= (SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
344  if (pBase)
345  {
346  pBase->dwSize= sizeof(SBaseIn);
347  pBase->eType= eResponse;
348  pBase->nChan= -1;
349  pBase->nError= nError;
350  sData.pHead= pBase;
351  m_pcComm->SendData(&sData, llId);
352  }
353  } else if (pBase->eType == eQuery) // send back info on channel
354  {
355  sData.dwSize= GetInfo(NULL, 0);
356  sData.pHead= m_pcMemPool->PoolAcquire(sData.dwSize);
357  if (sData.pHead && GetInfo(sData.pHead, sData.dwSize) == sData.dwSize)
358  m_pcComm->SendData(&sData, llId);
359  } else if (pBase->eType == eData) // need to queue write request
360  {
361  SMCDAQPacket *psPacket = new SMCDAQPacket;
362  psPacket->llId = llId;
363  psPacket->psData = new SMCDAQWData;
364  *psPacket->psData = *((SMCDAQWData *)((char *)pBase + sizeof(SBaseIn) + sizeof(SBase)));
365  m_asWPackets.Push(psPacket);
366  } else if (pBase->eType == eTrigger) // add this read request
367  {
368  EnterCriticalSection(&m_hReadSafe);
369  int k = 0;
370  for (; k < m_allReads.size(); ++k)
371  if (m_allReads[k] == llId)
372  break;
373  if (!m_sChanInit.bContinuous || k == m_allReads.size())
374  {
375  m_allReads.push_back(llId);
376  SetEvent(m_hReadEvent);
377  k = -1;
378  }
379  LeaveCriticalSection(&m_hReadSafe);
380  if (k != -1)
381  {
382  pBase= (SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
383  if (pBase)
384  {
385  pBase->dwSize= sizeof(SBaseIn);
386  pBase->eType= ((SBaseIn*)pHead)->eType;
387  pBase->nChan= ((SBaseIn*)pHead)->nChan;
388  pBase->nError= ALREADY_OPEN;
389  sData.pHead= pBase;
390  m_pcComm->SendData(&sData, llId);
391  }
392  }
393  } else // remove this read request
394  {
395  EnterCriticalSection(&m_hReadSafe);
396  for (int k = 0; k < m_allReads.size(); ++k)
397  {
398  if (m_allReads[k] == llId)
399  {
400  m_allReads.erase(m_allReads.begin() + k);
401  break;
402  }
403  }
404  if (!m_allReads.size())
405  ResetEvent(m_hReadEvent);
406  LeaveCriticalSection(&m_hReadSafe);
407  pBase= (SBaseIn*)m_pcMemPool->PoolAcquire(sData.dwSize);
408  if (pBase)
409  {
410  pBase->dwSize= sData.dwSize;
411  pBase->eType= ((SBaseIn*)pHead)->eType;
412  pBase->nChan= ((SBaseIn*)pHead)->nChan;
413  pBase->nError= 0;
414  sData.pHead= pBase;
415  m_pcComm->SendData(&sData, llId);
416  }
417  }
418 }
419 
420 DWORD CChannelMCDAQ::ThreadProc()
421 {
422  HANDLE ahEvents[]= {m_hStopEvent, m_hWriteEvent, m_hReadEvent};
423  bool bDone= false, bValid;
424  DWORD dwWait = INFINITE;
425  unsigned short usData;
426  SData sData;
427  sData.pDevice= this;
428  SBaseOut sBaseOut;
429  SBaseIn sBaseIn;
430  memset(&sBaseOut, 0, sizeof(SBaseOut));
431  sBaseOut.bActive= true;
432  sBaseOut.sBaseIn.eType= eResponseExD;
433  sBaseOut.sBaseIn.nChan= m_usChan;
434  sBaseIn.nError = 0;
435  sBaseIn.eType = eData;
436  sBaseIn.dwSize = sizeof(SBaseIn);
437  SMCDAQPacket* psPacket;
438 
439  while (!bDone)
440  {
441  switch (WaitForMultipleObjects(sizeof(ahEvents) / sizeof(HANDLE), &ahEvents[0], FALSE, dwWait))
442  {
443  case WAIT_OBJECT_0+1: // user requested write
444  {
445  ResetEvent(m_hWriteEvent); // event won't be set again as long as queue is not empty
446  psPacket= m_asWPackets.Front(true, bValid);
447  if (m_asWPackets.GetSize())
448  SetEvent(m_hWriteEvent);
449  if (!psPacket || !bValid) // valid queue element
450  break;
451  sBaseOut.sBaseIn.nError = MCDAQ_ERROR(lpf_cbDOut(m_usChan, AUXPORT,
452  (psPacket->psData->usBitSelect & psPacket->psData->usValue) |
453  (~psPacket->psData->usBitSelect & m_usLastWrite)), sBaseOut.sBaseIn.nError);
454  m_usLastWrite = ((psPacket->psData->usBitSelect & psPacket->psData->usValue) |
455  (~psPacket->psData->usBitSelect & m_usLastWrite));
456  sBaseOut.dDouble = g_cTimer.Seconds();
457  sData.dwSize = sizeof(SBaseOut);
458  sBaseOut.sBaseIn.dwSize = sData.dwSize;
459  SBaseOut* pBase = (SBaseOut*)m_pcMemPool->PoolAcquire(sData.dwSize);
460  if (pBase)
461  {
462  sData.pHead= pBase;
463  *pBase = sBaseOut;
464  m_pcComm->SendData(&sData, psPacket->llId);
465  }
466  delete psPacket->psData;
467  delete psPacket;
468  break;
469  }
470  case WAIT_OBJECT_0 + 2: // user requested read
471  {
472  ResetEvent(m_hReadEvent); // event won't be set again as long as queue is not empty
473  sBaseOut.sBaseIn.nError = MCDAQ_ERROR(lpf_cbDIn(m_usChan, AUXPORT, &usData), sBaseOut.sBaseIn.nError);
474  sBaseIn.dwInfo = usData;
475  sBaseOut.dDouble= g_cTimer.Seconds();
476  sData.dwSize = sizeof(SBaseOut) + sizeof(SBaseIn);
477  sBaseOut.sBaseIn.dwSize = sData.dwSize;
478  EnterCriticalSection(&m_hReadSafe);
479  SBaseOut* pBase;
480  for (int i = 0; i < m_allReads.size(); ++i)
481  {
482  pBase = (SBaseOut *)m_pcMemPool->PoolAcquire(sData.dwSize);
483  if (pBase)
484  {
485  sData.pHead = pBase;
486  *pBase = sBaseOut;
487  *((SBaseIn *)((char *)pBase + sizeof(SBaseOut))) = sBaseIn;
488  if (m_pcComm->SendData(&sData, m_allReads[i]))
489  m_allReads[i] = -1;
490  }
491  }
492  if (!m_sChanInit.bContinuous)
493  m_allReads.clear();
494  int k = 0;
495  while (k < m_allReads.size()) // remove bad pipes
496  {
497  if (m_allReads[k] == -1)
498  m_allReads.erase(m_allReads.begin() + k);
499  else
500  k += 1;
501  }
502  if (m_allReads.size())
503  SetEvent(m_hReadEvent);
504  LeaveCriticalSection(&m_hReadSafe);
505  break;
506  }
507  case WAIT_OBJECT_0:
508  default:
509  bDone= true;
510  break;
511  }
512  dwWait= INFINITE;
513  }
514 
515  sBaseOut.sBaseIn.dwSize= sizeof(SBaseIn);
516  sBaseOut.sBaseIn.eType= eResponse;
517  sBaseOut.sBaseIn.nError= DEVICE_CLOSING;
518  sData.dwSize= sizeof(SBaseIn);
519  EnterCriticalSection(&m_hReadSafe);
520  for (int i = 0; i < m_allReads.size(); ++i)
521  {
522  sData.pHead = m_pcMemPool->PoolAcquire(sData.dwSize);
523  if (sData.pHead)
524  {
525  *(SBaseIn *)sData.pHead = sBaseOut.sBaseIn;
526  m_pcComm->SendData(&sData, m_allReads[i]);
527  }
528  }
529  m_allReads.clear();
530  LeaveCriticalSection(&m_hReadSafe);
531  while (m_asWPackets.GetSize())
532  {
533  psPacket = m_asWPackets.Front(true, bValid);
534  if (!psPacket || !bValid)
535  continue;
536  sData.pHead= m_pcMemPool->PoolAcquire(sData.dwSize);
537  if (sData.pHead)
538  {
539  *(SBaseIn *)sData.pHead = sBaseOut.sBaseIn;
540  m_pcComm->SendData(&sData, psPacket->llId);
541  }
542  delete psPacket->psData;
543  delete psPacket;
544  }
545  return 0;
546 }
virtual int SendData(const SData *pData, __int64 llId)=0
LARGE_INTEGER GetStart() const
Definition: misc tools.h:69
void ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
virtual DWORD GetInfo(void *pHead, DWORD dwSize)
void ProcessData(const void *pHead, DWORD dwSize, __int64 llId)
int GetSize()
Definition: cpl queue.h:52
CChannelMCDAQ(const TCHAR szPipe[], int nChan, SChanInitMCDAQ &sChanInit, int &nError, LARGE_INTEGER &llStart)
double Seconds() const
Definition: misc tools.cpp:63
virtual void Close()=0
DWORD GetInfo(void *pHead, DWORD dwSize)
const std::tstring m_csName
Definition: base classses.h:98
void Push(T pHead)
Definition: cpl queue.h:26
T Front(bool bPop, bool &bValid)
Definition: cpl queue.h:38