Revision: 397 http://trac.macosforge.org/projects/darwinbuild/changeset/397 Author: kvv@apple.com Date: 2008-10-24 00:35:48 -0700 (Fri, 24 Oct 2008) Log Message: ----------- use flock(2) to serialize Depot access Modified Paths: -------------- trunk/darwinup/Depot.cpp trunk/darwinup/Depot.h Modified: trunk/darwinup/Depot.cpp =================================================================== --- trunk/darwinup/Depot.cpp 2008-10-24 05:42:44 UTC (rev 396) +++ trunk/darwinup/Depot.cpp 2008-10-24 07:35:48 UTC (rev 397) @@ -45,6 +45,7 @@ m_database_path = NULL; m_archives_path = NULL; m_db = NULL; + m_lock_fd = -1; } Depot::Depot(const char* prefix) { @@ -55,6 +56,8 @@ mkdir(m_depot_path, m_depot_mode); mkdir(m_archives_path, m_depot_mode); + (void)this->lock(LOCK_SH); + int exists = is_regular_file(m_database_path); int res = sqlite3_open(m_database_path, &m_db); @@ -73,6 +76,7 @@ } Depot::~Depot() { + if (m_lock_fd != -1) this->unlock(); if (m_db) sqlite3_close(m_db); if (m_depot_path) free(m_depot_path); if (m_database_path) free(m_database_path); @@ -454,6 +458,8 @@ // res = this->check_consistency(); // if (res != 0) return res; + res = this->lock(LOCK_EX); + if (res != 0) return res; // // The fun starts here @@ -530,6 +536,8 @@ if (rollback_path) free(rollback_path); if (archive_path) free(archive_path); + (void)this->lock(LOCK_SH); + return res; } @@ -652,6 +660,9 @@ // res = this->check_consistency(); // if (res != 0) return res; + res = this->lock(LOCK_EX); + if (res != 0) return res; + // XXX: this may be superfluous // uninstall_file should be smart enough to do a mtime check... if (res == 0) res = this->prune_directories(); @@ -682,6 +693,8 @@ if (res == 0) res = prune_archives(); + (void)this->lock(LOCK_SH); + return res; } @@ -920,6 +933,33 @@ return this->SQL("COMMIT TRANSACTION"); } +int Depot::lock(int operation) { + int res = 0; + if (m_lock_fd == -1) { + m_lock_fd = open(m_depot_path, O_RDONLY); + if (m_lock_fd == -1) { + perror(m_depot_path); + res = -1; + } + } + res = flock(m_lock_fd, operation); + if (res == -1) { + perror(m_depot_path); + } + return res; +} + +int Depot::unlock(void) { + int res = 0; + res = flock(m_lock_fd, LOCK_UN); + if (res == -1) { + perror(m_depot_path); + } + close(m_lock_fd); + m_lock_fd = -1; + return res; +} + int Depot::insert(Archive* archive) { // Don't insert an archive that is already in the database assert(archive->serial() == 0); Modified: trunk/darwinup/Depot.h =================================================================== --- trunk/darwinup/Depot.h 2008-10-24 05:42:44 UTC (rev 396) +++ trunk/darwinup/Depot.h 2008-10-24 07:35:48 UTC (rev 397) @@ -72,6 +72,10 @@ protected: + // Serialize access to the Depot via flock(2). + int lock(int operation); + int unlock(void); + // Inserts an Archive into the database. // This modifies the Archive's serial number. // If the Archive already has a serial number, it cannot be inserted. @@ -109,4 +113,5 @@ char* m_depot_path; char* m_database_path; char* m_archives_path; + int m_lock_fd; };
participants (1)
-
source_changes@macosforge.org