]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/msw/private/fswatcher.h
Don't create multiple parent-less top level frames in layout sample.
[wxWidgets.git] / include / wx / msw / private / fswatcher.h
index 664c8eccaa124eed203ed259515eedcc26d39509..3392141efddd0389bf5d1b1100b1853a21772df8 100644 (file)
@@ -50,7 +50,7 @@ public:
                                 m_path);
             }
         }
                                 m_path);
             }
         }
-        delete m_overlapped;
+        free(m_overlapped);
     }
 
     bool IsOk() const
     }
 
     bool IsOk() const
@@ -78,10 +78,13 @@ private:
     // asynchronous watched with ReadDirectoryChangesW
     static HANDLE OpenDir(const wxString& path)
     {
     // asynchronous watched with ReadDirectoryChangesW
     static HANDLE OpenDir(const wxString& path)
     {
-        HANDLE handle = CreateFile(path, FILE_LIST_DIRECTORY,
-                                   FILE_SHARE_READ | FILE_SHARE_WRITE |
+        HANDLE handle = CreateFile(path.t_str(),
+                                   FILE_LIST_DIRECTORY,
+                                   FILE_SHARE_READ |
+                                   FILE_SHARE_WRITE |
                                    FILE_SHARE_DELETE,
                                    FILE_SHARE_DELETE,
-                                   NULL, OPEN_EXISTING,
+                                   NULL,
+                                   OPEN_EXISTING,
                                    FILE_FLAG_BACKUP_SEMANTICS |
                                    FILE_FLAG_OVERLAPPED,
                                    NULL);
                                    FILE_FLAG_BACKUP_SEMANTICS |
                                    FILE_FLAG_OVERLAPPED,
                                    NULL);
@@ -101,7 +104,6 @@ private:
     wxDECLARE_NO_COPY_CLASS(wxFSWatchEntryMSW);
 };
 
     wxDECLARE_NO_COPY_CLASS(wxFSWatchEntryMSW);
 };
 
-
 // ============================================================================
 // wxFSWatcherImplMSW helper classes implementations
 // ============================================================================
 // ============================================================================
 // wxFSWatcherImplMSW helper classes implementations
 // ============================================================================
@@ -153,12 +155,54 @@ public:
         return m_watches.insert(val).second;
     }
 
         return m_watches.insert(val).second;
     }
 
+    // Removes a watch we're currently using. Notice that this doesn't happen
+    // immediately, CompleteRemoval() must be called later when it's really
+    // safe to delete the watch, i.e. after completion of the IO operation
+    // using it.
+    bool ScheduleForRemoval(const wxSharedPtr<wxFSWatchEntryMSW>& watch)
+    {
+        wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
+        wxCHECK_MSG( watch->IsOk(), false, "Invalid watch" );
+
+        const wxString path = watch->GetPath();
+        wxFSWatchEntries::iterator it = m_watches.find(path);
+        wxCHECK_MSG( it != m_watches.end(), false,
+                     "Can't remove a watch we don't use" );
+
+        // We can't just delete the watch here as we can have pending events
+        // for it and if we destroyed it now, we could get a dangling (or,
+        // worse, reused to point to another object) pointer in ReadEvents() so
+        // just remember that this one should be removed when CompleteRemoval()
+        // is called later.
+        m_removedWatches.insert(wxFSWatchEntries::value_type(path, watch));
+        m_watches.erase(it);
+
+        return true;
+    }
+
+    // Really remove the watch previously passed to ScheduleForRemoval().
+    //
+    // It's ok to call this for a watch that hadn't been removed before, in
+    // this case we'll just return false and do nothing.
+    bool CompleteRemoval(wxFSWatchEntryMSW* watch)
+    {
+        wxFSWatchEntries::iterator it = m_removedWatches.find(watch->GetPath());
+        if ( it == m_removedWatches.end() )
+            return false;
+
+        // Removing the object from the map will result in deleting the watch
+        // itself as it's not referenced from anywhere else now.
+        m_removedWatches.erase(it);
+
+        return true;
+    }
+
     // post completion packet
     bool PostEmptyStatus()
     {
         wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
 
     // post completion packet
     bool PostEmptyStatus()
     {
         wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
 
-        int ret = PostQueuedCompletionStatus(m_iocp, 0, NULL, NULL);
+        int ret = PostQueuedCompletionStatus(m_iocp, 0, 0, NULL);
         if (!ret)
         {
             wxLogSysError(_("Unable to post completion status"));
         if (!ret)
         {
             wxLogSysError(_("Unable to post completion status"));
@@ -179,7 +223,7 @@ public:
         wxCHECK_MSG( overlapped != NULL, false,
                      "Null out parameter 'overlapped'");
 
         wxCHECK_MSG( overlapped != NULL, false,
                      "Null out parameter 'overlapped'");
 
-        int ret = GetQueuedCompletionStatus(m_iocp, count, (PULONG_PTR)watch,
+        int ret = GetQueuedCompletionStatus(m_iocp, count, (ULONG_PTR *)watch,
                                             overlapped, INFINITE);
         if (!ret)
         {
                                             overlapped, INFINITE);
         if (!ret)
         {
@@ -200,7 +244,13 @@ protected:
     }
 
     HANDLE m_iocp;
     }
 
     HANDLE m_iocp;
+
+    // The hash containing all the wxFSWatchEntryMSW objects currently being
+    // watched keyed by their paths.
     wxFSWatchEntries m_watches;
     wxFSWatchEntries m_watches;
+
+    // Contains the watches which had been removed but are still pending.
+    wxFSWatchEntries m_removedWatches;
 };
 
 
 };