/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2008?/X/X - 2014/01/28
/// 
/// @brief  スレッド関連。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_WIN_Base.h"

namespace CPL {
namespace WIN {

/// @cond
namespace zzz_ {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 閉じる
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct ThreadClose {
  ThreadClose(){}
  void operator()( HANDLE& handle )
  {
    if( handle )
    {
      CloseHandle( handle );
      handle = nullptr;
    }
  }
};

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 指定されたハンドルが非シグナルになるまで待つ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct ThreadWait {
  ThreadWait(){}
  DWORD operator()( HANDLE handle, DWORD time_out )
  {
    return WaitForSingleObject( handle, time_out );
  }
};
} // namespace zzz_
/// @endcond

// _____________________________________________________________________________
/// @brief Win32 スレッド制御？クラス
///
/// ※ 2014/08/26 削除(コメントアウト)
// *****************************************************************************
//class Thread
//  : public CPL::Core::Thread<zzz_::ThreadClose, zzz_::ThreadWait, HANDLE>
//{
//public:
//  Thread()
//    : CPL::Core::Thread<zzz_::ThreadClose, zzz_::ThreadWait, HANDLE>()
//  {}
//
//  ~Thread()
//  {}
//
//  bool
//    Create
//    ( void*         in_security    = nullptr,
//      unsigned int  in_stack_size  = 0,
//      void*         in_arg_list    = nullptr,
//      unsigned int  in_init_flag   = 0,
//      //unsigned int* in_thread_addr = nullptr,
//      char const*   in_thread_name = nullptr )
//  {
//    m_handle =
//      create_(
//        in_security,
//        in_stack_size,
//        in_arg_list,
//        CREATE_SUSPENDED,
//        in_thread_name );
//    if( !m_handle )
//    {
//      return false;
//    }
//    if( in_thread_name )
//    {
//      zzf_setThreadName( m_arg.thread_ID, in_thread_name );
//    }
//    if( in_init_flag == 0 )
//    {
//      Resume();
//    }
//    m_arg.flag_init = true;
//
//    return m_handle != nullptr;
//  }
//
//  void Suspend()
//  {
//    SuspendThread( m_handle );
//  }
//
//  void Resume()
//  {
//    ResumeThread( m_handle );
//  }
//
//  static const DWORD MS_VC_EXCEPTION=0x406D1388;
//protected:
//  #pragma pack(push,8)
//  typedef struct tagTHREADNAME_INFO
//  {
//     DWORD  dwType; // Must be 0x1000.
//     LPCSTR szName; // Pointer to name (in user addr space).
//     DWORD  dwThreadID; // Thread ID (-1=caller thread).
//     DWORD  dwFlags; // Reserved for future use, must be zero.
//  } THREADNAME_INFO;
//  #pragma pack(pop)
//
//  void zzf_setThreadName( DWORD dwThreadID, const char* threadName )
//  {
//#ifndef CPL_PLATFORM_64
//    if( dwThreadID ==-1  ||  !threadName ) return;
//    THREADNAME_INFO info;
//    info.dwType = 0x1000;
//    info.szName = threadName;
//    info.dwThreadID = dwThreadID;
//    info.dwFlags = 0;
//
//    _try
//    {
//      RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
//    }
//    _except(EXCEPTION_EXECUTE_HANDLER)
//    {
//    }
//#endif
//  }
//};



} // namespace WIN
} // namespace CPL
