29 #include <nsComponentManagerUtils.h>
30 #include <nsServiceManagerUtils.h>
31 #include <nsIObserverService.h>
33 #include <nsThreadUtils.h>
34 #include <nsAutoLock.h>
38 #define BUFFER_LEN 1024 * 64
50 __in DWORD dwNumberOfBytesTransfered,
51 __in LPOVERLAPPED lpOverlapped)
57 LOG(
"%s: no watcher!", __FUNCTION__);
61 if (FAILED(HRESULT_FROM_WIN32(dwErrorCode))) {
66 if (dwNumberOfBytesTransfered == 0) {
71 FILE_NOTIFY_INFORMATION *fileInfo =
72 (FILE_NOTIFY_INFORMATION *)watcher->
GetBuffer();
75 TRACE(
"%s: found changes in %s", __FUNCTION__, fileInfo->FileName);
80 nsString curEventPath;
81 curEventPath.Assign(fileInfo->FileName,
82 (fileInfo->FileNameLength /
sizeof(WCHAR)));
86 if (fileInfo->NextEntryOffset == 0) {
90 (FILE_NOTIFY_INFORMATION *)((
char *)fileInfo + fileInfo->NextEntryOffset);
105 NS_WARNING(
"Could not get sbWin32FileSystemWatcher context in thread!");
133 mRootDirHandle(INVALID_HANDLE_VALUE),
134 mWatcherThread(INVALID_HANDLE_VALUE),
136 mShouldRunThread(PR_FALSE),
137 mIsThreadRunning(PR_FALSE),
138 mShuttingDown(PR_FALSE)
143 nsAutoLock::NewLock(
"sbWin32FileSystemWatcher::mEventPathsSetLock");
144 NS_ASSERTION(mEventPathsSetLock,
"Failed to create lock");
149 TRACE(
"%s", __FUNCTION__);
150 nsAutoLock::DestroyLock(mEventPathsSetLock);
154 if ((mWatcherThread != INVALID_HANDLE_VALUE) && mIsThreadRunning) {
155 TerminateThread(mWatcherThread, 0);
157 mWatcherThread = INVALID_HANDLE_VALUE;
162 const nsAString & aRootPath,
165 TRACE(
"%s: root path = %s", __FUNCTION__,
166 NS_ConvertUTF16toUTF8(aRootPath).
get());
168 nsCOMPtr<nsIObserverService> obsService =
169 do_GetService(
"@mozilla.org/observer-service;1", &rv);
170 NS_ENSURE_SUCCESS(rv, rv);
172 rv = obsService->AddObserver(
this,
"quit-application", PR_FALSE);
173 NS_ENSURE_SUCCESS(rv, rv);
181 TRACE(
"%s", __FUNCTION__);
183 mShuttingDown = PR_TRUE;
189 mShouldRunThread = PR_FALSE;
195 if (mRebuildThread) {
196 mRebuildThread->Shutdown();
199 return sbBaseFileSystemWatcher::StopWatching(aShouldSaveSession);
205 TRACE(
"%s", __FUNCTION__);
207 nsMemory::Free(mBuffer);
211 if (mRootDirHandle != INVALID_HANDLE_VALUE) {
212 CloseHandle(mRootDirHandle);
213 mRootDirHandle = INVALID_HANDLE_VALUE;
221 TRACE(
"%s", __FUNCTION__);
224 NS_ENSURE_TRUE(!mShuttingDown, );
226 mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
227 NS_ENSURE_SUCCESS(rv, );
229 rv = mTimer->InitWithCallback(
this, 100, nsITimer::TYPE_REPEATING_SLACK);
230 NS_ENSURE_SUCCESS(rv, );
236 TRACE(
"%s", __FUNCTION__);
238 FILE_NOTIFY_CHANGE_FILE_NAME |
239 FILE_NOTIFY_CHANGE_DIR_NAME |
240 FILE_NOTIFY_CHANGE_LAST_WRITE |
241 FILE_NOTIFY_CHANGE_CREATION;
243 if (mRootDirHandle != INVALID_HANDLE_VALUE) {
245 ReadDirectoryChangesW(mRootDirHandle,
254 NS_WARNING(
"ERROR: Could not ReadDirectoryChangesW()");
255 if (mRootDirHandle != INVALID_HANDLE_VALUE) {
256 CloseHandle(mRootDirHandle);
257 mRootDirHandle = INVALID_HANDLE_VALUE;
266 return mShouldRunThread;
272 return mIsThreadRunning;
278 mIsThreadRunning = aIsThreadRunning;
290 return &mEventPathsSet;
296 return mEventPathsSetLock;
306 TRACE(
"%s: root path %s",
307 __FUNCTION__, NS_ConvertUTF16toUTF8(aTreeRootPath).
get());
316 NS_ENSURE_STATE(!mRebuildThread);
319 nsCOMPtr<nsIRunnable> initRebuildEvent =
321 NS_ENSURE_TRUE(initRebuildEvent, NS_ERROR_OUT_OF_MEMORY);
323 rv = NS_NewThread(getter_AddRefs(mRebuildThread), initRebuildEvent);
324 NS_ENSURE_SUCCESS(rv, rv);
334 FILE_FLAG_BACKUP_SEMANTICS |
335 FILE_FLAG_OVERLAPPED,
338 NS_ENSURE_TRUE(mRootDirHandle != INVALID_HANDLE_VALUE, NS_ERROR_UNEXPECTED);
340 memset(&mOverlapped, 0,
sizeof(mOverlapped));
341 mOverlapped.hEvent = (HANDLE)
this;
348 if (!mIsThreadRunning) {
349 mShouldRunThread = PR_TRUE;
351 NS_ENSURE_TRUE(mWatcherThread != INVALID_HANDLE_VALUE, NS_ERROR_OUT_OF_MEMORY);
357 NS_ENSURE_SUCCESS(rv, rv);
366 sbWin32FileSystemWatcher::Observe(
nsISupports *aObject,
368 const PRUnichar *
aData)
370 LOG(
"%s: observing %s", __FUNCTION__, aTopic);
371 if (strcmp(aTopic,
"quit-application") == 0) {
380 nsCOMPtr<nsIObserverService> obsService =
381 do_GetService(
"@mozilla.org/observer-service;1", &rv);
382 NS_ENSURE_SUCCESS(rv, rv);
384 obsService->RemoveObserver(
this,
"quit-application");
385 NS_ENSURE_SUCCESS(rv, rv);
395 sbWin32FileSystemWatcher::Notify(nsITimer *aTimer)
397 TRACE(
"%s", __FUNCTION__);
399 nsAutoLock lock(mEventPathsSetLock);
407 while (!mEventPathsSet.empty()) {
411 curEventPath.Append(*begin);
414 mEventPathsSet.erase(begin);
417 nsCOMPtr<nsILocalFile> curEventFile =
418 do_CreateInstance(
"@mozilla.org/file/local;1", &rv);
423 rv = curEventFile->InitWithPath(curEventPath);
431 nsString curEventFileLeafName;
432 rv = curEventFile->GetLeafName(curEventFileLeafName);
437 curEventPath.Cut(curEventPath.Length() - curEventFileLeafName.Length(),
438 curEventFileLeafName.Length());
439 folderEventPaths.insert(curEventPath);
443 while (!folderEventPaths.empty()) {
445 mTree->Update(*begin);
446 folderEventPaths.erase(begin);
NS_IMETHOD StopWatching(PRBool aShouldSaveSession)
nsCOMPtr< sbIFileSystemListener > mListener
NS_IMPL_ISUPPORTS_INHERITED2(sbWin32FileSystemWatcher, sbBaseFileSystemWatcher, nsIObserver, nsITimerCallback) sbWin32FileSystemWatcher
#define SB_PRLOG_SETUP(x)
PRBool GetShouldRunThread()
NS_IMETHOD OnTreeReady(const nsAString &aTreeRootPath, sbStringArray &aDirPathArray)
nsTArray< nsString > sbStringArray
PRLock * GetEventPathsSetLock()
sbDeviceFirmwareAutoCheckForUpdate prototype flags
friend DWORD WINAPI BackgroundThreadProc(void *p)
nsRefPtr< sbFileSystemTree > mTree
PRBool GetIsThreadRunning()
virtual ~sbWin32FileSystemWatcher()
sbStringSet * GetEventPathsSet()
sbStringSet::iterator sbStringSetIter
std::set< nsString > sbStringSet
NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIOBSERVER NS_DECL_NSITIMERCALLBACK NS_IMETHOD Init(sbIFileSystemListener *aListener, const nsAString &aRootPath, PRBool aIsRecursive)
DWORD WINAPI BackgroundThreadProc(void *p)
void SetIsThreadRunning(PRBool aIsThreadRunning)
VOID CALLBACK ReadDirectoryChangesWCallbackRoutine(__in DWORD dwErrorCode, __in DWORD dwNumberOfBytesTransfered, __in LPOVERLAPPED lpOverlapped)
_updateTextAndScrollDataForFrame aData