OSDN Git Service

Fix open second file log list error
[tortoisegit/TortoiseGitJp.git] / src / Utils / PathWatcher.h
1 // TortoiseGit - a Windows shell extension for easy version control\r
2 \r
3 // External Cache Copyright (C) 2007-2008 - TortoiseSVN\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 #include "TGitPath.h"\r
21 \r
22 #define READ_DIR_CHANGE_BUFFER_SIZE 4096\r
23 \r
24 typedef CComCritSecLock<CComCriticalSection> AutoLocker;\r
25 \r
26 /**\r
27  * \ingroup Utils\r
28  * Watches the file system for changes.\r
29  *\r
30  * When a CPathWatcher object is created, a new thread is started which\r
31  * waits for file system change notifications.\r
32  * To add folders to the list of watched folders, call \c AddPath().\r
33  *\r
34  * The folders are watched recursively. To prevent having too many folders watched,\r
35  * children of already watched folders are automatically removed from watching.\r
36  */\r
37 class CPathWatcher\r
38 {\r
39 public:\r
40         CPathWatcher(void);\r
41         ~CPathWatcher(void);\r
42         \r
43         /**\r
44          * Adds a new path to be watched. The path \b must point to a directory.\r
45          * If the path is already watched because a parent of that path is already\r
46          * watched recursively, then the new path is just ignored and the method\r
47          * returns false.\r
48          */\r
49         bool AddPath(const CTGitPath& path);\r
50         /**\r
51          * Removes a path and all its children from the watched list.\r
52          */\r
53         bool RemovePathAndChildren(const CTGitPath& path);\r
54         \r
55         /**\r
56          * Returns the number of recursively watched paths.\r
57          */\r
58         int GetNumberOfWatchedPaths() {return watchedPaths.GetCount();}\r
59                 \r
60         /**\r
61          * Stops the watching thread.\r
62          */\r
63         void Stop();\r
64 \r
65         /**\r
66          * Returns the number of changed paths up to now.\r
67          */\r
68         int GetNumberOfChangedPaths() {return m_changedPaths.GetCount();}\r
69 \r
70         /**\r
71          * Returns the list of paths which maybe got changed, i.e., for which\r
72          * a change notification was received.\r
73          */\r
74         CTGitPathList GetChangedPaths() {return m_changedPaths;}\r
75 \r
76         /**\r
77          * Clears the list of changed paths\r
78          */\r
79         void ClearChangedPaths() {AutoLocker lock(m_critSec); m_changedPaths.Clear();}\r
80 \r
81 private:\r
82         static unsigned int __stdcall ThreadEntry(void* pContext);\r
83         void WorkerThread();\r
84 \r
85         void ClearInfoMap();\r
86 \r
87 private:\r
88         CComAutoCriticalSection m_critSec;\r
89         HANDLE                                  m_hThread;\r
90         HANDLE                                  m_hCompPort;\r
91         volatile LONG                   m_bRunning;\r
92         \r
93         CTGitPathList                   watchedPaths;   ///< list of watched paths.\r
94         CTGitPathList                   m_changedPaths; ///< list of paths which got changed\r
95 \r
96         /**\r
97          * Helper class: provides information about watched directories.\r
98          */\r
99         class CDirWatchInfo \r
100         {\r
101         private:\r
102                 CDirWatchInfo();        // private & not implemented\r
103                 CDirWatchInfo & operator=(const CDirWatchInfo & rhs);//so that they're aren't accidentally used. -- you'll get a linker error\r
104         public:\r
105                 CDirWatchInfo(HANDLE hDir, const CTGitPath& DirectoryName);\r
106                 ~CDirWatchInfo();\r
107 \r
108         protected:\r
109         public:\r
110                 bool            CloseDirectoryHandle();\r
111 \r
112                 HANDLE          m_hDir;                 ///< handle to the directory that we're watching\r
113                 CTGitPath       m_DirName;              ///< the directory that we're watching\r
114                 CHAR            m_Buffer[READ_DIR_CHANGE_BUFFER_SIZE]; ///< buffer for ReadDirectoryChangesW\r
115                 DWORD           m_dwBufLength;  ///< length or returned data from ReadDirectoryChangesW -- ignored?...\r
116                 OVERLAPPED  m_Overlapped;\r
117                 CString         m_DirPath;              ///< the directory name we're watching with a backslash at the end\r
118                 //HDEVNOTIFY    m_hDevNotify;   ///< Notification handle\r
119         };\r
120 \r
121         std::map<HANDLE, CDirWatchInfo *> watchInfoMap;\r
122         \r
123         HDEVNOTIFY              m_hdev;\r
124 \r
125 };\r