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:
@@ -33,6 +33,8 @@
|
|||||||
recurring tasks. This column can be added to any custom report.
|
recurring tasks. This column can be added to any custom report.
|
||||||
+ Added support for "color.recurring" configuration variable which
|
+ Added support for "color.recurring" configuration variable which
|
||||||
specifies the color of recurring tasks.
|
specifies the color of recurring tasks.
|
||||||
|
+ Added support for "locking" configuration variable that controls whether
|
||||||
|
file locking is used.
|
||||||
|
|
||||||
------ old releases ------------------------------
|
------ old releases ------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -325,6 +325,21 @@ ID Project Pri Description
|
|||||||
whenever the shadow file is updated by some task command.
|
whenever the shadow file is updated by some task command.
|
||||||
</dd>
|
</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>
|
<p>
|
||||||
Note that the command:
|
Note that the command:
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -127,6 +127,8 @@
|
|||||||
recurring tasks. This column can be added to any custom report.
|
recurring tasks. This column can be added to any custom report.
|
||||||
<li>Added support for "color.recurring" configuration variable which
|
<li>Added support for "color.recurring" configuration variable which
|
||||||
specifies the color of recurring tasks.
|
specifies the color of recurring tasks.
|
||||||
|
<li>Added support for "locking" configuration variable that controls whether
|
||||||
|
file locking is used.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ void Config::createDefault (const std::string& home)
|
|||||||
fprintf (out, "color=on\n");
|
fprintf (out, "color=on\n");
|
||||||
fprintf (out, "due=7\n");
|
fprintf (out, "due=7\n");
|
||||||
fprintf (out, "nag=You have higher priority tasks.\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.overdue=bold_red\n");
|
||||||
fprintf (out, "color.due=bold_yellow\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]);
|
std::string value = lowerCase ((*this)[key]);
|
||||||
|
|
||||||
if (value == "t" ||
|
if (value == "t" ||
|
||||||
value == "true" ||
|
value == "true" ||
|
||||||
value == "1" ||
|
value == "1" ||
|
||||||
value == "yes" ||
|
value == "yes" ||
|
||||||
value == "on")
|
value == "on" ||
|
||||||
|
value == "enable" ||
|
||||||
|
value == "enabled")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
30
src/TDB.cpp
30
src/TDB.cpp
@@ -38,6 +38,7 @@ TDB::TDB ()
|
|||||||
: mPendingFile ("")
|
: mPendingFile ("")
|
||||||
, mCompletedFile ("")
|
, mCompletedFile ("")
|
||||||
, mId (1)
|
, mId (1)
|
||||||
|
, mNoLock (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +290,9 @@ bool TDB::modifyT (const T& t)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool TDB::lock (FILE* file) const
|
bool TDB::lock (FILE* file) const
|
||||||
{
|
{
|
||||||
|
if (mNoLock)
|
||||||
|
return true;
|
||||||
|
|
||||||
return flock (fileno (file), LOCK_EX) ? false : 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")))
|
if ((out = fopen (mPendingFile.c_str (), "w")))
|
||||||
{
|
{
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
if (!mNoLock)
|
||||||
delay (0.25);
|
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||||
|
delay (0.1);
|
||||||
|
|
||||||
std::vector <T>::iterator it;
|
std::vector <T>::iterator it;
|
||||||
for (it = all.begin (); it != all.end (); ++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")))
|
if ((out = fopen (mPendingFile.c_str (), "a")))
|
||||||
{
|
{
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
if (!mNoLock)
|
||||||
delay (0.25);
|
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||||
|
delay (0.1);
|
||||||
|
|
||||||
fputs (t.compose ().c_str (), out);
|
fputs (t.compose ().c_str (), out);
|
||||||
|
|
||||||
@@ -342,8 +348,9 @@ bool TDB::writeCompleted (const T& t)
|
|||||||
if ((out = fopen (mCompletedFile.c_str (), "a")))
|
if ((out = fopen (mCompletedFile.c_str (), "a")))
|
||||||
{
|
{
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
if (!mNoLock)
|
||||||
delay (0.25);
|
while (flock (fileno (out), LOCK_EX) && ++retry <= 3)
|
||||||
|
delay (0.1);
|
||||||
|
|
||||||
fputs (t.compose ().c_str (), out);
|
fputs (t.compose ().c_str (), out);
|
||||||
|
|
||||||
@@ -367,8 +374,9 @@ bool TDB::readLockedFile (
|
|||||||
if ((in = fopen (file.c_str (), "r")))
|
if ((in = fopen (file.c_str (), "r")))
|
||||||
{
|
{
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
while (flock (fileno (in), LOCK_EX) && ++retry <= 3)
|
if (!mNoLock)
|
||||||
delay (0.25);
|
while (flock (fileno (in), LOCK_EX) && ++retry <= 3)
|
||||||
|
delay (0.1);
|
||||||
|
|
||||||
char line[T_LINE_MAX];
|
char line[T_LINE_MAX];
|
||||||
while (fgets (line, T_LINE_MAX, in))
|
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 gc ();
|
||||||
int nextId ();
|
int nextId ();
|
||||||
|
|
||||||
|
void noLock ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool lock (FILE*) const;
|
bool lock (FILE*) const;
|
||||||
bool overwritePending (std::vector <T>&);
|
bool overwritePending (std::vector <T>&);
|
||||||
@@ -62,6 +64,7 @@ private:
|
|||||||
std::string mPendingFile;
|
std::string mPendingFile;
|
||||||
std::string mCompletedFile;
|
std::string mCompletedFile;
|
||||||
int mId;
|
int mId;
|
||||||
|
bool mNoLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -367,8 +367,8 @@ std::string handleVersion (Config& conf)
|
|||||||
"blanklines color color.active color.due color.overdue color.pri.H "
|
"blanklines color color.active color.due color.overdue color.pri.H "
|
||||||
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
||||||
"confirmation curses data.location dateformat default.command "
|
"confirmation curses data.location dateformat default.command "
|
||||||
"default.priority defaultwidth due monthsperline nag newest next oldest "
|
"default.priority defaultwidth due locking monthsperline nag newest next "
|
||||||
"project shadow.command shadow.file shadow.notify";
|
"oldest project shadow.command shadow.file shadow.notify";
|
||||||
|
|
||||||
// This configuration variable is supported, but not documented. It exists
|
// 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
|
// 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"));
|
std::string dataLocation = expandPath (conf.get ("data.location"));
|
||||||
tdb.dataDirectory (dataLocation);
|
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.
|
// Check for silly shadow file settings.
|
||||||
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
||||||
if (shadowFile != "")
|
if (shadowFile != "")
|
||||||
|
|||||||
Reference in New Issue
Block a user