www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - scope(exit)

reply MM <MM_member pathlink.com> writes:
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
next sibling parent reply Sean Kelly <sean f4.ca> writes:
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
parent reply MM <MM_member pathlink.com> writes:
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

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 12 2006
next sibling parent MM <MM_member pathlink.com> writes:
In article <e43ilf$141k$1 digitaldaemon.com>, MM says...
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

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... :)

change should be chance
May 12 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
MM wrote:
 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.

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... :)

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 :-) Sean
May 15 2006
prev sibling parent "Derek Parnell" <derek psych.ward> writes:
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