digitalmars.D - scope(exit)
- MM (9/9) May 12 2006 I've been reading through Exception Safe Programming page and I had a qu...
- Sean Kelly (18/29) May 12 2006 Personally, I find the basic guarantee to be of very limited use. For
- MM (6/23) May 12 2006 Lock && unlock could ofcourse be any arbitrary function.. thus I was ask...
- MM (2/29) May 12 2006 change should be chance
- Sean Kelly (22/47) May 15 2006 Typically, you want to use the strongest guarantee you can reasonably
- Derek Parnell (9/20) May 10 2006 I prefer to think of the purpose of 'unlock' is to ensure that the
I've been reading through Exception Safe Programming page and I had a question: why not: scope(exit) unlock(m); lock(m); iso the inverse? lock() might crash but might still have locked m Or is this stpd reasoning? unlocking m when it is not locked should not ba a problem or the scope(exit) could check whether or not m is locked?
May 12 2006
MM wrote:I've been reading through Exception Safe Programming page and I had a question: why not: scope(exit) unlock(m); lock(m); iso the inverse? lock() might crash but might still have locked m Or is this stpd reasoning? unlocking m when it is not locked should not ba a problem or the scope(exit) could check whether or not m is locked?Personally, I find the basic guarantee to be of very limited use. For most operations, the weak guarantee seems far more appropriate, and I believe it is reasonable to expect that of the lock function. In other words, if the lock function fails then I would expect m to be in the state it was in prior to the lock call. Further, it's possible that unlock might consider being asked to unlock a mutex that the calling thread doesn't own to be an error condition, which may result in an exception being generated. Therefore, if lock fails and throws and exception and scope(exit) unlock(m) therefore fails and throws an exception as well, the application will terminate because it has two exceptions in flight simultaneously. Therefore: lock(m); scope(exit) unlock(m); is preferred because unlock will only be called if a lock was successfully obtained, and will be called regardless of whether the following code generates an error or completes successfully. Sean
May 12 2006
Personally, I find the basic guarantee to be of very limited use. For most operations, the weak guarantee seems far more appropriate, and I believe it is reasonable to expect that of the lock function. In other words, if the lock function fails then I would expect m to be in the state it was in prior to the lock call. Further, it's possible that unlock might consider being asked to unlock a mutex that the calling thread doesn't own to be an error condition, which may result in an exception being generated. Therefore, if lock fails and throws and exception and scope(exit) unlock(m) therefore fails and throws an exception as well, the application will terminate because it has two exceptions in flight simultaneously. Therefore: lock(m); scope(exit) unlock(m); is preferred because unlock will only be called if a lock was successfully obtained, and will be called regardless of whether the following code generates an error or completes successfully. SeanLock && unlock could ofcourse be any arbitrary function.. thus I was asking myself, why use the weak guarantee? When you take the change on a fault in lock at about the same as unlock your reasoning would be sound. But most of the time(in my code:) the 'unlock' function is far less complex than the 'lock' function. Is it then still better to use the weak guarantee?(not a retoric question... :)
May 12 2006
In article <e43ilf$141k$1 digitaldaemon.com>, MM says...change should be chancePersonally, I find the basic guarantee to be of very limited use. For most operations, the weak guarantee seems far more appropriate, and I believe it is reasonable to expect that of the lock function. In other words, if the lock function fails then I would expect m to be in the state it was in prior to the lock call. Further, it's possible that unlock might consider being asked to unlock a mutex that the calling thread doesn't own to be an error condition, which may result in an exception being generated. Therefore, if lock fails and throws and exception and scope(exit) unlock(m) therefore fails and throws an exception as well, the application will terminate because it has two exceptions in flight simultaneously. Therefore: lock(m); scope(exit) unlock(m); is preferred because unlock will only be called if a lock was successfully obtained, and will be called regardless of whether the following code generates an error or completes successfully. SeanLock && unlock could ofcourse be any arbitrary function.. thus I was asking myself, why use the weak guarantee? When you take the change on a fault in lock at about the same as unlock your reasoning would be sound. But most of the time(in my code:) the 'unlock' function is far less complex than the 'lock' function. Is it then still better to use the weak guarantee?(not a retoric question... :)
May 12 2006
MM wrote:Typically, you want to use the strongest guarantee you can reasonably provide, which in most cases is the weak guarantee. The strong guarantee is mostly reserved for dtors and other operations that simply cannot fail, and it is typically either too difficult or is simply inadvisable to provide for anything but clean-up or certain other critical operations. The weak guarantee is what most people expect: if an error occurs, it's as if they had never called the function. By contrast, the basic guarantee merely ensures that a failure won't leave your application inclined to light its hair on fire and jump out a window--data structures are allowed to remain partially modified so long as they are in a stable state, etc. As for the scope declarations, it makes sense to me that they should occur after whatever operation they are paired with. That is, if a function fails then I would expect that to mean it hadn't done whatever it was supposed to do and there should be no need to call the paired function. So if lock/open/whatever throws an exception then it was unable to lock/open/do whatever it was supposed to do. If for some reason this function is a complex multi-step process that can't be recovered from if something goes wrong and exceptions simply must be thrown at arbitrary locations then consider redesigning the component :-) SeanPersonally, I find the basic guarantee to be of very limited use. For most operations, the weak guarantee seems far more appropriate, and I believe it is reasonable to expect that of the lock function. In other words, if the lock function fails then I would expect m to be in the state it was in prior to the lock call. Further, it's possible that unlock might consider being asked to unlock a mutex that the calling thread doesn't own to be an error condition, which may result in an exception being generated. Therefore, if lock fails and throws and exception and scope(exit) unlock(m) therefore fails and throws an exception as well, the application will terminate because it has two exceptions in flight simultaneously. Therefore: lock(m); scope(exit) unlock(m); is preferred because unlock will only be called if a lock was successfully obtained, and will be called regardless of whether the following code generates an error or completes successfully.Lock && unlock could ofcourse be any arbitrary function.. thus I was asking myself, why use the weak guarantee? When you take the change on a fault in lock at about the same as unlock your reasoning would be sound. But most of the time(in my code:) the 'unlock' function is far less complex than the 'lock' function. Is it then still better to use the weak guarantee?(not a retoric question... :)
May 15 2006
On Sat, 13 May 2006 10:16:11 +1000, MM <MM_member pathlink.com> wrote:I've been reading through Exception Safe Programming page and I had a question: why not: scope(exit) unlock(m); lock(m); iso the inverse? lock() might crash but might still have locked m Or is this stpd reasoning? unlocking m when it is not locked should not ba a problem or the scope(exit) could check whether or not m is locked?I prefer to think of the purpose of 'unlock' is to ensure that the resource is unlocked by the time the function completes. This is slightly different from saying the purpose of 'unlock' is to unlock the resource. Thus if it is already unlocked when it starts, all it does is return. The same goes for a file or database 'close' function. -- Derek Parnell Melbourne, Australia
May 10 2006