~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-10-24 19:39:04 UTC
  • mfrom: (1874.3.4 refactor)
  • Revision ID: brian@tangent.org-20101024193904-6c5a62rtd14bx9q4
Merge for "how do we make sure concurrent, are only concurrent"

Show diffs side-by-side

added added

removed removed

Lines of Context:
192
192
};
193
193
 
194
194
static UnusedTables unused_tables;
195
 
static int open_unireg_entry(Session *session,
196
 
                             Table *entry,
197
 
                             const char *alias,
198
 
                             TableIdentifier &identifier);
199
195
 
200
196
unsigned char *table_cache_key(const unsigned char *record,
201
197
                               size_t *length,
946
942
}
947
943
 
948
944
 
949
 
/*
950
 
  Open table which is already name-locked by this thread.
951
 
 
952
 
  SYNOPSIS
953
 
  reopen_name_locked_table()
954
 
  session         Thread handle
955
 
  table_list  TableList object for table to be open, TableList::table
956
 
  member should point to Table object which was used for
957
 
  name-locking.
958
 
  link_in     true  - if Table object for table to be opened should be
959
 
  linked into Session::open_tables list.
960
 
  false - placeholder used for name-locking is already in
961
 
  this list so we only need to preserve Table::next
962
 
  pointer.
963
 
 
964
 
  NOTE
965
 
  This function assumes that its caller already acquired LOCK_open mutex.
966
 
 
967
 
  RETURN VALUE
968
 
  false - Success
969
 
  true  - Error
970
 
*/
971
 
 
972
 
bool Session::reopen_name_locked_table(TableList* table_list)
973
 
{
974
 
  Table *table= table_list->table;
975
 
 
976
 
  safe_mutex_assert_owner(LOCK_open.native_handle());
977
 
 
978
 
  if (killed || not table)
979
 
    return true;
980
 
 
981
 
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
982
 
  if (open_unireg_entry(this, table, table_list->getTableName(), identifier))
983
 
  {
984
 
    table->intern_close_table();
985
 
    return true;
986
 
  }
987
 
 
988
 
  /*
989
 
    We want to prevent other connections from opening this table until end
990
 
    of statement as it is likely that modifications of table's metadata are
991
 
    not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
992
 
    or we might want to drop table if CREATE TABLE ... SELECT fails).
993
 
    This also allows us to assume that no other connection will sneak in
994
 
    before we will get table-level lock on this table.
995
 
  */
996
 
  table->getMutableShare()->resetVersion();
997
 
  table->in_use = this;
998
 
 
999
 
  table->tablenr= current_tablenr++;
1000
 
  table->used_fields= 0;
1001
 
  table->const_table= 0;
1002
 
  table->null_row= false;
1003
 
  table->maybe_null= false;
1004
 
  table->force_index= false;
1005
 
  table->status= STATUS_NO_RECORD;
1006
 
 
1007
 
  return false;
1008
 
}
1009
 
 
1010
 
 
1011
945
/**
1012
946
  Create and insert into table cache placeholder for table
1013
947
  which will prevent its opening (or creation) (a.k.a lock
1382
1316
            return NULL;
1383
1317
          }
1384
1318
 
1385
 
          error= open_unireg_entry(this, new_table, alias, identifier);
 
1319
          error= new_table->open_unireg_entry(this, alias, identifier);
1386
1320
          if (error != 0)
1387
1321
          {
1388
1322
            delete new_table;
1830
1764
  }
1831
1765
}
1832
1766
 
1833
 
/*
1834
 
  Load a table definition from cursor and open unireg table
1835
 
 
1836
 
  SYNOPSIS
1837
 
  open_unireg_entry()
1838
 
  session                       Thread handle
1839
 
  entry         Store open table definition here
1840
 
  table_list            TableList with db, table_name
1841
 
  alias         Alias name
1842
 
  cache_key             Key for share_cache
1843
 
  cache_key_length      length of cache_key
1844
 
 
1845
 
  NOTES
1846
 
  Extra argument for open is taken from session->open_options
1847
 
  One must have a lock on LOCK_open when calling this function
1848
 
 
1849
 
  RETURN
1850
 
  0     ok
1851
 
#       Error
1852
 
*/
1853
 
 
1854
 
static int open_unireg_entry(Session *session,
1855
 
                             Table *entry,
1856
 
                             const char *alias,
1857
 
                             TableIdentifier &identifier)
1858
 
{
1859
 
  int error;
1860
 
  TableSharePtr share;
1861
 
  uint32_t discover_retry_count= 0;
1862
 
 
1863
 
  safe_mutex_assert_owner(LOCK_open.native_handle());
1864
 
retry:
1865
 
  if (not (share= TableShare::getShareCreate(session,
1866
 
                                             identifier,
1867
 
                                             &error)))
1868
 
    return 1;
1869
 
 
1870
 
  while ((error= share->open_table_from_share(session,
1871
 
                                              identifier,
1872
 
                                              alias,
1873
 
                                              (uint32_t) (HA_OPEN_KEYFILE |
1874
 
                                                          HA_OPEN_RNDFILE |
1875
 
                                                          HA_GET_INDEX |
1876
 
                                                          HA_TRY_READ_ONLY),
1877
 
                                              session->open_options, *entry)))
1878
 
  {
1879
 
    if (error == 7)                             // Table def changed
1880
 
    {
1881
 
      share->resetVersion();                        // Mark share as old
1882
 
      if (discover_retry_count++)               // Retry once
1883
 
      {
1884
 
        TableShare::release(share);
1885
 
        return 1;
1886
 
      }
1887
 
 
1888
 
      /*
1889
 
        TODO->
1890
 
        Here we should wait until all threads has released the table.
1891
 
        For now we do one retry. This may cause a deadlock if there
1892
 
        is other threads waiting for other tables used by this thread.
1893
 
 
1894
 
        Proper fix would be to if the second retry failed:
1895
 
        - Mark that table def changed
1896
 
        - Return from open table
1897
 
        - Close all tables used by this thread
1898
 
        - Start waiting that the share is released
1899
 
        - Retry by opening all tables again
1900
 
      */
1901
 
 
1902
 
      /*
1903
 
        TO BE FIXED
1904
 
        To avoid deadlock, only wait for release if no one else is
1905
 
        using the share.
1906
 
      */
1907
 
      if (share->getTableCount() != 1)
1908
 
      {
1909
 
        TableShare::release(share);
1910
 
        return 1;
1911
 
      }
1912
 
      /* Free share and wait until it's released by all threads */
1913
 
      TableShare::release(share);
1914
 
 
1915
 
      if (!session->killed)
1916
 
      {
1917
 
        drizzle_reset_errors(session, 1);         // Clear warnings
1918
 
        session->clear_error();                 // Clear error message
1919
 
        goto retry;
1920
 
      }
1921
 
      return 1;
1922
 
    }
1923
 
 
1924
 
    TableShare::release(share);
1925
 
 
1926
 
    return 1;
1927
 
  }
1928
 
 
1929
 
  return 0;
1930
 
}
1931
 
 
1932
1767
 
1933
1768
/*
1934
1769
  Open all tables in list