📄 opcdrvthread.cpp
字号:
// OpcDrvThread.cpp
//
// This file contains functions used to initialize a server
// object for use with the background "helper" thread.
//
// (c) COPYRIGHT 1996-1998, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
//
// Functions defined in this module:
//
// InitServerSlot()
// DeleteServerSlot()
// FindServerSlot()
// ClearServerSlot()
// GetServerSlotCount()
// CalcServerBandWidthThread()
// ChangeDriverThreadPriority()
//
//
//
// Modification Log:
// Vers Date By Notes
// ---- -------- --- -----
// 1.0 08/26/97 jra Created
// 1.3 03/10/98 jra Modified to be wizard generated and driver specific.
// 7.11 11/03/98 jra Modified ChangeDriverThreadPriority()to to change the
// priority class because Workspace can't handle having its
// priority tweaked.
// 7.13 02/29/00 jra Added DeleteServerSlot() to perform shutdown cleanup and
// removed call to DeleteCriticalSecion() in ClearServerSlot()
//
//
#define WIN32_LEAN_AND_MEAN
#include "OpcStdAfx.h"
#include "OPCDrvThread.h"
#include "OPCDrv.h"
#include <process.h>
// Global variables
//
static CMap<int, int, COPCDrvServer*, COPCDrvServer*&> g_mapServers;
static int g_nLocation = 1;
static CRITICAL_SECTION g_csServerMap;
static DWORD g_dwBwThreadId = 0;
static HANDLE g_hBwThread = 0;
static BOOL g_bKeepRunning = TRUE;
static UINT __stdcall CalcServerBandWidthThread(void *pParam);
static inline void Lock(void) { EnterCriticalSection(&g_csServerMap); }
static inline void UnLock(void) { LeaveCriticalSection(&g_csServerMap); }
////////////////////////////////////////////////////////////////
// InitServerSlot()
//
// @desc Initialization at startup
//
// @parm none
//
// @retval void
//
// TODO: Any additional initialization
//
////////////////////////////////////////////////////////////////
void InitServerSlot(void)
{
// We initialize the hash table to an arbitrary prime number,
// init the critical section, etc...
g_mapServers.InitHashTable(13);
InitializeCriticalSection(&g_csServerMap);
}
////////////////////////////////////////////////////////////////
// DeleteServerSlot()
//
// @desc Cleanup at shutdown
//
// @parm none
//
// @retval void
//
// TODO: Any additional cleanup
//
////////////////////////////////////////////////////////////////
void DeleteServerSlot(void)
{
// Delete the critical section
DeleteCriticalSection(&g_csServerMap);
}
////////////////////////////////////////////////////////////////
// FindServerSlot()
//
// @desc Adds the server to the map
//
// @parm IN int * | pnSlotNumber | Returned location in the map
// @parm IN COPCDrvServer * | pServer | Pointer to the server to add
//
////////////////////////////////////////////////////////////////
BOOL FindServerSlot(int *pnSlotNumber,
COPCDrvServer *pServer)
{
*pnSlotNumber = g_nLocation++;
Lock();
g_mapServers.SetAt(*pnSlotNumber, pServer);
UnLock();
// If this is the first server being added, then start the
// bandwidth thread.
if (NULL == g_hBwThread)
{
g_dwBwThreadId = 0;
unsigned int nAddress = 0;
g_hBwThread = (HANDLE)_beginthreadex(NULL,
0,
CalcServerBandWidthThread,
NULL,
0,
&nAddress);
}
return TRUE;
}
////////////////////////////////////////////////////////////////
// ClearServerSlot()
//
// @desc 'UnRegister' the server
//
// @parm IN int | nSlotNumber | Location in the map
//
// @retval void
//
////////////////////////////////////////////////////////////////
void ClearServerSlot(IN int nSlotNumber)
{
int nNumServers;
Lock();
g_mapServers.RemoveKey(nSlotNumber);
nNumServers = g_mapServers.GetCount();
UnLock();
// If the map is now empty, then the last server object has
// been released, so shutdown the bandwidth thread.
if (0 == nNumServers)
{
g_bKeepRunning = FALSE;
if (WaitForSingleObject(g_hBwThread,
THREAD_SHUTDOWN_TIME) == WAIT_TIMEOUT)
{
TerminateThread(g_hBwThread, 0);
}
g_dwBwThreadId = 0;
g_hBwThread = NULL;
}
}
////////////////////////////////////////////////////////////////
// GetServerSlotCount()
//
// @desc Returns the number of instanciated server objects
//
// @parm none
//
// @retval int
//
////////////////////////////////////////////////////////////////
int GetServerSlotCount(void)
{
return g_mapServers.GetCount();
}
////////////////////////////////////////////////////////////////
// CalcServerBandWidthThread()
//
// @desc This thread calculates the bandwidth for all server objects.
// The bandwidth is calculated as follows:
//
// Bandwidth = (# Groups Processed / # Groups Updated) * 100%
//
// @parm IN void * | pParam | Passed in by _beginthreadex()
//
// @retval UINT
//
////////////////////////////////////////////////////////////////
UINT __stdcall CalcServerBandWidthThread(IN void *pParam)
{
DWORD dwNumGroupsProcessed = 0,
dwTotalPasses = 0,
dwPriority = 13;
int nKey = 0;
POSITION posServer = NULL;
COPCDrvServer *pServer = NULL;
// Increase the thread priority because this thread will do very little
if (!ChangeDriverThreadPriority(dwPriority))
{
LogEventMessage(TEXT("Unable to change bandwidth thread priority"),
TEXT("OPCNIO"),
6);
}
// Get the id of this thread
g_dwBwThreadId = GetCurrentThreadId();
while(g_bKeepRunning)
{
Sleep(500);
Lock();
posServer = g_mapServers.GetStartPosition();
while ((NULL != posServer) && (g_bKeepRunning))
{
g_mapServers.GetNextAssoc(posServer, nKey, pServer);
//
// We don't bother to lock the server here because this is just
// a diagnostic estimate of the percent bandwidth that the server
// is running at.
//
// Get temp copies for calculations and make sure they are valid
if ((0 == (dwTotalPasses = pServer->m_dwTotalPasses)) ||
(0 == (dwNumGroupsProcessed = pServer->m_dwNumGroupsProcessed)))
{
pServer->m_dwBandwidth = 0;
}
else
{
pServer->m_dwBandwidth =
(DWORD)(((float)dwNumGroupsProcessed / (float)dwTotalPasses) * 100);
}
pServer->m_dwTotalPasses = pServer->m_dwNumGroupsProcessed = 0;
}
UnLock();
}
_endthreadex(0);
return 0;
}
////////////////////////////////////////////////////////////////
// ChangeDriverThreadPriority()
//
// @desc This function will adjust the priority of the thread from which
// it is called. It takes a priority from 1 to 15 and attempts to
// change the class and priority to come as close as possible to
// the selected priority.
//
// @parm IN DWORD | dwPriority | New thread priority (1 - 15)
//
// @retval BOOL | TRUE - Priority successfully changed
// @retval BOOL | FALSE - Error
//
////////////////////////////////////////////////////////////////
BOOL ChangeDriverThreadPriority(IN DWORD dwPriority)
{
DWORD dwClassLevel,
dwPriorityLevel;
switch (dwPriority)
{
case 1:
dwClassLevel = IDLE_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_IDLE;
break;
case 2:
dwClassLevel = IDLE_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_LOWEST;
break;
case 3:
dwClassLevel = IDLE_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_BELOW_NORMAL;
break;
case 4:
dwClassLevel = IDLE_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_NORMAL;
break;
case 5:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_LOWEST;
break;
case 6:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_BELOW_NORMAL;
break;
case 7:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_NORMAL;
break;
case 8:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_ABOVE_NORMAL;
break;
case 9:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_HIGHEST;
break;
case 10:
dwClassLevel = NORMAL_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_HIGHEST;
break;
case 11:
dwClassLevel = HIGH_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_LOWEST;
break;
case 12:
dwClassLevel = HIGH_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_BELOW_NORMAL;
break;
case 13:
dwClassLevel = HIGH_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_NORMAL;
break;
case 14:
dwClassLevel = HIGH_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_ABOVE_NORMAL;
break;
case 15:
dwClassLevel = HIGH_PRIORITY_CLASS;
dwPriorityLevel = THREAD_PRIORITY_HIGHEST;
break;
default:
return(FALSE);
break;
}
// jra 110398
// Remove call to SetPriorityClass() because Workspace can't have it's
// priority changed.
// if (SetPriorityClass(GetCurrentProcess(), dwClassLevel))
// {
return(SetThreadPriority(GetCurrentThread(), dwPriorityLevel));
// }
return(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -