Example #1
0
File: Stm.cs Project: gusty/fsharpx
        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();
                }
            }
        }
Example #2
0
File: Stm.cs Project: gusty/fsharpx
        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);
            }
        }