~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/module/loader.cc

  • Committer: Andrew Hutchings
  • Date: 2010-09-08 19:03:09 UTC
  • mfrom: (1750 staging)
  • mto: (1750.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1751.
  • Revision ID: andrew@linuxjedi.co.uk-20100908190309-mya1nu7xvo1fpvk8
Merge trunk into branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <boost/program_options.hpp>
28
28
 
29
29
#include "drizzled/option.h"
30
 
#include "drizzled/my_hash.h"
31
30
#include "drizzled/internal/m_string.h"
32
31
 
33
32
#include "drizzled/plugin.h"
80
79
const char *opt_plugin_load_default= PANDORA_PLUGIN_LIST;
81
80
const char *builtin_plugins= PANDORA_BUILTIN_LIST;
82
81
 
 
82
extern bool opt_print_defaults;
 
83
 
83
84
/* Note that 'int version' must be the first field of every plugin
84
85
   sub-structure (plugin->info).
85
86
*/
95
96
*/
96
97
static memory::Root plugin_mem_root(4096);
97
98
static uint32_t global_variables_dynamic_size= 0;
98
 
static HASH bookmark_hash;
99
99
 
100
100
 
101
101
/*
107
107
  Item *item;
108
108
};
109
109
 
110
 
 
111
 
/*
112
 
  stored in bookmark_hash, this structure is never removed from the
113
 
  hash and is used to mark a single offset for a session local variable
114
 
  even if plugins have been uninstalled and reinstalled, repeatedly.
115
 
  This structure is allocated from plugin_mem_root.
116
 
 
117
 
  The key format is as follows:
118
 
    1 byte         - variable type code
119
 
    name_len bytes - variable name
120
 
    '\0'           - end of key
121
 
*/
122
 
struct st_bookmark
 
110
class Bookmark
123
111
{
124
 
  uint32_t name_len;
 
112
public:
 
113
  Bookmark() :
 
114
    type_code(0),
 
115
    offset(0),
 
116
    version(0),
 
117
    key("")
 
118
  {}
 
119
  uint8_t type_code;
125
120
  int offset;
126
121
  uint32_t version;
127
 
  char key[1];
 
122
  string key;
128
123
};
129
124
 
 
125
typedef boost::unordered_map<string, Bookmark> bookmark_unordered_map;
 
126
static bookmark_unordered_map bookmark_hash;
 
127
 
130
128
 
131
129
/*
132
130
  sys_var class for access to all plugin variables visible to the user
363
361
}
364
362
 
365
363
 
366
 
static unsigned char *get_bookmark_hash_key(const unsigned char *buff,
367
 
                                            size_t *length, bool)
368
 
{
369
 
  struct st_bookmark *var= (st_bookmark *)buff;
370
 
  *length= var->name_len + 1;
371
 
  return (unsigned char*) var->key;
372
 
}
373
 
 
374
 
 
375
364
/*
376
365
  The logic is that we first load and initialize all compiled in plugins.
377
366
  From there we load up the dynamic types (assuming we have not been told to
388
377
  if (initialized)
389
378
    return false;
390
379
 
391
 
  if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
392
 
                  get_bookmark_hash_key, NULL, HASH_UNIQUE))
393
 
  {
394
 
    tmp_root.free_root(MYF(0));
395
 
    return true;
396
 
  }
397
 
 
398
 
 
399
380
  initialized= 1;
400
381
 
401
382
  vector<string> builtin_list;
472
453
      plugin_initialize_vars(module);
473
454
 
474
455
      if (plugin_initialize(registry, module))
 
456
      {
 
457
        registry.remove(module);
475
458
        delete_module(module);
 
459
      }
476
460
    }
477
461
  }
478
462
}
567
551
  }
568
552
 
569
553
  /* Dispose of the memory */
570
 
 
571
 
  hash_free(&bookmark_hash);
572
554
  plugin_mem_root.free_root(MYF(0));
573
555
 
574
556
  global_variables_dynamic_size= 0;
805
787
  return(var);
806
788
}
807
789
 
808
 
static const string make_bookmark_name(const string &plugin, const char *name, int flags)
 
