protect the xrdb from multiple accesses from needupdate tests and write thread

This commit is contained in:
Jean-Francois Dockes 2013-01-01 16:20:06 +01:00
parent b8b4f4cb6d
commit 1a469d893f
3 changed files with 20 additions and 16 deletions

View file

@ -163,9 +163,10 @@ if test X$withFam != Xno ; then
fi fi
fi fi
# Enable use of file extended attributes. # Enable use of file extended attributes. Not by default as extended
# Not by default as extended attributes are little used for now, and # attributes are little used for now, and looking for them is not
# looking for them is not completely trivial # completely trivial: we have to use ctime instead of mtime to detect
# changes.
AC_ARG_ENABLE(xattr, AC_ARG_ENABLE(xattr,
AC_HELP_STRING([--enable-xattr], AC_HELP_STRING([--enable-xattr],
[Enable fetching metadata from file extended attributes. This is only [Enable fetching metadata from file extended attributes. This is only

View file

@ -500,11 +500,10 @@ bool Db::i_close(bool final)
if (!m_ndb->m_noversionwrite) if (!m_ndb->m_noversionwrite)
m_ndb->xwdb.set_metadata(cstr_RCL_IDX_VERSION_KEY, cstr_RCL_IDX_VERSION); m_ndb->xwdb.set_metadata(cstr_RCL_IDX_VERSION_KEY, cstr_RCL_IDX_VERSION);
LOGDEB(("Rcl::Db:close: xapian will close. May take some time\n")); LOGDEB(("Rcl::Db:close: xapian will close. May take some time\n"));
}
#ifdef IDX_THREADS #ifdef IDX_THREADS
waitUpdIdle(); waitUpdIdle();
#endif #endif
// Used to do a flush here. Cant see why it should be necessary. }
deleteZ(m_ndb); deleteZ(m_ndb);
if (w) if (w)
LOGDEB(("Rcl::Db:close() xapian close done.\n")); LOGDEB(("Rcl::Db:close() xapian close done.\n"));
@ -1490,9 +1489,8 @@ bool Db::purge()
bool Db::docExists(const string& uniterm) bool Db::docExists(const string& uniterm)
{ {
#ifdef IDX_THREADS #ifdef IDX_THREADS
// If we're not running our own (single) thread, need to protect // Need to protect read db against multiaccess.
// read db against multiaccess (e.g. from needUpdate(), or this method). PTMutexLocker lock(m_ndb->m_mutex);
PTMutexLocker lock(m_ndb->m_mutex, m_ndb->m_havewriteq);
#endif #endif
string ermsg; string ermsg;
@ -1543,10 +1541,11 @@ bool Db::purgeFile(const string &udi, bool *existed)
bool Db::purgeFileWrite(const string& udi, const string& uniterm) bool Db::purgeFileWrite(const string& udi, const string& uniterm)
{ {
#if defined(IDX_THREADS) #if defined(IDX_THREADS)
// If we have a write queue we're called from there, and single // We need a mutex even if we have a write queue (so we can only
// threaded, no locking. Else need to mutex other threads from // be called by a single thread) to protect about multiple acces
// above // to xrdb from subDocs() which is also called from needupdate()
PTMutexLocker lock(m_ndb->m_mutex, m_ndb->m_havewriteq); // (called from outside the write thread !
PTMutexLocker lock(m_ndb->m_mutex);
#endif // IDX_THREADS #endif // IDX_THREADS
Xapian::WritableDatabase db = m_ndb->xwdb; Xapian::WritableDatabase db = m_ndb->xwdb;

View file

@ -368,7 +368,6 @@ class Db {
/* This has to be public for access by embedded Query::Native */ /* This has to be public for access by embedded Query::Native */
Native *m_ndb; Native *m_ndb;
bool purgeFileWrite(const string& udi, const string& uniterm);
private: private:
const RclConfig *m_config; const RclConfig *m_config;
string m_reason; // Error explanation string m_reason; // Error explanation
@ -379,8 +378,6 @@ private:
// File existence vector: this is filled during the indexing pass. Any // File existence vector: this is filled during the indexing pass. Any
// document whose bit is not set at the end is purged // document whose bit is not set at the end is purged
vector<bool> updated; vector<bool> updated;
// Stop terms: those don't get indexed.
StopList m_stops;
// Text bytes indexed since beginning // Text bytes indexed since beginning
long long m_curtxtsz; long long m_curtxtsz;
// Text bytes at last flush // Text bytes at last flush
@ -393,6 +390,8 @@ private:
/*************** /***************
* Parameters cached out of the configuration files. Logically const * Parameters cached out of the configuration files. Logically const
* after init */ * after init */
// Stop terms: those don't get indexed.
StopList m_stops;
// This is how long an abstract we keep or build from beginning of // This is how long an abstract we keep or build from beginning of
// text when indexing. It only has an influence on the size of the // text when indexing. It only has an influence on the size of the
// db as we are free to shorten it again when displaying // db as we are free to shorten it again when displaying
@ -416,6 +415,11 @@ private:
static bool o_inPlaceReset; static bool o_inPlaceReset;
/******* End logical constnesss */ /******* End logical constnesss */
#ifdef IDX_THREADS
friend void *DbUpdWorker(void*);
#endif // IDX_THREADS
bool purgeFileWrite(const string& udi, const string& uniterm);
// Internal form of close, can be called during destruction // Internal form of close, can be called during destruction
bool i_close(bool final); bool i_close(bool final);
// Reinitialize when adding/removing additional dbs // Reinitialize when adding/removing additional dbs