~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_plugin.cc

  • Committer: Brian Aker
  • Date: 2009-03-25 18:35:47 UTC
  • mfrom: (962.1.6 merge)
  • Revision ID: brian@tangent.org-20090325183547-l79aiecte974hmx3
Merge in factoring out sql_plugin work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
128
128
   sub-structure (plugin->info).
129
129
*/
130
130
 
131
 
static bool initialized= 0;
 
131
static bool initialized= false;
132
132
 
133
133
static DYNAMIC_ARRAY plugin_dl_array;
134
134
static DYNAMIC_ARRAY plugin_array;
231
231
static void plugin_vars_free_values(sys_var *vars);
232
232
static void plugin_opt_set_limits(struct my_option *options,
233
233
                                  const struct st_mysql_sys_var *opt);
234
 
#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B)
235
 
#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B)
236
234
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin);
237
 
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
238
235
static void reap_plugins(void);
239
236
 
240
237
 
309
306
  for (i= 0; i < plugin_dl_array.elements; i++)
310
307
  {
311
308
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
312
 
    if (tmp->ref_count &&
313
 
        ! my_strnncoll(files_charset_info,
 
309
    if (! my_strnncoll(files_charset_info,
314
310
                       (const unsigned char *)dl->str, dl->length,
315
311
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
316
312
      return(tmp);
326
322
  for (i= 0; i < plugin_dl_array.elements; i++)
327
323
  {
328
324
    tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
329
 
    if (! tmp->ref_count)
330
325
    {
331
326
      memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
332
327
      return(tmp);
376
371
  /* If this dll is already loaded just increase ref_count. */
377
372
  if ((tmp= plugin_dl_find(dl)))
378
373
  {
379
 
    tmp->ref_count++;
380
374
    return(tmp);
381
375
  }
382
376
  memset(&plugin_dl, 0, sizeof(plugin_dl));
384
378
  dlpath.append(opt_plugin_dir);
385
379
  dlpath.append("/");
386
380
  dlpath.append(dl->str);
387
 
  plugin_dl.ref_count= 1;
388
381
  /* Open new dll handle */
389
382
  if (!(plugin_dl.handle= dlopen(dlpath.c_str(), RTLD_LAZY|RTLD_GLOBAL)))
390
383
  {
453
446
  {
454
447
    struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
455
448
                                               struct st_plugin_dl **);
456
 
    if (tmp->ref_count &&
457
 
        ! my_strnncoll(files_charset_info,
 
449
    if (! my_strnncoll(files_charset_info,
458
450
                       (const unsigned char *)dl->str, dl->length,
459
451
                       (const unsigned char *)tmp->dl.str, tmp->dl.length))
460
452
    {
461
453
      /* Do not remove this element, unless no other plugin uses this dll. */
462
 
      if (! --tmp->ref_count)
463
454
      {
464
455
        free_plugin_mem(tmp);
465
456
        memset(tmp, 0, sizeof(struct st_plugin_dl));
512
503
{
513
504
  st_plugin_int *pi= plugin_ref_to_int(rc);
514
505
 
 
506
  assert(pi);
 
507
  assert(rc);
 
508
 
515
509
  if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
516
510
  {
517
511
    plugin_ref plugin;
536
530
{
537
531
  LEX *lex= session ? session->lex : 0;
538
532
  plugin_ref rc;
539
 
  rc= my_intern_plugin_lock_ci(lex, *ptr);
 
533
  rc= intern_plugin_lock(lex, *ptr);
540
534
  return(rc);
541
535
}
542
536
 
552
546
    return(0);
553
547
 
554
548
  if ((plugin= registry.find(name, type)))
555
 
    rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin));
 
549
    rc= intern_plugin_lock(lex, plugin_int_to_ref(plugin));
556
550
  return(rc);
557
551
}
558
552
 
559
553
 
560
554
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
561
555
{
562
 
  uint32_t i;
563
556
  struct st_plugin_int *tmp;
564
 
  for (i= 0; i < plugin_array.elements; i++)
565
 
  {
566
 
    tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
567
 
    if (tmp->state == PLUGIN_IS_FREED)
568
 
    {
569
 
      memcpy(tmp, plugin, sizeof(struct st_plugin_int));
570
 
      return(tmp);
571
 
    }
572
 
  }
573
557
  if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
574
558
    return(0);
575
559
  tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
651
635
}
652
636
 
653
637
 
654
 
static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
 
638
static void plugin_deinitialize(struct st_plugin_int *plugin)
655
639
{
656
640
  if (plugin->plugin->status_vars)
657
641
  {
658
 
#ifdef FIX_LATER
659
 
    /*
660
 
      We have a problem right now where we can not prepend without
661
 
      breaking backwards compatibility. We will fix this shortly so
662
 
      that engines have "use names" and we wil use those for
663
 
      CREATE TABLE, and use the plugin name then for adding automatic
664
 
      variable names.
665
 
    */
666
 
    SHOW_VAR array[2]= {
667
 
      {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
668
 
      {0, 0, SHOW_UNDEF}
669
 
    };
670
 
    remove_status_vars(array);
671
 
#else
672
642
    remove_status_vars(plugin->plugin->status_vars);
673
 
#endif /* FIX_LATER */
674
643
  }
675
644
 
676
645
  if (plugin_type_deinitialize[plugin->plugin->type])
685
654
    plugin->plugin->deinit(plugin);
686
655
 
687
656
  plugin->state= PLUGIN_IS_UNINITIALIZED;
688
 
 
689
 
  /*
690
 
    We do the check here because NDB has a worker Session which doesn't
691
 
    exit until NDB is shut down.
692
 
  */
693
 
  if (ref_check && plugin->ref_count)
694
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after deinitialization."),
695
 
                    plugin->name.str, plugin->ref_count);
696
657
}
697
658
 
698
659
 
708
669
  mysql_del_sys_var_chain(plugin->system_vars);
709
670
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
710
671
  free_root(&plugin->mem_root, MYF(0));
711
 
  return;
712
672
}
713
673
 
714
674
static void reap_plugins(void)
717
677
  uint32_t idx;
718
678
  struct st_plugin_int *plugin;
719
679
 
720
 
  reap_needed= false;
721
680
  count= plugin_array.elements;
722
681
 
723
682
  for (idx= 0; idx < count; idx++)
724
683
  {
725
684
    plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
726
685
    plugin->state= PLUGIN_IS_DYING;
727
 
    plugin_deinitialize(plugin, true);
 
686
    plugin_deinitialize(plugin);
728
687
    plugin_del(plugin);
729
688
  }
730
689
}
731
690
 
732
 
static void intern_plugin_unlock(LEX *, plugin_ref plugin)
733
 
{
734
 
  st_plugin_int *pi;
735
 
 
736
 
  if (!plugin)
737
 
    return;
738
 
 
739
 
  pi= plugin_ref_to_int(plugin);
740
 
 
741
 
  free((void *) plugin);
742
 
 
743
 
  //assert(pi->ref_count);
744
 
  if (pi->ref_count > 0)
745
 
    pi->ref_count--;
746
 
 
747
 
  if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count)
748
 
    reap_needed= true;
749
 
 
750
 
  return;
751
 
}
752
 
 
753
 
 
754
 
void plugin_unlock(Session *session, plugin_ref plugin)
755
 
{
756
 
  LEX *lex= session ? session->lex : 0;
757
 
  if (!plugin)
758
 
    return;
759
 
  intern_plugin_unlock(lex, plugin);
760
 
  return;
761
 
}
762
 
 
763
 
 
764
 
void plugin_unlock_list(Session *session, plugin_ref *list, uint32_t count)
765
 
{
766
 
  LEX *lex= session ? session->lex : 0;
767
 
  assert(list);
768
 
  while (count--)
769
 
    intern_plugin_unlock(lex, *list++);
770
 
  return;
771
 
}
772
 
 
773
 
 
774
691
static int plugin_initialize(struct st_plugin_int *plugin)
775
692
{
776
693
  plugin->state= PLUGIN_IS_UNINITIALIZED;
913
830
      {
914
831
        assert(!global_system_variables.table_plugin);
915
832
        global_system_variables.table_plugin=
916
 
          my_intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
 
833
          intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr));
917
834
        assert(plugin_ptr->ref_count == 1);
918
835
      }
919
836
    }
943
860
      if (plugin_initialize(plugin_ptr))
944
861
      {
945
862
        plugin_ptr->state= PLUGIN_IS_DYING;
946
 
        plugin_deinitialize(plugin_ptr, true);
 
863
        plugin_deinitialize(plugin_ptr);
947
864
        plugin_del(plugin_ptr);
948
865
      }
949
866
    }
1070
987
 
1071
988
void plugin_shutdown(void)
1072
989
{
1073
 
  uint32_t idx, free_slots= 0;
 
990
  uint32_t idx;
1074
991
  size_t count= plugin_array.elements;
1075
 
  struct st_plugin_int *plugin;
1076
992
  vector<st_plugin_int *> plugins;
1077
993
  vector<st_plugin_dl *> dl;
1078
994
 
1080
996
  {
1081
997
    reap_needed= true;
1082
998
 
1083
 
    /*
1084
 
      We want to shut down plugins in a reasonable order, this will
1085
 
      become important when we have plugins which depend upon each other.
1086
 
      Circular references cannot be reaped so they are forced afterwards.
1087
 
      TODO: Have an additional step here to notify all active plugins that
1088
 
      shutdown is requested to allow plugins to deinitialize in parallel.
1089
 
    */
1090
 
    while (reap_needed && (count= plugin_array.elements))
1091
 
    {
1092
 
      reap_plugins();
1093
 
      for (idx= free_slots= 0; idx < count; idx++)
1094
 
      {
1095
 
        plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
1096
 
        switch (plugin->state) {
1097
 
        case PLUGIN_IS_READY:
1098
 
          plugin->state= PLUGIN_IS_DELETED;
1099
 
          reap_needed= true;
1100
 
          break;
1101
 
        case PLUGIN_IS_FREED:
1102
 
        case PLUGIN_IS_UNINITIALIZED:
1103
 
          free_slots++;
1104
 
          break;
1105
 
        }
1106
 
      }
1107
 
      if (!reap_needed)
1108
 
      {
1109
 
        /*
1110
 
          release any plugin references held.
1111
 
        */
1112
 
        unlock_variables(NULL, &global_system_variables);
1113
 
        unlock_variables(NULL, &max_system_variables);
1114
 
      }
1115
 
    }
1116
 
 
1117
 
    if (count > free_slots)
1118
 
      errmsg_printf(ERRMSG_LVL_WARN, _("Forcing shutdown of %"PRIu64" plugins"),
1119
 
                        (uint64_t)count - free_slots);
1120
 
 
1121
 
    plugins.reserve(count);
1122
 
 
1123
 
    /*
1124
 
      If we have any plugins which did not die cleanly, we force shutdown
1125
 
    */
1126
 
    for (idx= 0; idx < count; idx++)
1127
 
    {
1128
 
      plugins.push_back(*dynamic_element(&plugin_array, idx,
1129
 
                                         struct st_plugin_int **));
1130
 
      /* change the state to ensure no reaping races */
1131
 
      if (plugins[idx]->state == PLUGIN_IS_DELETED)
1132
 
        plugins[idx]->state= PLUGIN_IS_DYING;
1133
 
    }
1134
 
 
1135
 
    /*
1136
 
      We loop through all plugins and call deinit() if they have one.
1137
 
    */
1138
 
    for (idx= 0; idx < count; idx++)
1139
 
      if (!(plugins[idx]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
1140
 
      {
1141
 
        errmsg_printf(ERRMSG_LVL_INFO, _("Plugin '%s' will be forced to shutdown"),
1142
 
                              plugins[idx]->name.str);
1143
 
        /*
1144
 
          We are forcing deinit on plugins so we don't want to do a ref_count
1145
 
          check until we have processed all the plugins.
1146
 
        */
1147
 
        plugin_deinitialize(plugins[idx], false);
1148
 
      }
1149
 
 
1150
 
    /*
1151
 
      We defer checking ref_counts until after all plugins are deinitialized
1152
 
      as some may have worker threads holding on to plugin references.
1153
 
    */
1154
 
    for (idx= 0; idx < count; idx++)
1155
 
    {
1156
 
      if (plugins[idx]->ref_count)
1157
 
        errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has ref_count=%d after shutdown."),
1158
 
                        plugins[idx]->name.str, plugins[idx]->ref_count);
1159
 
      if (plugins[idx]->state & PLUGIN_IS_UNINITIALIZED)
1160
 
        plugin_del(plugins[idx]);
1161
 
    }
1162
 
 
1163
 
    /*
1164
 
      Now we can deallocate all memory.
1165
 
    */
 
999
    reap_plugins();
 
1000
    unlock_variables(NULL, &global_system_variables);
 
1001
    unlock_variables(NULL, &max_system_variables);
1166
1002
 
1167
1003
    cleanup_variables(NULL, &global_system_variables);
1168
1004
    cleanup_variables(NULL, &max_system_variables);
1169
1005
 
1170
1006
    initialized= 0;
1171
 
 
1172
1007
  }
1173
1008
 
1174
1009
  /* Dispose of the memory */
1188
1023
  free_root(&plugin_mem_root, MYF(0));
1189
1024
 
1190
1025
  global_variables_dynamic_size= 0;
1191
 
 
1192
 
  return;
1193
1026
}
1194
1027
 
1195
1028
/**
1569
1402
  {
1570
1403
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1571
1404
    LEX *lex= session ? session->lex : 0;
1572
 
    if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
 
1405
    if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
1573
1406
      var= NULL; /* failed to lock it, it must be uninstalling */
1574
1407
    else
1575
1408
    if (!(plugin_state(plugin) & PLUGIN_IS_READY))
1576
1409
    {
1577
 
      /* initialization not completed */
1578
1410
      var= NULL;
1579
 
      intern_plugin_unlock(lex, plugin);
1580
1411
    }
1581
1412
  }
1582
1413
  else
1869
1700
 
1870
1701
void plugin_sessionvar_init(Session *session)
1871
1702
{
1872
 
  plugin_ref old_table_plugin= session->variables.table_plugin;
1873
 
 
1874
1703
  session->variables.table_plugin= NULL;
1875
1704
  cleanup_variables(session, &session->variables);
1876
1705
 
1883
1712
  session->variables.dynamic_variables_ptr= 0;
1884
1713
 
1885
1714
  session->variables.table_plugin=
1886
 
        my_intern_plugin_lock(NULL, global_system_variables.table_plugin);
1887
 
  intern_plugin_unlock(NULL, old_table_plugin);
1888
 
  return;
 
1715
    intern_plugin_lock(NULL, global_system_variables.table_plugin);
1889
1716
}
1890
1717
 
1891
1718
 
1894
1721
*/
1895
1722
static void unlock_variables(Session *, struct system_variables *vars)
1896
1723
{
1897
 
  intern_plugin_unlock(NULL, vars->table_plugin);
1898
1724
  vars->table_plugin= NULL;
1899
1725
}
1900
1726