]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/fswatcher_inotify.cpp
Rethrow abi::__forced_unwind in wxThread code under Unix.
[wxWidgets.git] / src / unix / fswatcher_inotify.cpp
index 6c27e5c0f2336975528a905e5fc6f9e32ebad1ae..675d1168e352aa797859ab5af590f706b69fdbd2 100644 (file)
@@ -139,6 +139,9 @@ public:
             wxFAIL_MSG( wxString::Format("Path %s is not watched",
                                           watch->GetPath()) );
         }
+        // Cache the wd in case any events arrive late
+        m_staleDescriptors.Add(watch->GetWatchDescriptor());
+
         watch->SetWatchDescriptor(-1);
         return true;
     }
@@ -217,13 +220,33 @@ protected:
         // will be already removed from our list at that time
         if (inevt.mask & IN_IGNORED)
         {
+            // It is now safe to remove it from the stale descriptors too, we
+            // won't get any more events for it.
+            m_staleDescriptors.Remove(inevt.wd);
+            wxLogTrace(wxTRACE_FSWATCHER,
+                       "Removed wd %i from the stale-wd cache", inevt.wd);
             return;
         }
 
         // get watch entry for this event
         wxFSWatchEntryDescriptors::iterator it = m_watchMap.find(inevt.wd);
-        wxCHECK_RET(it != m_watchMap.end(),
-                             "Watch descriptor not present in the watch map!");
+        if (it == m_watchMap.end())
+        {
+            // It's not in the map; check if was recently removed from it.
+            if (m_staleDescriptors.Index(inevt.wd) != wxNOT_FOUND)
+            {
+                wxLogTrace(wxTRACE_FSWATCHER,
+                           "Got an event for stale wd %i", inevt.wd);
+            }
+            else
+            {
+                wxFAIL_MSG("Event for unknown watch descriptor.");
+            }
+
+            // In any case, don't process this event: it's either for an
+            // already removed entry, or for a completely unknown one.
+            return;
+        }
 
         wxFSWatchEntry& watch = *(it->second);
         int nativeFlags = inevt.mask;
@@ -344,9 +367,12 @@ protected:
         wxString mask = (inevt.mask & IN_ISDIR) ?
                         wxString::Format("IS_DIR | %u", inevt.mask & ~IN_ISDIR) :
                         wxString::Format("%u", inevt.mask);
+        const char* name = "";
+        if (inevt.len)
+            name = inevt.name;
         return wxString::Format("Event: wd=%d, mask=%s, cookie=%u, len=%u, "
                                 "name=%s", inevt.wd, mask, inevt.cookie,
-                                inevt.len, inevt.name);
+                                inevt.len, name);
     }
 
     static wxFileName GetEventPath(const wxFSWatchEntry& watch,
@@ -354,7 +380,7 @@ protected:
     {
         // only when dir is watched, we have non-empty e.name
         wxFileName path = watch.GetPath();
-        if (path.IsDir())
+        if (path.IsDir() && inevt.len)
         {
             path = wxFileName(path.GetPath(), inevt.name);
         }
@@ -422,6 +448,7 @@ protected:
 
     wxFSWSourceHandler* m_handler;        // handler for inotify event source
     wxFSWatchEntryDescriptors m_watchMap; // inotify wd=>wxFSWatchEntry* map
+    wxArrayInt m_staleDescriptors;        // stores recently-removed watches
     wxInotifyCookies m_cookies;           // map to track renames
     wxEventLoopSource* m_source;          // our event loop source