mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Bug Workaround - locking
- Added support for the "locking" configuration variable that disables file locking. This can be helpful to folks who use task on Solaris, and store their task data files on an NFS mount.
This commit is contained in:
parent
dc946e175e
commit
d174bb1143
8 changed files with 58 additions and 15 deletions
|
@ -33,6 +33,8 @@
|
|||
recurring tasks. This column can be added to any custom report.
|
||||
+ Added support for "color.recurring" configuration variable which
|
||||
specifies the color of recurring tasks.
|
||||
+ Added support for "locking" configuration variable that controls whether
|
||||
file locking is used.
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
|
|
|
@ -325,6 +325,21 @@ ID Project Pri Description
|
|||
whenever the shadow file is updated by some task command.
|
||||
</dd>
|
||||
|
||||
<dt>locking</dt>
|
||||
<dd>
|
||||
<p>
|
||||
Determines whether task uses file locking when accessing the pending.data
|
||||
and completed.data files. Default to "on". Solaris users who store
|
||||
the task data files on an NFS mount may need to set locking to "off".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that setting this value to "off" is dangerous. It means that
|
||||
another program may write to the task.pending file when task is
|
||||
attempting to do the same.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<p>
|
||||
Note that the command:
|
||||
</p>
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
recurring tasks. This column can be added to any custom report.
|
||||
<li>Added support for "color.recurring" configuration variable which
|
||||
specifies the color of recurring tasks.
|
||||
<li>Added support for "locking" configuration variable that controls whether
|
||||
file locking is used.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -132,6 +132,7 @@ void Config::createDefault (const std::string& home)
|
|||
fprintf (out, "color=on\n");
|
||||
fprintf (out, "due=7\n");
|
||||
fprintf (out, "nag=You have higher priority tasks.\n");
|
||||
fprintf (out, "locking=on\n");
|
||||
|
||||
fprintf (out, "color.overdue=bold_red\n");
|
||||
fprintf (out, "color.due=bold_yellow\n");
|
||||
|
@ -222,11 +223,13 @@ bool Config::get (const std::string& key, bool default_value)
|
|||
{
|
||||
std::string value = lowerCase ((*this)[key]);
|
||||
|
||||
if (value == "t" ||
|
||||
value == "true" ||
|
||||
value == "1" ||
|
||||
value == "yes" ||
|
||||
value == "on")
|
||||
if (value == "t" ||
|
||||
value == "true" ||
|
||||
value == "1" ||
|
||||
value == "yes" ||
|
||||
value == "on" ||
|
||||
value == "enable" ||
|
||||
value == "enabled")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
30
src/TDB.cpp
30
src/TDB.cpp
|
@ -38,6 +38,7 @@ TDB::TDB ()
|
|||
: mPendingFile ("")
|
||||
, mCompletedFile ("")
|
||||
, mId (1)
|
||||
, mNoLock (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -289,6 +290,9 @@ bool TDB::modifyT (const T& t)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::lock (FILE* file) const
|
||||
{
|
||||
if (mNoLock)
|
||||
return true;
|
||||
|
||||
return flock (fileno (file), LOCK_EX) ? false : true;
|
||||
}
|
||||
|
||||
|
@ -300,8 +304,9 @@ bool TDB::overwritePending (std::vector <T>& all)
|
|||
if ((out = fopen (mPendingFile.c_str (), "w")))
|
||||
{
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
if (!mNoLock)
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.1);
|
||||
|
||||
std::vector <T>::iterator it;
|
||||
for (it = all.begin (); it != all.end (); ++it)
|
||||
|
@ -322,8 +327,9 @@ bool TDB::writePending (const T& t)
|
|||
if ((out = fopen (mPendingFile.c_str (), "a")))
|
||||
{
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
if (!mNoLock)
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.1);
|
||||
|
||||
fputs (t.compose ().c_str (), out);
|
||||
|
||||
|
@ -342,8 +348,9 @@ bool TDB::writeCompleted (const T& t)
|
|||
if ((out = fopen (mCompletedFile.c_str (), "a")))
|
||||
{
|
||||
int retry = 0;
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
if (!mNoLock)
|
||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.1);
|
||||
|
||||
fputs (t.compose ().c_str (), out);
|
||||
|
||||
|
@ -367,8 +374,9 @@ bool TDB::readLockedFile (
|
|||
if ((in = fopen (file.c_str (), "r")))
|
||||
{
|
||||
int retry = 0;
|
||||
while (flock (fileno (in), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.25);
|
||||
if (!mNoLock)
|
||||
while (flock (fileno (in), LOCK_EX) && ++retry <= 3)
|
||||
delay (0.1);
|
||||
|
||||
char line[T_LINE_MAX];
|
||||
while (fgets (line, T_LINE_MAX, in))
|
||||
|
@ -432,4 +440,10 @@ int TDB::nextId ()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void TDB::noLock ()
|
||||
{
|
||||
mNoLock = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
int gc ();
|
||||
int nextId ();
|
||||
|
||||
void noLock ();
|
||||
|
||||
private:
|
||||
bool lock (FILE*) const;
|
||||
bool overwritePending (std::vector <T>&);
|
||||
|
@ -62,6 +64,7 @@ private:
|
|||
std::string mPendingFile;
|
||||
std::string mCompletedFile;
|
||||
int mId;
|
||||
bool mNoLock;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -367,8 +367,8 @@ std::string handleVersion (Config& conf)
|
|||
"blanklines color color.active color.due color.overdue color.pri.H "
|
||||
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
||||
"confirmation curses data.location dateformat default.command "
|
||||
"default.priority defaultwidth due monthsperline nag newest next oldest "
|
||||
"project shadow.command shadow.file shadow.notify";
|
||||
"default.priority defaultwidth due locking monthsperline nag newest next "
|
||||
"oldest project shadow.command shadow.file shadow.notify";
|
||||
|
||||
// This configuration variable is supported, but not documented. It exists
|
||||
// so that unit tests can force color to be on even when the output from task
|
||||
|
|
|
@ -299,6 +299,10 @@ int main (int argc, char** argv)
|
|||
std::string dataLocation = expandPath (conf.get ("data.location"));
|
||||
tdb.dataDirectory (dataLocation);
|
||||
|
||||
// Allow user override of file locking. Solaris/NFS machines may want this.
|
||||
if (! conf.get ("locking", true))
|
||||
tdb.noLock ();
|
||||
|
||||
// Check for silly shadow file settings.
|
||||
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
||||
if (shadowFile != "")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue