Solution46
LibNewDel.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// 生成消滅演算子ライブラリ実装ファイル
4 ///
5 /// 生成消滅演算子ライブラリ実装ファイルです。
6 ///
7 /// $Id: LibNewDel.cpp 245 2019-03-20 15:03:41Z admin $
8 /// $Date: 2019-03-21 00:03:41 +0900 (2019/03/21 (木)) $
9 /// $Author: admin $
10 ///
11 /// @attention なし
12 
13 #pragma managed( push, off )
14 
15 //=============================================================================
16 // インクルードファイル
17 #include <LibNewDel.h>
18 #include <CSyncAuto.h>
19 #include <CProcess.h>
20 #include <LibLogOut.h>
21 #include <LibUtility.h>
22 
23 //=============================================================================
24 // インクルード実装ファイル
25 #include <LibCommon.hpp>
26 
27 //=============================================================================
28 // 生成消滅演算子ライブラリ名前空間
29 namespace LibNewDel {
30  //=========================================================================
31  // 生成消滅演算子ライブラリクラス
32  //=========================================================================
33  // 構築子と解体子
34  //-------------------------------------------------------------------------
35  // コンストラクタ
37  // 基底クラスコンストラクタ
38  : CMapping()
39  // メンバ変数初期化
40  , m_psMappingInfo( nullptr )
41  , m_bLogOut( false )
42  {
43  // コンストラクタ実行通知
45 
46  // 処理ブロック
47  bool result = false;
48  do {
49  // マッピングメモリを作成する
50  if ( !Create( sizeof( SMappingInfo ), OBJECT_NAME ) ) {
51  // 失敗!
52  break;
53  }
54  // 同期処理ブロック
55  else do {
56  CSyncAuto cSyncAuto( *this );
57 
58  // 共有メモリ情報構造体ポインタを取得する
59  m_psMappingInfo = reinterpret_cast< SMappingInfo* >( GetView() );
60  if ( nullptr == m_psMappingInfo ) {
61  // 致命的エラー!
63  break;
64  }
65 
66  // プロセス情報を巡回する
67  DWORD dwProcessId = ::GetCurrentProcessId();
68  for ( int nIndex = 0; PROCESS_MAX > nIndex; ++nIndex ) {
69  // プロセスIDを調べる
70  if ( 0 == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
71  // プロセスIDを設定する
72  m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId = dwProcessId;
73 
74  // 終了!
75  break;
76  }
77  }
78 
79  // 参照カウントをインクリメントする
81 
82  // 成功!
83  result = true;
84  } while ( false );
85  } while ( false );
86 
87  // 実行結果を調べる
88  if ( !result ) {
89  // マッピングをクローズする
91  }
92  }
93 
94  //-------------------------------------------------------------------------
95  // デストラクタ
97  // デストラクタ実行通知
99 
100  // 同期処理ブロック
101  do {
102  CSyncAuto cSyncAuto( *this );
103 
104  // プロセス情報を更新する
105  UpdateProcessInfo( true );
106  } while ( false );
107  }
108 
109  //=========================================================================
110  // 公開関数
111  //-------------------------------------------------------------------------
112  // 生成演算子実行通知関数
113  void CLibNewDel::NotifyOperatorNew( void* pAddr, size_t uSize, wchar_t const* pszFuncName ) noexcept {
114  // 同期処理ブロック
115  do {
116  CSyncAuto cSyncAuto( *this );
117 
118  // ログ出力許可フラグを調べる
119  if ( m_bLogOut ) {
120  // プロセス情報を更新する
122  }
123 
124  // 生成消滅カウントをインクリメントする
126 
127  // トータルサイズに加算する
128  m_psMappingInfo->m_nTotalSize += uSize;
129 
130  // 最大サイズを更新する
133  }
134 
135  // ログ出力する
137 
138  // プロセス情報を巡回する
139  DWORD dwProcessId = ::GetCurrentProcessId();
140  for ( int nIndex = 0;; ++nIndex ) {
141  // インデックスを調べる
142  if ( PROCESS_MAX <= nIndex ) {
143  // 致命的エラー!
145  break;
146  }
147  // プロセスIDを調べる
148  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
149  // プロセス単位の生成消滅演算子カウントをインクリメントする
150  ++m_psMappingInfo->m_sProcess[ nIndex ].m_nCount;
151 
152  // プロセス単位の生成消滅メモリサイズに加算する
153  m_psMappingInfo->m_sProcess[ nIndex ].m_nTotalSize += uSize;
154  break;
155  }
156  }
157  } while ( false );
158  }
159 
160  //-------------------------------------------------------------------------
161  // 消滅演算子実行通知関数
162  void CLibNewDel::NotifyOperatorDelete( void* pAddr, size_t uSize, wchar_t const* pszFuncName ) noexcept {
163  // 同期処理ブロック
164  do {
165  CSyncAuto cSyncAuto( *this );
166 
167  // ログ出力許可フラグを調べる
168  if ( m_bLogOut ) {
169  // プロセス情報を更新する
171  }
172 
173  // トータルサイズから減算する
174  m_psMappingInfo->m_nTotalSize -= uSize;
175 
176  // ログ出力する
178 
179  // 生成消滅カウントを調べる
180  if ( 0 == m_psMappingInfo->m_nCount ) {
181  // 致命的エラー!
183  break;
184  }
185 
186  // 生成消滅カウントをデクリメントする
188 
189  // プロセス情報を巡回する
190  DWORD dwProcessId = ::GetCurrentProcessId();
191  for ( int nIndex = 0;; ++nIndex ) {
192  // インデックスを調べる
193  if ( PROCESS_MAX <= nIndex ) {
194  // 致命的エラー!
196  break;
197  }
198  // プロセスIDを調べる
199  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
200  // プロセス単位の生成消滅演算子カウントをデクリメントする
201  --m_psMappingInfo->m_sProcess[ nIndex ].m_nCount;
202 
203  // プロセス単位の生成消滅メモリサイズから減算する
204  m_psMappingInfo->m_sProcess[ nIndex ].m_nTotalSize -= uSize;
205  break;
206  }
207  }
208  } while ( false );
209  }
210 
211  //=========================================================================
212  // 限定公開関数
213  //-------------------------------------------------------------------------
214  // プロセス情報更新関数
215  bool CLibNewDel::UpdateProcessInfo( bool bCurrent ) noexcept {
216  // 同期処理ブロック
217  bool result = false;
218  do {
219  CSyncAuto cSyncAuto( *this );
220 
221  // プロセス情報を巡回する
222  DWORD dwProcessId = ::GetCurrentProcessId();
223  for ( int nIndex = 0;; ++nIndex ) {
224  // インデックスを調べる
225  if ( PROCESS_MAX <= nIndex ) {
226  // 成功!
227  result = true;
228  break;
229  }
230  // プロセスIDを調べる
231  else if ( 0 == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
232  // 継続!
233  continue;
234  }
235  // プロセスIDを調べる
236  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
237  // カレントプロセス削除フラグを調べる
238  if ( !bCurrent ) {
239  // 継続!
240  continue;
241  }
242  }
243  else {
244  // プロセスをオープンする
245  CProcess cProcess;
246  if ( cProcess.Open( m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) ) {
247  // プロセス実行状態を調べる
248  if ( !cProcess.Wait( 0 ) ) {
249  // プロセスをクローズする
250  cProcess.Close();
251 
252  // 継続!
253  continue;
254  }
255 
256  // プロセスをクローズする
257  cProcess.Close();
258  }
259  }
260 
261  // 生成消滅カウントを減算する
263 
264  // トータルメモリサイズを減算する
266 
267  // 参照カウントを調べる
268  if ( 0 == m_psMappingInfo->m_nReffer ) {
269  // 致命的エラー!
271  break;
272  }
273 
274  // 参照カウントをデクリメントする
275  wchar_t const* pszMessage = L"";
276  if ( 0 == --m_psMappingInfo->m_nReffer ) {
277  // 生成消滅演算子情報更新ログを出力する
278  pszMessage = L", All Processes Termination";
279  }
280 
281  // プロセス終了生成消滅演算子ログを出力する
282  LogOutNoIndent( L"NewDel#%d, Total = %lld, Max = %lld, By Terminated Process[%04X], Count = %d, Size = %lld%s."
287  , m_psMappingInfo->m_sProcess[ nIndex ].m_nCount
289  , pszMessage );
290 
291  // プロセス情報をクリアする
293  m_psMappingInfo->m_sProcess[ nIndex ].m_nCount = 0;
294  m_psMappingInfo->m_sProcess[ nIndex ].m_nTotalSize = 0;
295  }
296  } while ( false );
297 
298  // 実行結果を返す
299  return result;
300  }
301 
302  //-------------------------------------------------------------------------
303  // 生成消滅演算子ログ出力関数
304  void CLibNewDel::LogOutOperatorNewDelete( int nCount, void* pAddr, size_t uSize, LONGLONG nTotalSize, LONGLONG nMaxSize, wchar_t const* pszFuncName ) noexcept {
305  // ログ出力許可フラグを調べる
306  if ( m_bLogOut ) {
307  // インデントなしでログ出力する
308  LogOutNoIndent( L"NewDel#%d, Total = %lld, Max = %lld, Addr = 0x%p, Size = %zu, By %s!%s.", nCount, nTotalSize, nMaxSize, pAddr, uSize, LogOutExeFile(), pszFuncName );
309  }
310  }
311 
312  //=========================================================================
313  // 静的公開関数
314  //-------------------------------------------------------------------------
315  // プロジェクト種別取得関数
316  wchar_t const* CLibNewDel::GetProjectType() noexcept {
317  // プロジェクト種別文字列を返す
318  return _PROJECT_TYPE;
319  }
320 
321  //-------------------------------------------------------------------------
322  // インスタンスハンドル取得関数
323  HINSTANCE CLibNewDel::GetInstanceHandle() noexcept {
324 #if defined( _WINDLL ) && !defined( _MANAGED )
325 
326  // インスタンスハンドルを返す
327  return s_hInstance;
328 
329 # else
330 
331  // 実行モジュールのインスタンスハンドルを返す
332  return ::GetModuleHandleW( nullptr );
333 
334 # endif
335  }
336 
337  //=========================================================================
338  // 静的限定公開文字列定数
339  wchar_t const* const CLibNewDel::OBJECT_NAME = L"LibNewDel::CLibNewDel";
340 
341  //=========================================================================
342  // 静的限定公開変数
344 }
345 
346 #pragma managed( pop )
#define NotifyConstructor()
コンストラクタ実行通知マクロ
Definition: LibUtility.h:24
int m_nCount
生成消滅カウント
Definition: LibNewDel.h:208
#define NotifyFatalError()
致命的エラー発生通知マクロ
Definition: LibUtility.h:22
virtual void Close() noexcept override
クローズ関数
Definition: CProcess.cpp:46
CLibNewDel() noexcept
コンストラクタ
Definition: LibNewDel.cpp:36
SProcessInfo m_sProcess[PROCESS_MAX]
参照プロセス情報構造体配列
Definition: LibNewDel.h:211
共通ライブラリ実装ヘッダファイル
DWORD m_dwProcessId
プロセスID
Definition: LibNewDel.h:194
static int const PROCESS_MAX
最大参照プロセス数
Definition: LibNewDel.h:181
int m_nReffer
参照カウント
Definition: LibNewDel.h:207
#define NotifyDestructor()
デストラクタ実行通知マクロ
Definition: LibUtility.h:25
virtual void LogOutOperatorNewDelete(int nCount, void *pAddr, size_t uSize, LONGLONG nTotalSize, LONGLONG nMaxSize, wchar_t const *pszFuncName) noexcept
生成消滅演算子ログ出力関数
Definition: LibNewDel.cpp:304
static HINSTANCE GetInstanceHandle() noexcept
インスタンスハンドル取得関数
Definition: LibNewDel.cpp:323
virtual LPVOID GetView() const noexcept
ビューポインタ取得関数
Definition: CMapping.h:79
static CLibNewDel s_cInstance
静的インスタンス
Definition: LibNewDel.h:228
virtual ~CLibNewDel() noexcept
デストラクタ
Definition: LibNewDel.cpp:96
virtual void NotifyOperatorDelete(void *pAddr, size_t uSize, wchar_t const *pszFuncName) noexcept
消滅演算子実行通知関数
Definition: LibNewDel.cpp:162
生成消滅演算子ライブラリ名前空間
Definition: LibNewDel.h:30
プロセスクラスヘッダファイル
#define _PROJECT_TYPE
プロジェクト種別定義
Definition: LibCommonDef.h:88
virtual bool Wait(DWORD dwTime=INFINITE) noexcept
ウェイト関数
Definition: CSync.cpp:59
virtual bool UpdateProcessInfo(bool bCurrent=false) noexcept
プロセス情報更新関数
Definition: LibNewDel.cpp:215
virtual void NotifyOperatorNew(void *pAddr, size_t uSize, wchar_t const *pszFuncName) noexcept
生成演算子実行通知関数
Definition: LibNewDel.cpp:113
SMappingInfo * m_psMappingInfo
共有メモリ情報構造体ポインタ
Definition: LibNewDel.h:217
生成消滅演算子ライブラリクラス
Definition: LibNewDel.h:38
virtual bool Open(DWORD dwProcessId, DWORD dwAccess=SYNCHRONIZE) noexcept
オープン関数
Definition: CProcess.cpp:114
static wchar_t const *const OBJECT_NAME
オブジェクト名
Definition: LibNewDel.h:223
static wchar_t const * GetProjectType() noexcept
プロジェクト種別取得関数
Definition: LibNewDel.cpp:316
bool m_bLogOut
ログ出力許可フラグ
Definition: LibNewDel.h:218
自動同期クラス
Definition: CSyncAuto.h:30
#define LogOutNoIndent(...)
インデントなし書式設定文字列行出力マクロ
Definition: LibLogOut.h:39
LONGLONG m_nTotalSize
トータルメモリサイズ
Definition: LibNewDel.h:196
マッピングクラス
Definition: CMapping.h:30
int m_nCount
生成消滅カウント
Definition: LibNewDel.h:195
virtual bool Create(DWORD dwSize, wchar_t const *pszObjectName=nullptr) noexcept
作成関数
Definition: CMapping.cpp:65
自動同期クラスヘッダファイル
LONGLONG m_nMaxSize
最大メモリサイズ
Definition: LibNewDel.h:210
生成消滅演算子ライブラリヘッダファイル
プロセスクラス
Definition: CProcess.h:30
#define LogOutExeFile()
実行ファイル名取得マクロ
Definition: LibLogOut.h:41
virtual void Close() noexcept override
クローズ関数
Definition: CMapping.cpp:48
ユーティリティライブラリヘッダファイル
LONGLONG m_nTotalSize
トータルメモリサイズ
Definition: LibNewDel.h:209
共有メモリ情報構造体
Definition: LibNewDel.h:206
ログ出力ライブラリヘッダファイル