790
static const string make_bookmark_name(const string &plugin, const char *name)
809
791
{
810
 
  /* Embed the flags into the first char of the string */
811
 
  string varname(1, static_cast<char>(flags & PLUGIN_VAR_TYPEMASK));
812
 
  varname.append(plugin);
 
792
  string varname(plugin);
813
793
  varname.push_back('_');
814
794
  varname.append(name);
815
795
 
828
808
  Returns the 'bookmark' for the named variable.
829
809
  LOCK_system_variables_hash should be at least read locked
830
810
*/
831
 
static st_bookmark *find_bookmark(const string &plugin, const char *name, int flags)
 
811
static Bookmark *find_bookmark(const string &plugin, const char *name, int flags)
832
812
{
833
 
  st_bookmark *result= NULL;
834
 
 
835
813
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
836
814
    return NULL;
837
815
 
838
 
  const string varname(make_bookmark_name(plugin, name, flags));
839
 
 
840
 
 
841
 
  result= (st_bookmark*) hash_search(&bookmark_hash,
842
 
                                     (const unsigned char*) varname.c_str(), varname.size() - 1);
843
 
 
844
 
  return result;
 
816
  const string varname(make_bookmark_name(plugin, name));
 
817
 
 
818
  bookmark_unordered_map::iterator iter= bookmark_hash.find(varname);
 
819
  if (iter != bookmark_hash.end())
 
820
  {
 
821
    return &((*iter).second);
 
822
  }
 
823
  return NULL;
845
824
}
846
825
 
847
826
 
850
829
  returns null for non session-local variables.
851
830
  Requires that a write lock is obtained on LOCK_system_variables_hash
852
831
*/
853
 
static st_bookmark *register_var(const string &plugin, const char *name,
 
832
static Bookmark *register_var(const string &plugin, const char *name,
854
833
                                 int flags)
855
834
{
856
835
  if (!(flags & PLUGIN_VAR_SessionLOCAL))
857
836
    return NULL;
858
837
 
859
838
  uint32_t size= 0, offset, new_size;
860
 
  st_bookmark *result;
 
839
  Bookmark *result= NULL;
861
840
 
862
841
  switch (flags & PLUGIN_VAR_TYPEMASK) {
863
842
  case PLUGIN_VAR_BOOL:
883
862
 
884
863
  if (!(result= find_bookmark(plugin, name, flags)))
885
864
  {
886
 
    const string varname(make_bookmark_name(plugin, name, flags));
 
865
    const string varname(make_bookmark_name(plugin, name));
887
866
 
888
 
    result= static_cast<st_bookmark*>(plugin_mem_root.alloc_root(sizeof(struct st_bookmark) + varname.size() + 1));
889
 
    memset(result->key, 0, varname.size()+1);
890
 
    memcpy(result->key, varname.c_str(), varname.size());
891
 
    result->name_len= varname.size() - 2;
892
 
    result->offset= -1;
 
867
    Bookmark new_bookmark;
 
868
    new_bookmark.key= varname;
 
869
    new_bookmark.offset= -1;
893
870
 
894
871
    assert(size && !(size & (size-1))); /* must be power of 2 */
895
872
 
896
873
    offset= global_system_variables.dynamic_variables_size;
897
874
    offset= (offset + size - 1) & ~(size - 1);
898
 
    result->offset= (int) offset;
 
875
    new_bookmark.offset= (int) offset;
899
876
 
900
877
    new_size= (offset + size + 63) & ~63;
901
878
 
935
912
    global_system_variables.dynamic_variables_version++;
936
913
    max_system_variables.dynamic_variables_version++;
937
914
 
938
 
    result->version= global_system_variables.dynamic_variables_version;
 
915
    new_bookmark.version= global_system_variables.dynamic_variables_version;
 
916
    new_bookmark.type_code= flags;
939
917
 
940
918
    /* this should succeed because we have already checked if a dup exists */
941
 
    if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
942
 
    {
943
 
      fprintf(stderr, "failed to add placeholder to hash");
944
 
      assert(0);
945
 
    }
 
919
    bookmark_hash.insert(make_pair(varname, new_bookmark));
 
920
    result= find_bookmark(plugin, name, flags);
946
921
  }
947
922
  return result;
948
923
}
968
943
  if (!session->variables.dynamic_variables_ptr ||
969
944
      (uint32_t)offset > session->variables.dynamic_variables_head)
970
945
  {
971
 
    uint32_t idx;
972
 
 
973
946
    char *tmpptr= NULL;
974
947
    if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
975
948
                                  global_variables_dynamic_size)))
992
965
      now we need to iterate through any newly copied 'defaults'
993
966
      and if it is a string type with MEMALLOC flag, we need to strdup
994
967
    */
995
 
    for (idx= 0; idx < bookmark_hash.records; idx++)
 
968
    bookmark_unordered_map::iterator iter= bookmark_hash.begin();
 
969
    for (; iter != bookmark_hash.end() ; ++iter)
996
970
    {
997
971
      sys_var_pluginvar *pi;
998
972
      sys_var *var;
999
 
      st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
 
973
      const Bookmark &v= (*iter).second;
 
974
      const string var_name((*iter).first);
1000
975
 
1001
 
      if (v->version <= session->variables.dynamic_variables_version ||
1002
 
          !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
 
976
      if (v.version <= session->variables.dynamic_variables_version ||
 
977
          !(var= intern_find_sys_var(var_name.c_str(), var_name.size(), true)) ||
1003
978
          !(pi= var->cast_pluginvar()) ||
1004
 
          v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
 
979
          v.type_code != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1005
980
        continue;
1006
981
 
1007
982
      /* Here we do anything special that may be required of the data types */
1091
1066
*/
1092
1067
static void cleanup_variables(Session *session, struct system_variables *vars)
1093
1068
{
1094
 
  st_bookmark *v;
1095
1069
  sys_var_pluginvar *pivar;
1096
1070
  sys_var *var;
1097
1071
  int flags;
1098
1072
 
1099
 
  for (uint32_t idx= 0; idx < bookmark_hash.records; idx++)
 
1073
  bookmark_unordered_map::iterator iter= bookmark_hash.begin();
 
1074
  for (; iter != bookmark_hash.end() ; ++iter)
1100
1075
  {
1101
 
    v= (st_bookmark*) hash_element(&bookmark_hash, idx);
1102
 
    if (v->version > vars->dynamic_variables_version ||
1103
 
        !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
 
1076
    const Bookmark &v= (*iter).second;
 
1077
    const string key_name((*iter).first);
 
1078
    if (v.version > vars->dynamic_variables_version ||
 
1079
        !(var= intern_find_sys_var(key_name.c_str(), key_name.size(), true)) ||
1104
1080
        !(pivar= var->cast_pluginvar()) ||
1105
 
        v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
 
1081
        v.type_code != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1106
1082
      continue;
1107
1083
 
1108
1084
    flags= pivar->plugin_var->flags;
1439
1415
  char *optname, *p;
1440
1416
  int index= 0, offset= 0;
1441
1417
  drizzle_sys_var *opt, **plugin_option;
1442
 
  st_bookmark *v;
 
1418
  Bookmark *v;
1443
1419
 
1444
1420
  string name(plugin_name);
1445
1421
  transform(name.begin(), name.end(), name.begin(), ::tolower);
1569
1545
      if (opt->flags & PLUGIN_VAR_NOCMDOPT)
1570
1546
        continue;
1571
1547
 
1572
 
      optname= (char*) mem_root->memdup_root(v->key + 1, (optnamelen= v->name_len) + 1);
 
1548
      optname= (char*) mem_root->memdup_root(v->key.c_str(), (optnamelen= v->key.size()) + 1);
1573
1549
    }
1574
1550
 
1575
1551
    /* convert '_' to '-' */
1656
1632
  option *opts= NULL;
1657
1633
  int error;
1658
1634
  drizzle_sys_var *o;
1659
 
  struct st_bookmark *var;
 
1635
  Bookmark *var;
1660
1636
  uint32_t len, count= EXTRA_OPTIONS;
1661
1637
 
1662
1638
  if (test_module->getManifest().init_options != NULL)
1721
1697
 
1722
1698
      if ((var= find_bookmark(test_module->getName(), o->name, o->flags)))
1723
1699
      {
1724
 
        v= new sys_var_pluginvar(var->key + 1, o);
 
1700
        v= new sys_var_pluginvar(var->key.c_str(), o);
1725
1701
      }
1726
1702
      else
1727
1703
      {
1846
1822
  /* main_options now points to the empty option terminator */
1847
1823
  all_options.push_back(*main_options);
1848
1824
 
1849
 
  my_print_help(&*(all_options.begin()));
1850
 
  cout << long_options << endl;
1851
 
  my_print_variables(&*(all_options.begin()));
 
1825
  if (!opt_print_defaults)
 
1826
  {
 
1827
    my_print_help(&*(all_options.begin()));
 
1828
    cout << long_options << endl;
 
1829
  }
 
1830
  else
 
1831
  {
 
1832
    my_print_variables(&*(all_options.begin()));
 
1833
  }
1852
1834
 
1853
1835
  mem_root.free_root(MYF(0));
1854
1836
}