OSDN Git Service

Improve log speed.
[tortoisegit/TortoiseGitJp.git] / src / TGitCache / FolderCrawler.h
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // External Cache Copyright (C) 2005 - 2006 - Will Dean, Stefan Kueng\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #pragma once\r
20 \r
21 #include "TGitPath.h"\r
22 #include "CacheInterface.h"\r
23 #include <set>\r
24 //////////////////////////////////////////////////////////////////////////\r
25 \r
26 \r
27 \r
28 #pragma pack(push, r1, 16)\r
29 \r
30 /**\r
31  * \ingroup TSVNCache\r
32  * Helper class to crawl folders in the background (in a separate thread)\r
33  * so that the main cache isn't blocked until all the status are fetched.\r
34  */\r
35 class CFolderCrawler\r
36 {\r
37 public:\r
38         CFolderCrawler(void);\r
39         ~CFolderCrawler(void);\r
40 \r
41 public:\r
42         void Initialise();\r
43         void AddDirectoryForUpdate(const CTGitPath& path);\r
44         void AddPathForUpdate(const CTGitPath& path);\r
45         void Stop();\r
46         bool SetHoldoff(DWORD milliseconds = 100);\r
47         void BlockPath(const CTGitPath& path, DWORD ticks = 0);\r
48 private:\r
49         static unsigned int __stdcall ThreadEntry(void* pContext);\r
50         void WorkerThread();\r
51 \r
52 private:\r
53         CComAutoCriticalSection m_critSec;\r
54         HANDLE m_hThread;\r
55         std::deque<CTGitPath> m_foldersToUpdate;\r
56         std::deque<CTGitPath> m_pathsToUpdate;\r
57         HANDLE m_hTerminationEvent;\r
58         HANDLE m_hWakeEvent;\r
59         \r
60         // This will be *asynchronously* modified by CCrawlInhibitor.\r
61         // So, we have to mark it volatile, preparing compiler and\r
62         // optimizer for the "worst".\r
63         volatile LONG m_lCrawlInhibitSet;\r
64         \r
65         // While the shell is still asking for items, we don't\r
66         // want to start crawling.  This timer is pushed-out for \r
67         // every shell request, and stops us crawling until\r
68         // a bit of quiet time has elapsed\r
69         long m_crawlHoldoffReleasesAt;\r
70         bool m_bItemsAddedSinceLastCrawl;\r
71         bool m_bPathsAddedSinceLastCrawl;\r
72         \r
73         CTGitPath m_blockedPath;\r
74         DWORD m_blockReleasesAt;\r
75         bool m_bRun;\r
76 \r
77 \r
78         friend class CCrawlInhibitor;\r
79 };\r
80 \r
81 \r
82 //////////////////////////////////////////////////////////////////////////\r
83 \r
84 \r
85 class CCrawlInhibitor\r
86 {\r
87 private:\r
88         CCrawlInhibitor(); // Not defined\r
89 public:\r
90         explicit CCrawlInhibitor(CFolderCrawler* pCrawler)\r
91         {\r
92                 m_pCrawler = pCrawler;\r
93                 \r
94                 // Count locks instead of a mere flag toggle (exchange)\r
95                 // to allow for multiple, concurrent locks.\r
96                 ::InterlockedIncrement(&m_pCrawler->m_lCrawlInhibitSet);\r
97         }\r
98         ~CCrawlInhibitor()\r
99         {\r
100                 ::InterlockedDecrement(&m_pCrawler->m_lCrawlInhibitSet);\r
101                 m_pCrawler->SetHoldoff();\r
102         }\r
103 private:\r
104         CFolderCrawler* m_pCrawler;\r
105 };\r
106 \r
107 #pragma pack(pop, r1)\r