[Groonga-commit] groonga/groonga [master] fixed a bug that leads to deadlock.

Back to archive index

null+****@clear***** null+****@clear*****
2011年 11月 4日 (金) 10:55:51 JST


Susumu Yata	2011-11-04 01:55:51 +0000 (Fri, 04 Nov 2011)

  New Revision: 96addc231dc49a37f12d3c9b7da58ee125db38f3

  Log:
    fixed a bug that leads to deadlock.

  Modified files:
    lib/dat.cpp

  Modified: lib/dat.cpp (+34 -3)
===================================================================
--- lib/dat.cpp    2011-11-04 01:08:49 +0000 (9a707f5)
+++ lib/dat.cpp    2011-11-04 01:55:51 +0000 (c1cba7d)
@@ -26,6 +26,35 @@
 
 namespace {
 
+class CriticalSection {
+ public:
+  CriticalSection() : lock_(NULL) {}
+  explicit CriticalSection(grn_critical_section *lock) : lock_(lock) {
+    CRITICAL_SECTION_ENTER(*lock_);
+  }
+  ~CriticalSection() {
+    leave();
+  }
+
+  void enter(grn_critical_section *lock) {
+    leave();
+    lock_ = lock;
+  }
+  void leave() {
+    if (lock_ != NULL) {
+      CRITICAL_SECTION_LEAVE(*lock_);
+      lock_ = NULL;
+    }
+  }
+
+ private:
+  grn_critical_section *lock_;
+
+  // Disallows copy and assignment.
+  CriticalSection(const CriticalSection &);
+  CriticalSection &operator=(const CriticalSection &);
+};
+
 void
 grn_dat_init(grn_ctx *, grn_dat *dat)
 {
@@ -47,7 +76,7 @@ grn_dat_fin(grn_ctx *ctx, grn_dat *dat)
 #ifndef WIN32
   delete static_cast<grn::dat::Trie *>(dat->old_trie);
   delete static_cast<grn::dat::Trie *>(dat->trie);
-#endif  // WIN32
+#endif
   dat->old_trie = NULL;
   dat->trie = NULL;
   if (dat->io) {
@@ -84,7 +113,8 @@ grn_dat_open_trie_if_needed(grn_ctx *ctx, grn_dat *dat)
   if (dat->trie && (file_id <= dat->file_id)) {
     return true;
   }
-  CRITICAL_SECTION_ENTER(dat->lock);
+
+  CriticalSection critical_section(&dat->lock);
   if (dat->trie && (file_id <= dat->file_id)) {
     return true;
   }
@@ -110,7 +140,8 @@ grn_dat_open_trie_if_needed(grn_ctx *ctx, grn_dat *dat)
   dat->old_trie = trie;
   dat->trie = new_trie;
   dat->file_id = file_id;
-  CRITICAL_SECTION_LEAVE(dat->lock);
+  critical_section.leave();
+
   delete old_trie;
 #endif
   return true;




Groonga-commit メーリングリストの案内
Back to archive index