myrocks proc init梳理

void native_procedure_init() {
  TABLE_LIST tables;
  MEM_ROOT mem;
  READ_RECORD read_record_info;
  TABLE *table;
  int error;
  DBUG_ENTER("native_procedure_init");

#ifdef HAVE_PSI_INTERFACE
  init_psi_keys();
#endif
  mysql_rwlock_init(key_THR_LOCK_np, &THR_LOCK_np);
  init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0);

  // Initialize THD (we don't have THD during server startup).
  THD *new_thd = new THD;
  if (!new_thd) {
    // NO_LINT_DEBUG
    sql_print_error("Can't allocate memory for native procedures");
    free_root(&mem, MYF(0));
    DBUG_VOID_RETURN;
  }

  new_thd->thread_stack = (char *)&new_thd;
  new_thd->store_globals();
  new_thd->set_db(system_db, sizeof(system_db) - 1);

  // Open mysql.native_proc table.
  tables.init_one_table(system_db, sizeof(system_db), system_table,
                        sizeof(system_table), system_table, TL_READ);
  if (open_and_lock_tables(new_thd, &tables, FALSE,
                           MYSQL_LOCK_IGNORE_TIMEOUT)) {
    // NO_LINT_DEBUG
    sql_print_error("Can't open the mysql.native_proc table. "
                    "Please run mysql_upgrade to create it.");
    goto exit;
  }

  // Read records in table.
  table = tables.table;
  if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 1, FALSE))
    goto exit;
  table->use_all_columns();
  while (!(error = read_record_info.read_record(&read_record_info))) {
    native_proc np;
    np.name = get_field(&mem, table->field[0]);
    np.dl = get_field(&mem, table->field[2]);
    DBUG_ASSERT(strcmp("native", get_field(&mem, table->field[1])) == 0);

    if (add_native_procedure(&np)) {
      // NO_LINT_DEBUG
      sql_print_error("Error adding native procedure: '%.64s'",
                      np.name.c_str());
    } else {
      DBUG_ASSERT(proc_map.count(np.name) > 0);
      proc_map[np.name].enabled = true;
    }
  }

  if (error > 0) {
    // NO_LINT_DEBUG
    sql_print_error("Got unknown error: %d", my_errno);
  }

  end_read_record(&read_record_info);
  // Force close to free memory.
  table->m_needs_reopen = TRUE;

exit:
  close_mysql_tables(new_thd);
  free_root(&mem, MYF(0));
  delete new_thd;
  my_pthread_setspecific_ptr(THR_THD, 0);
  DBUG_VOID_RETURN;
}

看源码 它是先从 system_table 中找相关符号 然后读取,之后做 add_native_procedure


static int add_native_procedure(native_proc *np) {
  void *dl = nullptr;
  bool dlclose_needed = false;

  if (proc_map.count(np->name) > 0) {
    my_error(ER_NP_PROCEDURE_EXISTS, MYF(0), np->name.c_str());
    return 1;
  }

  dl = search_dlhandle(np->dl);

  // If dlhandle not present, dlopen the shared object.
  if (dl == nullptr) {
    char dlpath[FN_REFLEN];
    strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", np->dl.c_str(),
             NullS);
    unpack_filename(dlpath, dlpath);

    if (!(dl = dlopen(dlpath, RTLD_NOW))) {
      const char *errmsg;
      int error_number = dlopen_errno;
      DLERROR_GENERATE(errmsg, error_number);

      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), np->dl.c_str(), error_number,
               errmsg);
      return 1;
    }
    dlclose_needed = true;
  }
  np->dlhandle = dl;

  // Lookup function pointer with dlsym.
  if (!(np->proc = (proc_t *)dlsym(np->dlhandle, np->name.c_str()))) {
    my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), np->name.c_str());
    if (dlclose_needed) {
      DBUG_ASSERT(dl);
      dlclose(dl);
    }
    return 1;
  }

  // Insert into proc_map.
  proc_map[np->name] = *np;

  return 0;
}


这里做了将 名字 和 函数做了关联 分别用了 dlopen(打开句柄),dlsym符号链接


猜你喜欢

转载自blog.csdn.net/qq948993066/article/details/78261089