OSDN Git Service

Update TranslationsStatus.*
[winmerge-jp/winmerge-jp.git] / Src / Concurrent.h
1 /* Later delete this file and use Parallel Patterns Library instead */
2 #pragma once
3
4 namespace Concurrent
5 {
6         template <class ResultType>
7         class Task
8         {
9         private:
10                 struct TaskParams
11                 {
12                         std::function<ResultType()> m_func;
13                         HANDLE m_hThread;
14                         ResultType m_result;
15                         bool m_detached;
16                         bool m_completed;
17                 };
18
19                 Task(TaskParams *pParams) : m_pParams(pParams)
20                 {
21                 }
22
23         public:
24                 Task() : m_pParams(nullptr) {}
25                 Task(Task&& other)
26                 {
27                         m_pParams = other.m_pParams;
28                         other.m_pParams = nullptr;
29                 }
30
31                 Task& operator=(Task&& other)
32                 {
33                         m_pParams = other.m_pParams;
34                         other.m_pParams = nullptr;
35                         return *this;
36                 }
37
38                 ~Task()
39                 {
40                         EnterCriticalSection(&g_cs);
41                         if (m_pParams)
42                         {
43                                 if (m_pParams->m_completed)
44                                 {
45                                         CloseHandle(m_pParams->m_hThread);
46                                         delete m_pParams;
47                                 }
48                                 else
49                                 {
50                                         m_pParams->m_detached = true;
51                                 }
52                         }
53                         LeaveCriticalSection(&g_cs);
54                 }
55
56         private:
57                 static unsigned __stdcall ThreadProc(void *pParam)
58                 {
59                         TaskParams *pParams = reinterpret_cast<TaskParams *>(pParam);
60                         pParams->m_result = pParams->m_func();
61                         EnterCriticalSection(&g_cs);
62                         if (pParams->m_detached)
63                         {
64                                 CloseHandle(pParams->m_hThread);
65                                 delete pParams;
66                         }
67                         else
68                         {
69                                 pParams->m_completed = true;
70                         }
71                         LeaveCriticalSection(&g_cs);
72                         return 0;
73                 }
74
75         public:
76                 template <typename FuncType>
77                 static auto Create(FuncType func)
78                 {
79                         unsigned threadId;
80                         TaskParams *pParams = new TaskParams();
81                         pParams->m_detached = false;
82                         pParams->m_completed = false;
83                         pParams->m_func = func;
84                         pParams->m_hThread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, ThreadProc, pParams, 0, &threadId));
85                         return Task<decltype(func())>(pParams);
86                 }
87
88                 ResultType Get()
89                 {
90                         WaitForSingleObject(m_pParams->m_hThread, INFINITE);
91                         return m_pParams->m_result;
92                 }
93
94         private:
95                 TaskParams *m_pParams;
96         };
97
98         template <typename FuncType>
99         auto CreateTask(FuncType func)
100         {
101                 return Task<decltype(func())>::Create(func);
102         }
103
104         extern CRITICAL_SECTION g_cs;
105         extern bool g_initialized;
106 }