internal TLog StartNested() { TLog inner = new TLog(); inner.outer = this; return(inner); }
public T ReadTVar <T>(TVar <T> location) { TLog trans = this; do { Entry entry; if (trans.log.TryGetValue(location, out entry)) { return(((Entry <T>)entry).newValue); } trans = trans.outer; } while(trans != null); Entry <T> entryT = new Entry <T>(location); log.Add(location, entryT); return(entryT.oldValue); }
public T OrElse <T>(StmAction <T> p, StmAction <T> q) { TLog fst = this.StartNested(); try { T result = p(fst); fst.Lock(); bool isValid = fst.IsValid(); fst.UnLock(); if (isValid) { fst.MergeNested(); return(result); } else { throw new CommitFailedException(); } } catch (RetryException) { TLog snd = this.StartNested(); try { T result = q(snd); snd.Lock(); bool isValid = snd.IsValid(); snd.UnLock(); if (isValid) { snd.MergeNested(); return(result); } else { throw new CommitFailedException(); } } catch (RetryException) { this.Lock(); bool isValid = fst.IsValidSingle() && snd.IsValidSingle() && this.IsValid(); this.UnLock(); if (isValid) { fst.MergeNested(); snd.MergeNested(); throw; } else { throw new CommitFailedException(); } } catch (CommitFailedException) { throw; } catch (ThreadInterruptedException) { throw; } catch { snd.Lock(); bool isValid = snd.IsValid(); snd.UnLock(); if (isValid) { snd.MergeNested(); throw; } else { throw new CommitFailedException(); } } } catch (CommitFailedException) { throw; } catch (ThreadInterruptedException) { throw; } catch { fst.Lock(); bool isValid = fst.IsValid(); fst.UnLock(); if (isValid) { fst.MergeNested(); throw; } else { throw new CommitFailedException(); } } }
public static T Atomic <T>(StmAction <T> p) { TLog trans = new TLog(); while (true) { bool retry = false; try { T result = p(trans); trans.Lock(); bool isValid = trans.IsValid(); if (isValid) { trans.Commit(); trans.Signal(); } trans.UnLock(); if (isValid) { return(result); } } catch (RetryException) { // cannot receive ThreadInterruptedException in catch handler retry = true; } catch (CommitFailedException) { } catch (ThreadInterruptedException) { throw; } catch { trans.Lock(); bool isValid = trans.IsValid(); trans.UnLock(); if (isValid) { throw; } } if (retry) { trans.Lock(); bool isValid = trans.IsValid(); if (isValid) { trans.Wait(); try { do { trans.Block(); }while (trans.IsValid()); } finally { trans.UnWait(); trans.UnLock(); } } else { trans.UnLock(); } } trans.log.Clear(); Thread.Sleep(0); } }