What guarantees (if any) do interruptible operations have in presence of asynchronous exceptions?
From the discussion of "Help needed interrupting accepting a network connection", what we have so far is:
* To break out of an "accept" call, an asynchronous exception is needed. * The presence of asynchronous exceptions complicates the other code used to report if "accept" completed or was interrupted, whether that code is written using MVar's or STM. Thus the next question is what guarantees, if any, do interruptible operations possess? For example, suppose that inside of a "block", a putMVar operation was guaranteed to either interrupt and allow an asynchronous exception to be raised, or to complete the putMVar operation, but not both. If this were true, then if you caught an asynchronous exception from the putMVar operation, you'd know that a value was not put into the MVar by the operation. Then it would be easy to program with MVar's in the presence of asynchronous exceptions. When you caught an asynchronous exception, you could set a flag, and then redo the putMVar. The same question can be asked of other interruptible operations. For the "accept" call itself, is it guaranteed (inside of a "block") to either accept a connection, or be interrupted and allow an asynchronous exception to be raised, but not both? For STM, is "atomically" an interruptible operation? If it is, what guarantees does it offer in the presence of asynchronous exceptions?
Making small programs to test these properties is a good sanity check. For instance I just leaned that "safePoint = unblock ( return () )" does not work. What I think happens: Cat Dancer wrote:
From the discussion of "Help needed interrupting accepting a network connection", what we have so far is:
* To break out of an "accept" call, an asynchronous exception is needed.
* The presence of asynchronous exceptions complicates the other code used to report if "accept" completed or was interrupted, whether that code is written using MVar's or STM.
Thus the next question is what guarantees, if any, do interruptible operations possess?
During "unblock" anything can happen. During "block": No async. exceptions are raised, unless... ...the "block" is lifted by an "interruptible operation" The will only happen when that operation must block.
For example, suppose that inside of a "block", a putMVar operation was guaranteed to either interrupt and allow an asynchronous exception to be raised, or to complete the putMVar operation, but not both.
A putMVar will only allow interruptions insofar as it must wait for the MVar to become empty. So while it is waiting on the MVar it may receive an async. exception and so will not perform the put operation.
If this were true, then if you caught an asynchronous exception from the putMVar operation, you'd know that a value was not put into the MVar by the operation.
I think that should be a safe assumption when running under "block".
Then it would be easy to program with MVar's in the presence of asynchronous exceptions. When you caught an asynchronous exception, you could set a flag, and then redo the putMVar.
If you call that "easy" then sure.
The same question can be asked of other interruptible operations.
For the "accept" call itself, is it guaranteed (inside of a "block") to either accept a connection, or be interrupted and allow an asynchronous exception to be raised, but not both?
That should be true, for the same reason as putMVar.
For STM, is "atomically" an interruptible operation? If it is, what guarantees does it offer in the presence of asynchronous exceptions?
"block (atomically stm)" is interruptible when the operation "stm" uses retry and perhaps when it has to be re-attempted due to conflicting updates. If it runs without conflict and commits then it cannot be interrupted by an async exception. If (atomically stm) is interrupted then it is rolled back and will have had no visible side effects. -- Chris
On 12/5/06, Chris Kuklewicz <haskell@list.mightyreason.com> wrote:
Making small programs to test these properties is a good sanity check. For instance I just leaned that "safePoint = unblock ( return () )" does not work.
Maybe if you do something to allocate some memory inside of the unblock?
If this were true, then if you caught an asynchronous exception from the putMVar operation, you'd know that a value was not put into the MVar by the operation.
I think that should be a safe assumption when running under "block".
"I think" and "should be" is nice, how do we find out if it's really true -- for sure?
Then it would be easy to program with MVar's in the presence of asynchronous exceptions. When you caught an asynchronous exception, you could set a flag, and then redo the putMVar.
If you call that "easy" then sure.
For STM, is "atomically" an interruptible operation? If it is, what guarantees does it offer in the presence of asynchronous exceptions?
"block (atomically stm)" is interruptible when the operation "stm" uses retry and perhaps when it has to be re-attempted due to conflicting updates. If it runs without conflict and commits then it cannot be interrupted by an async exception.
If (atomically stm) is interrupted then it is rolled back and will have had no visible side effects.
Easy in the sense that the pattern of "trying an operation, setting a flag if an asynchronous exception is raised, and redoing the operation" can be encapsulated in a function. That function can then be used with any interruptible operation (such as putMVar, or atomically, or accept) *if* the operation guarantees that inside of a "block" it will either perform its operation, or interrupt and allow an asynchronous to be raised, but not both.
Cat Dancer wrote:
On 12/5/06, Chris Kuklewicz <haskell@list.mightyreason.com> wrote:
Making small programs to test these properties is a good sanity check. For instance I just leaned that "safePoint = unblock ( return () )" does not work.
Maybe if you do something to allocate some memory inside of the unblock?
If this were true, then if you caught an asynchronous exception from the putMVar operation, you'd know that a value was not put into the MVar by the operation.
I think that should be a safe assumption when running under "block".
"I think" and "should be" is nice, how do we find out if it's really true -- for sure?
Read the papers the have been written about the design (see the wiki for links) and ask the developers of the compiler you are using. nicely.
participants (2)
-
Cat Dancer -
Chris Kuklewicz