Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 2014-10-13 10:39, Brad King wrote: On 10/10/2014 07:45 AM, Ruslan Baratov wrote: Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: I think this can be activated buy a DIRECTORY option. Why do we need even that? Can't CMake just test if the lock target is a directory? p.s. For a lock with no timeout, maybe there can be a built-in timeout after which CMake displays a message what it's trying to do, so that it doesn't just hang mysteriously. -- Matthew -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 17-Dec-14 21:11, Matthew Woehlke wrote: On 2014-10-13 10:39, Brad King wrote: On 10/10/2014 07:45 AM, Ruslan Baratov wrote: Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: I think this can be activated buy a DIRECTORY option. Why do we need even that? Can't CMake just test if the lock target is a directory? I've used boost.interprocess as a hint for implementation, as far as I know boost::interprocess::file_lock is not able to lock directories: terminate called after throwing an instance of 'boost::interprocess::interprocess_exception' what(): Is a directory I'm not saying that it's not possible, just trying to use well-known cross-platform solution. p.s. For a lock with no timeout, maybe there can be a built-in timeout after which CMake displays a message what it's trying to do, so that it doesn't just hang mysteriously. You can use `message` command: message(STATUS Try to lock ${file}) file(LOCK ${file}) or more complex (more user-friendly): while(TRUE) file(LOCK ${file} RESULT is_locked TIMEOUT 5) if(is_locked) message(Locked. ${resource_info}) break() endif() string(TIMESTAMP time_now %S/%M) message([${time_now}] Lock failed, retry... (file: ${file})) endwhile() Ruslo -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 05-Dec-14 17:12, Brad King wrote: On 12/05/2014 09:10 AM, Ruslan Baratov wrote: file: Add LOCK subcommand to do file and directory locking http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e6db4c5a Great, thank you! So will this be applied to cmake 3.1.0? No, sorry. The feature deadline for that was almost 2 months ago. The release candidate period has been pretty drawn out this time :( -Brad Okay, just curious what version it will be? Ruslo -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/05/2014 09:38 AM, Ruslan Baratov wrote: Okay, just curious what version it will be? 3.2. There is a roadmap here: http://www.cmake.org/Bug/roadmap_page.php with tentative dates. -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 05-Dec-14 17:09, Brad King wrote: On 12/05/2014 09:03 AM, Ruslan Baratov wrote: Actually why not use 'strtoll' and 'long long' ? I'm not sure that function or type exists portably on some of the older host platforms we support. The long type should be plenty big for timeout values, and there are other strtol call sites that already use long and could be converted to use a StringToLong helper too. Sending patch with 'long'. Actually for the lock timeout use case would it make sense to change to a floating point value so timeouts can be more granular? Some use cases may not want to block for a whole second between lock attempts. What granularity you think is appropriate, 100 ms? 10 ms? (It will be value in `cmSystemTools::Delay(...);`) Ruslo From 3ed0ad891c6108fa2a03834f9fe109ee5d628847 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Fri, 5 Dec 2014 17:18:11 +0300 Subject: [PATCH] Use 'long' for StringToInt --- Source/cmFileCommand.cxx | 6 +++--- Source/cmFileLock.cxx | 4 ++-- Source/cmFileLock.h| 4 ++-- Source/cmFileLockPool.cxx | 8 Source/cmFileLockPool.h| 10 ++ Source/cmFileLockUnix.cxx | 2 +- Source/cmFileLockWin32.cxx | 2 +- Source/cmSystemTools.cxx | 7 --- Source/cmSystemTools.h | 4 ++-- 9 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index a6eb8c4..42cd132 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3521,7 +3521,7 @@ bool cmFileCommand::HandleLockCommand( }; Guard guard = GUARD_PROCESS; std::string resultVariable; - unsigned timeout = static_castunsigned(-1); + unsigned long timeout = static_castunsigned long(-1); // Parse arguments if(args.size() 2) @@ -3597,7 +3597,7 @@ bool cmFileCommand::HandleLockCommand( expected timeout value after TIMEOUT); return false; } - int scanned; + long scanned; if(!cmSystemTools::StringToInt(args[i].c_str(), scanned) || scanned 0) { cmOStringStream e; @@ -3605,7 +3605,7 @@ bool cmFileCommand::HandleLockCommand( this-Makefile-IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } - timeout = static_castunsigned(scanned); + timeout = static_castunsigned long(scanned); } else { diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx index 5f75637..e6aa5f4 100644 --- a/Source/cmFileLock.cxx +++ b/Source/cmFileLock.cxx @@ -28,7 +28,7 @@ cmFileLock::~cmFileLock() } cmFileLockResult cmFileLock::Lock( -const std::string filename, unsigned timeout) +const std::string filename, unsigned long timeout) { if (filename.empty()) { @@ -48,7 +48,7 @@ cmFileLockResult cmFileLock::Lock( cmFileLockResult result = this-OpenFile(); if (result.IsOk()) { -if (timeout == static_castunsigned(-1)) +if (timeout == static_castunsigned long(-1)) { result = this-LockWithoutTimeout(); } diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h index 4d922a0..dd959a7 100644 --- a/Source/cmFileLock.h +++ b/Source/cmFileLock.h @@ -37,7 +37,7 @@ class cmFileLock * @brief Lock the file. * @param timeoutSec Lock timeout. If -1 try until success or fatal error. */ - cmFileLockResult Lock(const std::string filename, unsigned timeoutSec); + cmFileLockResult Lock(const std::string filename, unsigned long timeoutSec); /** * @brief Unlock the file. @@ -57,7 +57,7 @@ class cmFileLock cmFileLockResult OpenFile(); cmFileLockResult LockWithoutTimeout(); - cmFileLockResult LockWithTimeout(unsigned timeoutSec); + cmFileLockResult LockWithTimeout(unsigned long timeoutSec); #if defined(_WIN32) typedef HANDLE FileId; diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx index e84e71a..551a75a 100644 --- a/Source/cmFileLockPool.cxx +++ b/Source/cmFileLockPool.cxx @@ -60,7 +60,7 @@ void cmFileLockPool::PopFileScope() } cmFileLockResult cmFileLockPool::LockFunctionScope( -const std::string filename, unsigned timeoutSec) +const std::string filename, unsigned long timeoutSec) { if (this-IsAlreadyLocked(filename)) { @@ -74,7 +74,7 @@ cmFileLockResult cmFileLockPool::LockFunctionScope( } cmFileLockResult cmFileLockPool::LockFileScope( -const std::string filename, unsigned timeoutSec) +const std::string filename, unsigned long timeoutSec) { if (this-IsAlreadyLocked(filename)) { @@ -85,7 +85,7 @@ cmFileLockResult cmFileLockPool::LockFileScope( } cmFileLockResult cmFileLockPool::LockProcessScope( -const std::string filename, unsigned timeoutSec) +const std::string filename, unsigned long timeoutSec) { if (this-IsAlreadyLocked(filename)) { @@ -155,7 +155,7 @@ cmFileLockPool::ScopePool::~ScopePool() } cmFileLockResult cmFileLockPool::ScopePool::Lock( -const std::string filename, unsigned
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/05/2014 09:51 AM, Ruslan Baratov wrote: Sending patch with 'long'. Applied while also renaming to StringToLong, thanks: file: Use 'long' to represent the parsed LOCK TIMEOUT value http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=97841dad What granularity you think is appropriate, 100 ms? 10 ms? (It will be value in `cmSystemTools::Delay(...);`) On second thought, it is easy to change this later if a case comes up that really needs it, so let's stay with 1s for now. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/01/2014 10:52 AM, Brad King wrote: cmSystemTools: Add StringToInt helper http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5121f118 file: Add LOCK subcommand to do file and directory locking http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fca624ca Help: Add notes for topic 'file-LOCK-command' http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed00a808 After some revisions: cmSystemTools: Add StringToInt helper http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=05d6531c file: Add LOCK subcommand to do file and directory locking http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e6db4c5a Help: Add notes for topic 'file-LOCK-command' http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=93017828 -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/01/2014 10:52 AM, Brad King wrote: Thanks. I squashed the commits since the addition of the files cannot be tested independently, made minor tweaks, and merged to 'next' for testing: Testing went pretty well, but the RunCMake.file test fails on HP-UX in the LOCK-error-timeout case: http://open.cdash.org/testDetails.php?test=297595272build=3594885 The relevant expect/actual lines are: expect-err Timeout reached\. actual-err Permission denied. Any idea why that might happen? Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/02/2014 10:03 AM, Brad King wrote: Testing went pretty well, but the RunCMake.file test fails on HP-UX in the LOCK-error-timeout case: http://open.cdash.org/testDetails.php?test=297595272build=3594885 The relevant expect/actual lines are: expect-err Timeout reached\. actual-err Permission denied. Any idea why that might happen? This may fix it: cmFileLockUnix: Treat EACCES like EAGAIN http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=35bcecc0 According to 'man fcntl' locking an already-locked file may fail with either EACCES or EAGAIN. We were only checking the latter. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/25/2014 06:24 PM, Ruslan Baratov wrote: updated Thanks. I squashed the commits since the addition of the files cannot be tested independently, made minor tweaks, and merged to 'next' for testing: cmSystemTools: Add StringToInt helper http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5121f118 file: Add LOCK subcommand to do file and directory locking http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fca624ca Help: Add notes for topic 'file-LOCK-command' http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed00a808 -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
Rolf Eike Beer wrote: Brad King wrote: On 12/01/2014 11:05 AM, Rolf Eike Beer wrote: + char *endp; + *value = static_castint(strtol(str, endp, 10)); + return (*endp == '\0') (endp != str); Fine with me. Please extend the topic accordingly. I will squash it in later. Done. Existing uses of strtol also check errno. I guess your implementation should too. Then the existing users should use this new method. Thanks, Steve. -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 12/01/2014 03:26 PM, Stephen Kelly wrote: Existing uses of strtol also check errno. I guess your implementation should too. Yes, IIUC it is a range check on whether the value can be represented. Then the existing users should use this new method. In that case the type should be changed to 'long' instead of 'int', and the current call site should be updated accordingly. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/17/2014 06:45 PM, Ruslan Baratov wrote: Done Thanks. Here are some more comments: * Please rebase on current 'master' to resolve conflicts. * The background.(bat|sh) files need to have quoting to work with spaces in the path. Please try running tests with a source/build tree with spaces. * The error messages currently use SetError(...); return false;. That is why you need the : to get the prompt. Instead you can use IssueMessage as shown in the hunk below for one example. Indented lines in the message will be printed as preformatted blocks so you do not have to worry about variations in the line wrapping of expected test output. * Please use shorter timeouts in the test if possible to make it run faster. If they become spurious/problematic then we can lengthen them later. * Instead of background scripts, can you have a parent process take a lock, run a child with a timed out lock, and then release the lock? Then the timeout can be just 0.1s in the child and there is no race. Thanks, -Brad diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 8e63892..fb64b5a 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3679,10 +3679,10 @@ bool cmFileCommand::HandleLockCommand( if (resultVariable.empty() !fileLockResult.IsOk()) { cmOStringStream e; -e : error locking file \ path \ ( result ).; -this-SetError(e.str()); +e error locking file\n path \n( result ).; +this-Makefile-IssueMessage(cmake::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); -return false; +return true; } if (!resultVariable.empty()) -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 25-Nov-14 21:29, Brad King wrote: * The background.(bat|sh) files need to have quoting to work with spaces in the path. Please try running tests with a source/build tree with spaces. * Instead of background scripts, can you have a parent process take a lock, run a child with a timed out lock, and then release the lock? Test updated, no need to use 'background.*' scripts indeed. * The error messages currently use SetError(...); return false;. That is why you need the : to get the prompt. Instead you can use IssueMessage as shown in the hunk below for one example. 's,SetError,IssueMessage,g' done I'm not quite sure about when do I need to use 'return false'/'return true', so I leave 'return false' everywhere. * Please use shorter timeouts in the test if possible to make it run faster. If they become spurious/problematic then we can lengthen them later. * ... Then the timeout can be just 0.1s in the child and there is no race. I've set timeout to 1 sec (minimal unsigned integer). Ruslo. From 6b874aa940a86f9a789cfae23a8c47d609587d61 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Wed, 26 Nov 2014 01:45:26 +0300 Subject: [PATCH 1/7] Add function cmSystemTools::StringToInt --- Source/cmSystemTools.cxx | 7 +++ Source/cmSystemTools.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index baac7b8..e247481 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2923,3 +2923,10 @@ std::vectorstd::string cmSystemTools::tokenize(const std::string str, } return tokens; } + +// +bool cmSystemTools::StringToInt(const char* str, int* value) { + char unused; + const int result = sscanf(str, %d%c, value, unused); + return (result == 1); +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 4455dd1..763389b 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -458,6 +458,9 @@ public: static std::vectorstd::string tokenize(const std::string str, const std::string sep); + /** Convert string to int. Expected that the whole string is an integer */ + static bool StringToInt(const char* str, int* value); + #ifdef _WIN32 struct WindowsFileRetry { -- 2.1.1 From 569bc681c0a980b87cd94184cfb83b44122d92a0 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Wed, 26 Nov 2014 01:46:14 +0300 Subject: [PATCH 2/7] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 111 Source/cmFileLockResult.h | 85 + 2 files changed, 196 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +#include errno.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this-ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), +
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/17/2014 6:45 PM, Ruslan Baratov wrote: Done Thanks for the updates. I'll try this out again when I get a chance. -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/15/2014 03:34 AM, Rolf Eike Beer wrote: Ruslan Baratov wrote: Done. Also I've found parse issue which is based on `sscanf` behaviour, e.g. string '123xyz' will be successfully parsed as a integer (%d). Same issue for example in file(STRINGS) command: I use strtol()/strtoul() for this kind of this, which also has a less worrisome interface. Yes, please change to that so a proper error can be produced for the new API when 123xyz is given as a timeout, for example. The file(STRINGS) command could be fixed with a separate change. In order to be compatible it should do something like %u%c and produce a warning if %c matched anything. On 11/14/2014 06:27 PM, Ruslan Baratov wrote: On linux you can test timeout by: cat script.cmake file(LOCK ${CMAKE_CURRENT_LIST_DIR}/file-to-lock TIMEOUT 5) execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 10) cmake -P script.cmake # start one instance in background cmake -P script.cmake # start second instance, expected lock failed by timeout CMake Error at script.cmake:1 (file): file : error locking file /.../file-to-lock (Timeout reached). Please look at adding a case to the test suite for this. An outer process could take the lock and then execute_process a child that tries to take the lock with a timeout. Then check that it fails as expected. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 17-Nov-14 18:06, Brad King wrote: Yes, please change to that so a proper error can be produced for the new API when 123xyz is given as a timeout, for example. Function added cmSystemTools::StringToInt Please look at adding a case to the test suite for this. An outer process could take the lock and then execute_process a child that tries to take the lock with a timeout. Then check that it fails as expected. Done Ruslo From 9a3e5728173d2b5e4381d3c65556534298f7bb27 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Tue, 18 Nov 2014 02:32:27 +0300 Subject: [PATCH 1/7] Add function cmSystemTools::StringToInt --- Source/cmSystemTools.cxx | 7 +++ Source/cmSystemTools.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 3247f7f..9664983 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2925,3 +2925,10 @@ std::vectorstd::string cmSystemTools::tokenize(const std::string str, } return tokens; } + +// +bool cmSystemTools::StringToInt(const char* str, int* value) { + char unused; + const int result = sscanf(str, %d%c, value, unused); + return (result == 1); +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 4455dd1..763389b 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -458,6 +458,9 @@ public: static std::vectorstd::string tokenize(const std::string str, const std::string sep); + /** Convert string to int. Expected that the whole string is an integer */ + static bool StringToInt(const char* str, int* value); + #ifdef _WIN32 struct WindowsFileRetry { -- 2.1.1 From 9e7e463d51a8944c8951540114e0e34824a239f5 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Tue, 18 Nov 2014 02:33:46 +0300 Subject: [PATCH 2/7] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 111 Source/cmFileLockResult.h | 85 + 2 files changed, 196 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +#include errno.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this-ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)errorText, + 0, + NULL + ); + + if (errorText != NULL) +{ +const std::string message = errorText; +::LocalFree(errorText); +return message; +} + else +{ +return Internal error (FormatMessageA failed); +} + } +#else + return strerror(this-ErrorValue); +#endif +case TIMEOUT: + return Timeout reached; +case ALREADY_LOCKED: + return File already locked; +case NO_FUNCTION: + return 'GUARD FUNCTION' not used in function definition; +case INTERNAL: +
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
Am Samstag, 15. November 2014, 02:27:40 schrieb Ruslan Baratov via cmake- developers: On 14-Nov-14 22:58, Brad King wrote: - Please add more test cases covering all the file(LOCK) argument processing error messages. Done. Also I've found parse issue which is based on `sscanf` behaviour, e.g. string '123xyz' will be successfully parsed as a integer (%d). Same issue for example in file(STRINGS) command: I use strtol()/strtoul() for this kind of this, which also has a less worrisome interface. Eike -- signature.asc Description: This is a digitally signed message part. -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
ConvertToWindowsExtendedPath fix + tests From e994378d61e64136043d9db614762e79927766cb Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Fri, 14 Nov 2014 21:09:35 +0400 Subject: [PATCH 1/6] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 111 Source/cmFileLockResult.h | 85 + 2 files changed, 196 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +#include errno.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this-ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)errorText, + 0, + NULL + ); + + if (errorText != NULL) +{ +const std::string message = errorText; +::LocalFree(errorText); +return message; +} + else +{ +return Internal error (FormatMessageA failed); +} + } +#else + return strerror(this-ErrorValue); +#endif +case TIMEOUT: + return Timeout reached; +case ALREADY_LOCKED: + return File already locked; +case NO_FUNCTION: + return 'GUARD FUNCTION' not used in function definition; +case INTERNAL: +default: + return Internal error; +} +} + +cmFileLockResult::cmFileLockResult(ErrorType typeValue, Error errorValue): +Type(typeValue), ErrorValue(errorValue) +{ +} diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h new file mode 100644 index 000..531fb49 --- /dev/null +++ b/Source/cmFileLockResult.h @@ -0,0 +1,85 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#ifndef cmFileLockResult_h +#define cmFileLockResult_h + +#include cmStandardIncludes.h + +#if defined(_WIN32) +# include windows.h // DWORD +#endif + +/** + * @brief Result of the locking/unlocking file. + * @note See @c cmFileLock + */ +class cmFileLockResult +{ + public: +#if defined(_WIN32) + typedef DWORD Error; +#else + typedef int Error; +#endif + + /** +* @brief Successful lock/unlock. +*/ + static cmFileLockResult MakeOk(); + + /** +* @brief Lock/Unlock failed. Read error/GetLastError. +*/ + static cmFileLockResult MakeSystem(); + + /** +* @brief Lock/Unlock failed. Timeout reached. +*/ + static cmFileLockResult MakeTimeout(); + + /** +* @brief File already locked. +*/ + static cmFileLockResult MakeAlreadyLocked(); + + /** +* @brief Internal error. +*/ + static cmFileLockResult
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/14/2014 12:31 PM, Ruslan Baratov wrote: ConvertToWindowsExtendedPath fix + tests Thanks. I started testing on Linux so far. A few more comments: - Please add more test cases covering all the file(LOCK) argument processing error messages. - Please squash in the attached patch to your commit that adds the file(LOCK) command to CMake. We should not need to build it during bootstrap. - Instead of ::sleep you can use cmSystemTools::Delay() - We need to test whether failing to lock after a timeout actually works. I tried adding a line to Tests/RunCMake/file/LOCK.cmake: file(LOCK ${lfile} TIMEOUT 3) at the end of the file, duplicating the one before it. I expected to see a 3 second delay followed by a lock failure. Instead it fails immediately. Is that expected? Thanks, -Brad From 36c0d3450f3968c2f3a3ee8912c6b9a12978906e Mon Sep 17 00:00:00 2001 Message-Id: 36c0d3450f3968c2f3a3ee8912c6b9a12978906e.1415994879.git.brad.k...@kitware.com From: Brad King brad.k...@kitware.com Date: Fri, 14 Nov 2014 14:39:46 -0500 Subject: [PATCH] file(LOCK): Drop this API during CMake bootstrap build CMake's own build system won't need this. --- Source/cmFileCommand.cxx| 9 +++-- Source/cmGlobalGenerator.h | 6 +- Source/cmLocalGenerator.cxx | 4 Source/cmMakefile.cxx | 4 bootstrap | 3 --- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 7d5d4c7..e060bbd 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -21,9 +21,8 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) #include cm_curl.h -#endif - #include cmFileLockResult.h +#endif #undef GetCurrentDirectory #include assert.h @@ -3511,6 +3510,7 @@ bool cmFileCommand::HandleGenerateCommand( bool cmFileCommand::HandleLockCommand( std::vectorstd::string const args) { +#if defined(CMAKE_BUILD_WITH_CMAKE) // Default values bool directory = false; bool release = false; @@ -3691,6 +3691,11 @@ bool cmFileCommand::HandleLockCommand( } return true; +#else + static_castvoid(args); + this-SetError(sub-command LOCK not implemented in boostrap cmake); + return false; +#endif } // diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 0f79174..0847654 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -21,9 +21,9 @@ #include cmExportSetMap.h // For cmExportSetMap #include cmGeneratorTarget.h #include cmGeneratorExpression.h -#include cmFileLockPool.h #if defined(CMAKE_BUILD_WITH_CMAKE) +# include cmFileLockPool.h # include cmsys/hash_map.hxx #endif @@ -349,7 +349,9 @@ public: std::setcmTarget const* const GetFilenameTargetDepends(cmSourceFile* sf) const; +#if defined(CMAKE_BUILD_WITH_CMAKE) cmFileLockPool GetFileLockPool() { return FileLockPool; } +#endif protected: virtual void Generate(); @@ -502,8 +504,10 @@ private: mutable std::mapcmSourceFile*, std::setcmTarget const* FilenameTargetDepends; +#if defined(CMAKE_BUILD_WITH_CMAKE) // Pool of file locks cmFileLockPool FileLockPool; +#endif }; #endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 6b5d785..2de6c93 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -79,11 +79,15 @@ public: this-GG = lg-GetGlobalGenerator(); this-LG = this-GG-GetCurrentLocalGenerator(); this-GG-SetCurrentLocalGenerator(lg); +#if defined(CMAKE_BUILD_WITH_CMAKE) this-GG-GetFileLockPool().PushFileScope(); +#endif } ~cmLocalGeneratorCurrent() { +#if defined(CMAKE_BUILD_WITH_CMAKE) this-GG-GetFileLockPool().PopFileScope(); +#endif this-GG-SetCurrentLocalGenerator(this-LG); } }; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a94c752..5484421 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4426,8 +4426,10 @@ void cmMakefile::PushScope() this-Internal-VarStack.push(cmDefinitions(parent)); this-Internal-VarInitStack.push(init); this-Internal-VarUsageStack.push(usage); +#if defined(CMAKE_BUILD_WITH_CMAKE) this-GetLocalGenerator()-GetGlobalGenerator()- GetFileLockPool().PushFunctionScope(); +#endif } void cmMakefile::PopScope() @@ -4465,8 +4467,10 @@ void cmMakefile::PopScope() { this-Internal-VarUsageStack.top().insert(*it); } +#if defined(CMAKE_BUILD_WITH_CMAKE) this-GetLocalGenerator()-GetGlobalGenerator()- GetFileLockPool().PopFunctionScope(); +#endif } void cmMakefile::RaiseScope(const std::string var, const char *varDef) diff --git a/bootstrap b/bootstrap index 19189d3..94bed0e 100755 --- a/bootstrap +++ b/bootstrap @@ -286,9 +286,6 @@ CMAKE_CXX_SOURCES=\ cmSystemTools \ cmTestGenerator \ cmVersion \ - cmFileLock \ - cmFileLockPool \ - cmFileLockResult \ cmFileTimeComparison \
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 14-Nov-14 22:58, Brad King wrote: - Please add more test cases covering all the file(LOCK) argument processing error messages. Done. Also I've found parse issue which is based on `sscanf` behaviour, e.g. string '123xyz' will be successfully parsed as a integer (%d). Same issue for example in file(STRINGS) command: cat script.cmake set(tmp ${CMAKE_CURRENT_LIST_DIR}/temp-file) file(WRITE ${tmp} qwertyuiopasdfghjklzxcvbnm) file(STRINGS ${tmp} result LIMIT_INPUT 7) message(result(1): ${result}) file(STRINGS ${tmp} result LIMIT_INPUT 7abc) # expected error message message(result(2): ${result}) cmake -P script.cmake result(1): qwertyu result(2): qwertyu - Please squash in the attached patch to your commit that adds the file(LOCK) command to CMake. We should not need to build it during bootstrap. - Instead of ::sleep you can use cmSystemTools::Delay() Done - We need to test whether failing to lock after a timeout actually works. I tried adding a line to Tests/RunCMake/file/LOCK.cmake: file(LOCK ${lfile} TIMEOUT 3) at the end of the file, duplicating the one before it. I expected to see a 3 second delay followed by a lock failure. Instead it fails immediately. Is that expected? Yes, since we know that we already own the lock nothing will change after timeout - it still be locked by us. On linux you can test timeout by: cat script.cmake file(LOCK ${CMAKE_CURRENT_LIST_DIR}/file-to-lock TIMEOUT 5) execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 10) cmake -P script.cmake # start one instance in background cmake -P script.cmake # start second instance, expected lock failed by timeout CMake Error at script.cmake:1 (file): file : error locking file /.../file-to-lock (Timeout reached). Ruslo From aa6418cd5a9bad2dfa26aae657d354d02cc39d20 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Sat, 15 Nov 2014 02:10:45 +0300 Subject: [PATCH 1/6] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 111 Source/cmFileLockResult.h | 85 + 2 files changed, 196 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +#include errno.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this-ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)errorText, + 0, + NULL + ); + + if (errorText != NULL) +{ +const std::string message = errorText; +::LocalFree(errorText); +return message; +} + else +{ +return Internal error (FormatMessageA failed); +} + } +#else + return strerror(this-ErrorValue); +#endif +case TIMEOUT: + return Timeout reached; +case ALREADY_LOCKED: + return File already locked; +case NO_FUNCTION: + return 'GUARD FUNCTION' not used in function definition; +case INTERNAL: +default: + return
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11-Nov-14 21:28, Brad King wrote: * All headers and sources need to include cmStandardIncludes.h first, directly or indirectly through other headers. It can affect the way certain standard library headers are preprocessed on some platforms, and needs to be consistent across all translation units. * Please add the .cxx files to 'bootstrap' and Source/CMakeLists.txt rather than including them in cmBootstrapCommands*.cxx. * The windows header should be included in lower case windows.h. * The cerrno and cstdio headers need to be just errno.h and stdio.h to work on some of the older compilers. * Please add documentation to Help/command/file.rst and anywhere else that is appropriate. Done * Please add test cases for all APIs and error cases, probably in Tests/RunCMake/file using the RunCMake infrastructure. I added test LOCK.cmake but not quite understand how to execute it. Is it possible to run tests only from 'Tests/RunCMake/file' directory? By the way I got the following error (Visual Studio 2013) if I include 'cmFileLockResult.h' before 'cm_curl.h' in file 'cmFileCommand.cxx': C:\Program Files (x86)\Windows Kits\8.1\Include\shared\ws2ipdef.h(202): error C2079: '_SOCKADDR_INET::Ipv4' uses undefined struct 'sockaddr_in' C:\Program Files (x86)\Windows Kits\8.1\Include\shared\ws2ipdef.h(715): error C2011: 'ip_mreq' : 'struct' type redefinition C:\Program Files (x86)\Windows Kits\8.1\Include\um\winsock.h(355) : see declaration of 'ip_mreq' C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(696): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(703): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(742): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(749): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(793): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(800): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(841): error C3861: 'WSASetLastError': identifier not found C:\Program Files (x86)\Windows Kits\8.1\Include\um\ws2tcpip.h(848): error C3861: 'WSASetLastError': identifier not found ...\cmake\Utilities\cmcurl/include/curl/curl.h(337): error C2079: 'curl_sockaddr::addr' uses undefined struct 'sockaddr' Compiles fine if 'cmFileLockResult.h' placed after 'cm_curl.h'. Ruslo From 55514802c135595e658f1897c123c0daf291ae81 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Thu, 13 Nov 2014 17:35:36 +0400 Subject: [PATCH 1/5] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 111 Source/cmFileLockResult.h | 85 + 2 files changed, 196 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +#include errno.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 +
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 11/13/2014 09:01 AM, Ruslan Baratov wrote: * Please add documentation to Help/command/file.rst and anywhere else that is appropriate. Done Thanks. I will try out the patch when I get a chance to provide further feedback. Is it possible to run tests only from 'Tests/RunCMake/file' directory? ctest -R RunCMake.file -V By the way I got the following error (Visual Studio 2013) if I include 'cmFileLockResult.h' before 'cm_curl.h' in file 'cmFileCommand.cxx': Compiles fine if 'cmFileLockResult.h' placed after 'cm_curl.h'. Okay. One comment from a quick scroll through the patches: - Use ConvertToWindowsExtendedPath for passing file paths to windows APIs. That will allow use of longer path names. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
Done On 31-Oct-14 16:39, Brad King wrote: On 10/31/2014 09:07 AM, Ruslan Baratov wrote: Does anybody ready to implement it or you want me to send the patches? Please work on the patches. You can use git format-patch to format them and post here either inline or as attachments. Thanks, -Brad From b235db704545bee59952c491c14a7eb4a5bdcde6 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov ruslan_bara...@yahoo.com Date: Fri, 7 Nov 2014 17:22:48 +0400 Subject: [PATCH 1/4] Add class cmFileLockResult --- Source/cmFileLockResult.cxx | 102 Source/cmFileLockResult.h | 77 + 2 files changed, 179 insertions(+) create mode 100644 Source/cmFileLockResult.cxx create mode 100644 Source/cmFileLockResult.h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 000..d6cb16e --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,102 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#include cmFileLockResult.h + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this-Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this-Type) +{ +case OK: + return 0; +case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this-ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)errorText, + 0, + NULL + ); + + if (errorText != NULL) +{ +const std::string message = errorText; +::LocalFree(errorText); +return message; +} + else +{ +return Internal error (FormatMessageA failed); +} + } +#else + return strerror(this-ErrorValue); +#endif +case TIMEOUT: + return Timeout reached; +case ALREADY_LOCKED: + return File already locked; +case INTERNAL: +default: + return Internal error; +} +} + +cmFileLockResult::cmFileLockResult(ErrorType typeValue, Error errorValue): +Type(typeValue), ErrorValue(errorValue) +{ +} diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h new file mode 100644 index 000..4d8f794 --- /dev/null +++ b/Source/cmFileLockResult.h @@ -0,0 +1,77 @@ +/* + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the License); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +*/ + +#ifndef cmFileLockResult_h +#define cmFileLockResult_h + +#if defined(_WIN32) +# include Windows.h // DWORD +#endif + +/** + * @brief Result of the locking/unlocking file. + * @note See @c cmFileLock + */ +class cmFileLockResult +{ + public: +#if defined(_WIN32) + typedef DWORD Error; +#else + typedef int Error; +#endif + + /** +* @brief Successful lock/unlock. +*/ + static cmFileLockResult MakeOk(); + + /** +* @brief Lock/Unlock failed. Read error/GetLastError. +*/ + static cmFileLockResult MakeSystem(); + + /** +* @brief Lock/Unlock failed. Timeout reached. +*/ + static cmFileLockResult MakeTimeout(); + + /** +* @brief File already locked. +*/ + static cmFileLockResult MakeAlreadyLocked(); + + /** +* @brief Internal error. +*/ + static
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
Does anybody ready to implement it or you want me to send the patches? Ruslo On 29-Oct-14 16:48, Brad King wrote: On 10/28/2014 04:28 PM, Ruslan Baratov wrote: What do you think about this: Thanks for drafting the signature. file( LOCK path [DIRECTORY] # if present locked file will be path/cmake.lock (instead of path) [RELEASE] # do explicit unlock [GUARD FUNCTION|FILE|PROCESS] # if not present - set to `GUARD PROCESS` (not used if RELEASE) [RESULT_VARIABLE variable] # 0 on success, error message otherwise; if not present - any error is FATAL_ERROR [TIMEOUT seconds] # 0 - return immediately if operation failed (try_lock), otherwise timeout (timed_lock); # if not present - lock until success (or error); # not used if RELEASE; ) That looks good. The TIMEOUT unit can be 'seconds' but it should accept a floating point value to get shorter times if possible. Boost implementation of file locking mechanism use LockFileEx/UnlockFileEx for windows and fcntl for unix-like platforms. These functions lock file only for current process. When process crashes lock removed by OS automatically. Great! I've tried (Un)LockFileEx/fcntl on windows (including mingw and cygwin), linux and mac - works fine for me with one exception: cygwin's lock is not visible by win32's lock. I.e. you can synchronize multiple cygwin processes and multiple windows normal processes, but you can't mix them. Thanks for testing. The windows/cygwin mixing limitation is acceptable IMO. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/31/2014 09:07 AM, Ruslan Baratov wrote: Does anybody ready to implement it or you want me to send the patches? Please work on the patches. You can use git format-patch to format them and post here either inline or as attachments. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/28/2014 04:28 PM, Ruslan Baratov wrote: What do you think about this: Thanks for drafting the signature. file( LOCK path [DIRECTORY] # if present locked file will be path/cmake.lock (instead of path) [RELEASE] # do explicit unlock [GUARD FUNCTION|FILE|PROCESS] # if not present - set to `GUARD PROCESS` (not used if RELEASE) [RESULT_VARIABLE variable] # 0 on success, error message otherwise; if not present - any error is FATAL_ERROR [TIMEOUT seconds] # 0 - return immediately if operation failed (try_lock), otherwise timeout (timed_lock); # if not present - lock until success (or error); # not used if RELEASE; ) That looks good. The TIMEOUT unit can be 'seconds' but it should accept a floating point value to get shorter times if possible. Boost implementation of file locking mechanism use LockFileEx/UnlockFileEx for windows and fcntl for unix-like platforms. These functions lock file only for current process. When process crashes lock removed by OS automatically. Great! I've tried (Un)LockFileEx/fcntl on windows (including mingw and cygwin), linux and mac - works fine for me with one exception: cygwin's lock is not visible by win32's lock. I.e. you can synchronize multiple cygwin processes and multiple windows normal processes, but you can't mix them. Thanks for testing. The windows/cygwin mixing limitation is acceptable IMO. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 13-Oct-14 18:39, Brad King wrote: With all the above in mind, please brainstorm and propose a more complete signature set. You can use the keyword/value pairing common in other commands to avoid needing a positional argument for every value. What do you think about this: file( LOCK path [DIRECTORY] # if present locked file will be path/cmake.lock (instead of path) [RELEASE] # do explicit unlock [GUARD FUNCTION|FILE|PROCESS] # if not present - set to `GUARD PROCESS` (not used if RELEASE) [RESULT_VARIABLE variable] # 0 on success, error message otherwise; if not present - any error is FATAL_ERROR [TIMEOUT seconds] # 0 - return immediately if operation failed (try_lock), otherwise timeout (timed_lock); # if not present - lock until success (or error); # not used if RELEASE; ) ? On 13-Oct-14 18:39, Brad King wrote: Also, please post a summary of how the implementation will work on each platform. Boost implementation of file locking mechanism use LockFileEx/UnlockFileEx for windows and fcntl for unix-like platforms. These functions lock file only for current process. When process crashes lock removed by OS automatically. In terms of boost documentation `file(LOCK ...)` locks are exclusive and advisory. boost.interprocess: http://www.boost.org/doc/libs/1_56_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.file_lock LockFileEx: http://msdn.microsoft.com/library/windows/desktop/aa365203%28v=vs.85%29.aspx UnlockFileEx: http://msdn.microsoft.com/library/windows/desktop/aa365716%28v=vs.85%29.aspx fcntl (linux): http://linux.die.net/man/2/fcntl fcntl (mac): https://developer.apple.com/library/Mac/documentation/Darwin/Reference/ManPages/man2/fcntl.2.html I've tried (Un)LockFileEx/fcntl on windows (including mingw and cygwin), linux and mac - works fine for me with one exception: cygwin's lock is not visible by win32's lock. I.e. you can synchronize multiple cygwin processes and multiple windows normal processes, but you can't mix them. On 13-Oct-14 18:34, Ben Boeckel wrote: Maybe we need something like the 'trap' shell builtin which runs code on various triggers rather than something like file/directory locks... Note that you can't set trap for SIGKILL. So if somebody will terminate your CMake instance by `kill -9 pid` probably you will have a problem. -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On Fri, Oct 10, 2014 at 17:59:07 +0400, Ruslan Baratov via cmake-developers wrote: Behavior when there's a lock that still exists (by bug/mistake) after CMake is done running is going to be strange and possibly hard-to-diagnose / hard-to-understand. That's *exactly* the problem I have and why I start this discussion. Currently I'm using mkdir command which return 0 only if directory created by current process (just to clarify, not the cmake -E make_directory). This works fine for me (tested on windows (mingw, cygwin), linux and mac). But I can't (or I don't know how) make remove this directory when I Ctrl+C my build (or abort the job on jenkins server). My current implementation just keep spinning with message: Directory locked by cmake, build started in directory cmake-binary-dir at timestamp. Maybe we need something like the 'trap' shell builtin which runs code on various triggers rather than something like file/directory locks which are…hairy (especially in the face of things like NFS or Samba)? I can think of at least: - end of configure - end of generate - end of directory scope - end of scope (function or directory) --Ben -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/10/2014 07:45 AM, Ruslan Baratov wrote: file(TRY_LOCK /path/to/file result) # try to lock and return TRUE on success (needed?) file(LOCK ...) # lock until unlock (unlock by further code (what if exit/crashed?) or by deamon) The LOCK signature should have a timeout after which it returns failure instead of blocking forever. One can just use a timeout of 0 to get TRY_LOCK behavior without a separate signature for it. Or, by leaving out the timeout, one can ask to block forever waiting for the lock. file(LOCK_GUARD ...) # lock for scope of current function or until exit I think the GUARD part can be an option to file(LOCK). We may need more than one to determine the scope, e.g. file(LOCK GUARD_FUNCTION ...) file(LOCK GUARD_PROCESS ...) file(UNLOCK ...) # explicit unlock of LOCK/LOCK_GUARD Perhaps file(LOCK RELEASE ...) # unlock now file(LOCK UNGUARD ...) # drop guard Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: I think this can be activated buy a DIRECTORY option. If any of this commands failed (e.g. have no permissions) - exit with unsuccessful code (i.e. FATAL_ERROR) ? The commands should all have an optional result argument so callers can find out what happened. If it is not provided, then failure can result in a FATAL_ERROR. With all the above in mind, please brainstorm and propose a more complete signature set. You can use the keyword/value pairing common in other commands to avoid needing a positional argument for every value. Also, please post a summary of how the implementation will work on each platform. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/13/2014 10:34 AM, Ben Boeckel wrote: Maybe we need something like the 'trap' shell builtin which runs code on various triggers That would first require an 'eval' equivalent in CMake, e.g. cmake_eval(). This has been requested a few times. -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 08-Oct-14 16:45, Brad King wrote: On 10/08/2014 07:52 AM, Ruslan Baratov wrote: Okay :) I just not sure that I understand to pass to some other process goal correctly. That was just an example of why one might want to drop management of the lock by CMake without actually unlocking it. Perhaps the code is starting a daemon and passes off responsibility for the unlock side to the daemon process. Okay, got it. * we just need to `unlock` file so the other instance will use it: file(UNLOCK_FILE /path/to/shared/file) # now anybody can do the lock Yes. We also need the locking API to return information about whether we really acquired the lock. So it can be TRY_LOCK and LOCK. But does the TRY_LOCK really needed? With LOCK we can try to lock and spin until acquire, but what to do with TRY_LOCK? Just give up? * we need other process to inherit the lock (what for?), i.e. move ownership (?): file(LOCK_FILE /path/to/shared/file) execute_process(${CMAKE_COMMAND} --take-ownership /path/to/shared/file ...) # unlocked by execute_process I think all we need there is a way to ask CMake to take over responsibility for a lock that it did not originally create. It can also be in the file() command. Thanks, -Brad Okay, so here is the commands inspired by C++: file(TRY_LOCK /path/to/file result) # try to lock and return TRUE on success (needed?) file(LOCK ...) # lock until unlock (unlock by further code (what if exit/crashed?) or by deamon) file(LOCK_GUARD ...) # lock for scope of current function or until exit file(UNLOCK ...) # explicit unlock of LOCK/LOCK_GUARD Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: file(DIRECTORY_TRY_LOCK ...) file(DIRECTORY_LOCK /path/to/shared/directory/) # == file(LOCK /path/to/shared/directory/cmake.lock) file(DIRECTORY_LOCK_GUARD ...) file(DIRECTORY_UNLOCK ...) If any of this commands failed (e.g. have no permissions) - exit with unsuccessful code (i.e. FATAL_ERROR) ? * http://en.cppreference.com/w/cpp/thread/try_lock * http://en.cppreference.com/w/cpp/thread/lock * http://en.cppreference.com/w/cpp/thread/lock_guard * http://en.cppreference.com/w/cpp/thread/mutex/unlock -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
What is the main use case for locking files and directories from the CMake language? I feel slightly uncomfortable, without being able to put my finger on exactly why, with the prospect of adding this to CMake... Behavior when there's a lock that still exists (by bug/mistake) after CMake is done running is going to be strange and possibly hard-to-diagnose / hard-to-understand. Let's make sure the use case is quite strong before we accept the possibility of stale locks in CMake. Thanks, David C. On Fri, Oct 10, 2014 at 7:45 AM, Ruslan Baratov via cmake-developers cmake-developers@cmake.org wrote: On 08-Oct-14 16:45, Brad King wrote: On 10/08/2014 07:52 AM, Ruslan Baratov wrote: Okay :) I just not sure that I understand to pass to some other process goal correctly. That was just an example of why one might want to drop management of the lock by CMake without actually unlocking it. Perhaps the code is starting a daemon and passes off responsibility for the unlock side to the daemon process. Okay, got it. * we just need to `unlock` file so the other instance will use it: file(UNLOCK_FILE /path/to/shared/file) # now anybody can do the lock Yes. We also need the locking API to return information about whether we really acquired the lock. So it can be TRY_LOCK and LOCK. But does the TRY_LOCK really needed? With LOCK we can try to lock and spin until acquire, but what to do with TRY_LOCK? Just give up? * we need other process to inherit the lock (what for?), i.e. move ownership (?): file(LOCK_FILE /path/to/shared/file) execute_process(${CMAKE_COMMAND} --take-ownership /path/to/shared/file ...) # unlocked by execute_process I think all we need there is a way to ask CMake to take over responsibility for a lock that it did not originally create. It can also be in the file() command. Thanks, -Brad Okay, so here is the commands inspired by C++: file(TRY_LOCK /path/to/file result) # try to lock and return TRUE on success (needed?) file(LOCK ...) # lock until unlock (unlock by further code (what if exit/crashed?) or by deamon) file(LOCK_GUARD ...) # lock for scope of current function or until exit file(UNLOCK ...) # explicit unlock of LOCK/LOCK_GUARD Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: file(DIRECTORY_TRY_LOCK ...) file(DIRECTORY_LOCK /path/to/shared/directory/) # == file(LOCK /path/to/shared/directory/cmake.lock) file(DIRECTORY_LOCK_GUARD ...) file(DIRECTORY_UNLOCK ...) If any of this commands failed (e.g. have no permissions) - exit with unsuccessful code (i.e. FATAL_ERROR) ? * http://en.cppreference.com/w/cpp/thread/try_lock * http://en.cppreference.com/w/cpp/thread/lock * http://en.cppreference.com/w/cpp/thread/lock_guard * http://en.cppreference.com/w/cpp/thread/mutex/unlock -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10-Oct-14 16:58, David Cole wrote: What is the main use case for locking files and directories from the CMake language? I feel slightly uncomfortable, without being able to put my finger on exactly why, with the prospect of adding this to CMake... I've described the situation in the first message of this thread: sharing resources between different cmake builds. If you want the particular case: I'm developing cmake-based package manager that share the builds of ExternalProject_Add. I'm experienced problems even when working on my local machine (I've started long-build in one console, then accidentally connect to the same shared directory in other console), but the main problem here is the server auto-builds which usually start multiple jobs simultaneously. Behavior when there's a lock that still exists (by bug/mistake) after CMake is done running is going to be strange and possibly hard-to-diagnose / hard-to-understand. That's *exactly* the problem I have and why I start this discussion. Currently I'm using mkdir command which return 0 only if directory created by current process (just to clarify, not the cmake -E make_directory). This works fine for me (tested on windows (mingw, cygwin), linux and mac). But I can't (or I don't know how) make remove this directory when I Ctrl+C my build (or abort the job on jenkins server). My current implementation just keep spinning with message: Directory locked by cmake, build started in directory cmake-binary-dir at timestamp. Let's make sure the use case is quite strong before we accept the possibility of stale locks in CMake. Command `file(LOCK_GUARD ...)` will cover 100% of my needs. Other commands that I've mentioned used to cover suggestions from Brad K. (may be I've just understand them wrong). Ruslo Thanks, David C. On Fri, Oct 10, 2014 at 7:45 AM, Ruslan Baratov via cmake-developers cmake-developers@cmake.org wrote: On 08-Oct-14 16:45, Brad King wrote: On 10/08/2014 07:52 AM, Ruslan Baratov wrote: Okay :) I just not sure that I understand to pass to some other process goal correctly. That was just an example of why one might want to drop management of the lock by CMake without actually unlocking it. Perhaps the code is starting a daemon and passes off responsibility for the unlock side to the daemon process. Okay, got it. * we just need to `unlock` file so the other instance will use it: file(UNLOCK_FILE /path/to/shared/file) # now anybody can do the lock Yes. We also need the locking API to return information about whether we really acquired the lock. So it can be TRY_LOCK and LOCK. But does the TRY_LOCK really needed? With LOCK we can try to lock and spin until acquire, but what to do with TRY_LOCK? Just give up? * we need other process to inherit the lock (what for?), i.e. move ownership (?): file(LOCK_FILE /path/to/shared/file) execute_process(${CMAKE_COMMAND} --take-ownership /path/to/shared/file ...) # unlocked by execute_process I think all we need there is a way to ask CMake to take over responsibility for a lock that it did not originally create. It can also be in the file() command. Thanks, -Brad Okay, so here is the commands inspired by C++: file(TRY_LOCK /path/to/file result) # try to lock and return TRUE on success (needed?) file(LOCK ...) # lock until unlock (unlock by further code (what if exit/crashed?) or by deamon) file(LOCK_GUARD ...) # lock for scope of current function or until exit file(UNLOCK ...) # explicit unlock of LOCK/LOCK_GUARD Locking directory is equivalent to locking file `cmake.lock` in directory /path/to/shared/directory/: file(DIRECTORY_TRY_LOCK ...) file(DIRECTORY_LOCK /path/to/shared/directory/) # == file(LOCK /path/to/shared/directory/cmake.lock) file(DIRECTORY_LOCK_GUARD ...) file(DIRECTORY_UNLOCK ...) If any of this commands failed (e.g. have no permissions) - exit with unsuccessful code (i.e. FATAL_ERROR) ? * http://en.cppreference.com/w/cpp/thread/try_lock * http://en.cppreference.com/w/cpp/thread/lock * http://en.cppreference.com/w/cpp/thread/lock_guard * http://en.cppreference.com/w/cpp/thread/mutex/unlock -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 07-Oct-14 16:25, Brad King wrote: On 10/07/2014 02:49 AM, Ruslan Baratov wrote: How it will looks like in terms of CMake code? That's what I'm asking you to think through and propose ;) Thanks, -Brad Okay :) I just not sure that I understand to pass to some other process goal correctly. * we just need to `unlock` file so the other instance will use it: file(UNLOCK_FILE /path/to/shared/file) # now anybody can do the lock * we need other process to inherit the lock (what for?), i.e. move ownership (?): file(LOCK_FILE /path/to/shared/file) execute_process(${CMAKE_COMMAND} --take-ownership /path/to/shared/file ...) # unlocked by execute_process Ruslo -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/08/2014 07:52 AM, Ruslan Baratov wrote: Okay :) I just not sure that I understand to pass to some other process goal correctly. That was just an example of why one might want to drop management of the lock by CMake without actually unlocking it. Perhaps the code is starting a daemon and passes off responsibility for the unlock side to the daemon process. * we just need to `unlock` file so the other instance will use it: file(UNLOCK_FILE /path/to/shared/file) # now anybody can do the lock Yes. We also need the locking API to return information about whether we really acquired the lock. * we need other process to inherit the lock (what for?), i.e. move ownership (?): file(LOCK_FILE /path/to/shared/file) execute_process(${CMAKE_COMMAND} --take-ownership /path/to/shared/file ...) # unlocked by execute_process I think all we need there is a way to ask CMake to take over responsibility for a lock that it did not originally create. It can also be in the file() command. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 06-Oct-14 16:54, Brad King wrote: On 10/05/2014 04:59 PM, Ruslan Baratov via cmake-developers wrote: So it can't be resolved without some low-level management. I'm thinking about `file` command sub-option like LOCK_DIRECTORY: `file(LOCK_DIRECTORY /path/to/shared-dir)`. Does it sounds doable? I think it is a reasonable proposal. However, more design is needed here, including at least the following items: * There needs to be a way to define the scope of the lock other than until cmake exits. For example, until current function exits. * There needs to be a way to explicitly unlock early, or to explicitly release management of the lock (e.g. to pass to some other process). How it will looks like in terms of CMake code? * The implementation on Windows needs to be handled carefully. The safe way to delete a file there is to open it with a handle that is marked as delete-on-close, and then close the handle. That way the file is eventually deleted even if other processes currently have it open/locked. I don't know if there is an equivalent for a directory. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/07/2014 02:49 AM, Ruslan Baratov wrote: How it will looks like in terms of CMake code? That's what I'm asking you to think through and propose ;) Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
On 10/05/2014 04:59 PM, Ruslan Baratov via cmake-developers wrote: So it can't be resolved without some low-level management. I'm thinking about `file` command sub-option like LOCK_DIRECTORY: `file(LOCK_DIRECTORY /path/to/shared-dir)`. Does it sounds doable? I think it is a reasonable proposal. However, more design is needed here, including at least the following items: * There needs to be a way to define the scope of the lock other than until cmake exits. For example, until current function exits. * There needs to be a way to explicitly unlock early, or to explicitly release management of the lock (e.g. to pass to some other process). * The implementation on Windows needs to be handled carefully. The safe way to delete a file there is to open it with a handle that is marked as delete-on-close, and then close the handle. That way the file is eventually deleted even if other processes currently have it open/locked. I don't know if there is an equivalent for a directory. Thanks, -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
[cmake-developers] New command 'file(LOCK_DIRECTORY ...)'
Hi, I have CMake modules that can share resources between different instances. For now I manage it by invoking `mkdir shared-dir/lock-directory` and checking the result, then removing this directory so the next instance can do the modification. The problem occurs when somebody terminate CMake. Since I can't set handler (e.g. SIGINT) to CMake, directory will not be removed and will be locked forever. So it can't be resolved without some low-level management. I'm thinking about `file` command sub-option like LOCK_DIRECTORY: `file(LOCK_DIRECTORY /path/to/shared-dir)`. Does it sounds doable? Thanks, Ruslo -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers