Page 1 of 3 123 LastLast
Results 1 to 10 of 21

Thread: Async issue

  1. #1

    Default Async issue

    I didn't see this before, first time encountered while making compactor.

    The issue is following: when only READING from many threads one shared locator, mistake appears. Mistake appears sometimes, in this example you will definitely catch it.
    Code for reproduction:


    public void Main()
    {
      InitTable();
      StartManyThreads();
    }
    
    XTable<string, string> myxtable = null;
            string myxtable_stringName = "myTableName";
            StorageEngine se = null;
    
            private void InitTable()
            {
                File.Delete(e1dbPath);
             
                se = StorageEngine.FromFile(e1dbPath);           
                myxtable = se.Scheme.CreateOrOpenXTable<string, string>(new Locator(myxtable_stringName));
                se.Scheme.Commit();
    
                myxtable["t1"] = "sdfjsdlfkjsdlfj sl";
                myxtable["t2"] = "sdfjsdlfkjsddsdfsdfj sl";
                myxtable["t3"] = "sdfjsdlsadfasdfsadfasdsafkjsddsdfsdfj sl";
                myxtable.Commit();
            }
    
            private void ReadIt1(object key)
            {
                bool couldGetValue = false;
                string stringValue = String.Empty;
    
                for (int i = 0; i < 10000; i++)
                {
                    try
                    {
    
                        couldGetValue = myxtable.TryGet(Convert.ToString(key), out stringValue);
                    }
                    catch (Exception ex)
                    {
                        //--------------------------- PUT A BREAKPOINT
                        //Exception: LinkedList node doesn't belong to the curernt LinkedList
                        //Occurs in FTable.Link.Touch()
                        throw ex;
                    }
                }
    
                Console.WriteLine("DONE");
            }
    
            private void StartManyThreads()
            {           
                for (int i = 1; i <= 3; i++)
                {
                    System.Threading.Thread tr = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ReadIt1));
                    tr.Start("t" + i.ToString());         
                }
            }
    
    Last edited by blaze; 12.02.2012 at 01:07.

  2. #2

    Default

    There are thread unsafe operations like Add, Remove, Clear in the LinkedList.

    And, my bad, it 's a cache, sure for different read locators it fills with different values.

    Issue is closed, will have to make a small re-design of MTL.
    Last edited by blaze; 12.02.2012 at 03:47.

  3. #3

    Default

    It doesn't appear in this case.

    private void ReadIt1(object key)
            {
                bool couldGetValue = false;
                string stringValue = String.Empty;
                XTable<string, string> table = null;
    
    lock (se.Scheme.SyncRoot)
                        {
                            table = se.Scheme.OpenXTable<string, string>(new Locator(myxtable_stringName));
                        }   
    
                for (int i = 0; i < 100000; i++)
                {
                    try
                    {         
                                                  
                        couldGetValue = table.TryGet(Convert.ToString(key), out stringValue);
                      
                    }
                    catch (Exception ex)
                    {
                        //--------------------------- PUT A BREAKPOINT
                        //Exception: LinkedList node doesn't belong to the curernt LinkedList
                        //Occurs in FTable.Link.Touch()
                        throw ex;
                    }
                }
    
                Console.WriteLine("DONE");
            }
    
    Last edited by blaze; 12.02.2012 at 03:43.

  4. #4

    Default

    ...when only READING from many threads one shared locator, mistake appears.
    XTable instances are not thread safe.

  5. #5

    Default

    Quote Originally Posted by a.todorov View Post
    XTable instances are not thread safe.
    One small question about the multi-threading rules.
    Please, approve my reasoning, for version 3.5.

    - Write into 2 different tables can be done from 2 parallel threads without locks.
    (1 thread writes into table1, 2 thread into table2)

    - Commit of 2 different tables can be done from 2 parallel threads without locks.
    (1 thread commits table1, 2 thread commits table2). Used table1.Commit(); and table2.Commit();.

    - Commit of 2 different tables must be done from 2 parallel threads with lock.
    If used transaction.Commit(table1,table2) technique, because we touch transaction journal table.

    - And Commit of 1 table from parallel threads must be done via lock.

  6. #6

    Default

    Yes, the answer for all is positive.

  7. #7

    Default

    Quote Originally Posted by a.todorov View Post
    Yes, the answer for all is positive.
    Thank you, very much!

  8. #8

    Default

    To finish the story

    - Opening 1 table from different threads using 2 locators must come via lock

    - Opening and reading 1 table via one locator from diff. threads must come via mutual lock

    - Opening table and committing of the same tabe must come via mutual lock.

    - Opening or creating different tables from different tables must com via sync.

  9. #9

    Default

    - Opening 1 table from different threads using 2 locators must come via lock
    Yes, because opening a table accesses the Scheme table.

    - Opening and reading 1 table via one locator from diff. threads must come via mutual lock
    Not necessary to be via 1 lock instance - the lock for table opening may be different from the lock for table reading.

    - Opening table and committing of the same table must come via mutual lock.
    Not necessary to be via 1 lock instance - the lock for table opening may be different from the lock for table committing. Table committing does not affect the Scheme table.

    - Opening or creating different tables from different threads must com via sync.
    Yes, because they accessed the Scheme table.
    Last edited by a.todorov; 16.02.2012 at 14:39. Reason: Clarification

  10. #10

    Default

    Thank you for notes,

    2 element - not sure, because 2 threads share one locator in this example. This is a very special case, I must rephrase it, locator must be open first (may be in class initialization), and then two parallel threads can read it via mutual lock. In this case this locator's cache will be filled with different elements for every thread and that's why read must be locked.

    3 - has to be investigated, I saw strange behavior in here. It's not about the scheme, but about writing last bytes into the table header by one locator (Commit) and parallel reading header, while opening second locator (Open new locator). Theoretically must work, will re-investigate.
    Last edited by blaze; 16.02.2012 at 13:36.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
2002 - 2014 STS Soft SC. All Rights reserved.
STSdb, Waterfall Tree and WTree are registered trademarks of STS Soft SC.