• dbproxy-main函数


    main主函数

    /home/id/lua.lua
    /home/id/lua-c/lua.lua
    /home/id/lua-c/metatable.lua
    /home/id/lua-c/1.lua

     

    int main(int argc, char **argv) {
        return main_cmdline(argc, argv);
    }
    main_cmdline函数
    int main_cmdline(int argc, char **argv) {
        //设置底盘的选项
        opts = chassis_options_new();
        chassis_frontend_set_chassis_options(frontend, opts);
        main_entries = chassis_options_to_g_option_entries(opts);
    
        //srcchassis-keyfile.c
        chassis_keyfile_to_options(frontend->keyfile, "mysql-proxy", main_entries)
    
        //srcmysql-proxy-cli.c
        //得到用户输入的/usr/local/wm/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/wm/mysql-proxy/conf/source_wtf.cnf
        //中的defaults-file
        if (chassis_frontend_init_base_options(option_ctx, &argc, &argv, &(frontend->print_version), &(frontend->default_file), &gerr)) {
    
        }
    
        if (frontend->default_file) {
            if (!(frontend->keyfile = chassis_frontend_open_config_file(frontend->default_file, &gerr))) {
                g_log_dbproxy(g_critical, "loading config from '%s' failed: %s", frontend->default_file, gerr->message);
                exit;
            }
        }
        //得到defaults-file中的参数
        if (frontend->keyfile) {
            if (chassis_keyfile_to_options(frontend->keyfile, "mysql-proxy", main_entries)) {
                GOTO_EXIT(EXIT_FAILURE);
            }
        }
    
        //加载插件
        if (chassis_frontend_load_plugins(srv->modules, frontend->plugin_dir, frontend->plugin_names)) {
        
        }
    
        //初始化插件选项
        chassis_frontend_init_plugins(srv->modules, option_ctx, &argc, &argv, frontend->keyfile, "mysql-proxy", srv->base_dir, &gerr)) {
    
        }
        
        //启动多个线程, 并设置回调函数chassis_event_handle, 使用libevent
        if (chassis_mainloop(srv)) {
            /* looks like we failed */
            g_log_dbproxy(g_critical, "Failure from chassis_mainloop. Shutting down");
            exit;
        }
    }

     

    chassis_options_new
    位置:srcchassis-options.c

    /**
     * create a command-line option
     */
    chassis_options_t *chassis_options_new() {
        chassis_options_t *opt;
    
        opt = g_slice_new0(chassis_options_t);
    
        return opt;
    }

    chassis_frontend_set_chassis_options
    位置:srcmysql-proxy-cli.c

    /**
     * setup the options of the chassis
     */
    int chassis_frontend_set_chassis_options(chassis_frontend_t *frontend, chassis_options_t *opts) {
        chassis_options_add(opts, "verbose-shutdown", 0, 0, G_OPTION_ARG_NONE, &(frontend->verbose_shutdown), "Always log the exit code when shutting down", NULL, NULL, NULL, 0);
    }

    chassis_options_add
    位置:srcchassis-options.c

    int chassis_options_add(chassis_options_t *opts, 
            const char *long_name,
            gchar short_name,
            gint flags,
            GOptionArg arg,
            gpointer   arg_data,
            const char *description,
            const char *arg_description,
            chas_opt_assign_hook assign_hook,
            chas_opt_show_hook show_hook,
            gint opt_property) {
        chassis_option_t *opt;
    
        opt = chassis_option_new();
        if (0 != chassis_option_set(opt,
                long_name,
                short_name,
                flags,
                arg,
                arg_data,
                description,
                arg_description,
                assign_hook,
                show_hook,
                opt_property) ||
            0 != chassis_options_add_option(opts, opt)) {
            chassis_option_free(opt);
            return -1;
        } else {
            return 0;
        }
    }

    chassis_option_set
    位置:srcchassis-options.c

    /**
     * add a option
     *
     * GOptionEntry
     */
    int chassis_option_set(chassis_option_t *opt, 
            const char *long_name,
            gchar short_name,
            gint flags,
            GOptionArg arg,
            gpointer   arg_data,
            const char *description,
            const char *arg_description,
            chas_opt_assign_hook assign_hook,
            chas_opt_show_hook show_hook,
            gint opt_property) {
        opt->long_name       = g_strdup(long_name);
        opt->short_name      = short_name;
        opt->flags           = flags;
        opt->arg             = arg;
        opt->arg_data        = arg_data;
        opt->description     = g_strdup(description);
        opt->arg_description = g_strdup(arg_description);
        opt->assign_opts_hook = assign_hook;
        opt->show_hook       = show_hook;
        opt->opt_property    = opt_property;
    
        return 0;
    }

    chassis_options_add_option
    位置:srcchassis-options.c

    /**
     * add a option
     *
     * GOptionEntry
     */
    int chassis_options_add_option(chassis_options_t *opts, 
            chassis_option_t *opt) {
    
        opts->options = g_list_append(opts->options, opt);
    
        return 0;
    }

    chassis_options_to_g_option_entries
    位置:srcchassis-options.c

    /**
     * convert the chassis_options into a GOptionEntry
     *
     * @see chassis_options_free_g_option_entries
     */
    GOptionEntry *chassis_options_to_g_option_entries(chassis_options_t *opts) {
        GOptionEntry *entries;
        int count;
        GList *node;
    
        /* build the GOptionEntry block */
        for (node = opts->options, count = 0; node; node = node->next) {
            count++;
        }
    
        entries = g_new0(GOptionEntry, count + 1);
        for (node = opts->options, count = 0; node; node = node->next) {
            chassis_option_t *opt = node->data;
    
            entries[count].long_name       = g_strdup(opt->long_name);
            entries[count].short_name      = opt->short_name;
            entries[count].flags           = opt->flags;
            entries[count].arg             = opt->arg;
            entries[count].arg_data        = opt->arg_data;
            entries[count].description     = g_strdup(opt->description);
            entries[count].arg_description = g_strdup(opt->arg_description);
            count++;
        }
    
        entries[count].long_name       = NULL;
        entries[count].short_name      = 0;
        entries[count].flags           = 0;
        entries[count].arg             = 0;
        entries[count].arg_data        = NULL;
        entries[count].description     = NULL;
        entries[count].arg_description = NULL;
    
        return entries;
    }

    chassis_keyfile_to_options
    位置:srcchassis-keyfile.c

    int chassis_keyfile_to_options(GKeyFile* keyfile, const gchar *ini_group_name, GOptionEntry *config_entries) {
        GError *gerr = NULL;
        int ret = 0;
        int i, j;
        
        /* all the options are in the group for "mysql-proxy" */
    
        if (!keyfile) return -1;
        if (!g_key_file_has_group(keyfile, ini_group_name)) return 0;
    
        /* set the defaults */
        for (i = 0; config_entries[i].long_name; i++) {
            GOptionEntry *entry = &(config_entries[i]);
            gchar *arg_string;
            gchar **arg_string_array;
            gboolean arg_bool = 0;
            gint arg_int = 0;
            gdouble arg_double = 0;
            gsize len = 0;
    
            switch (entry->arg) {
            case G_OPTION_ARG_FILENAME:
            case G_OPTION_ARG_STRING: 
                /* is this option set already */
                if (NULL == entry->arg_data || NULL != *(gchar **)(entry->arg_data)) break;
    
                arg_string = g_key_file_get_string(keyfile, ini_group_name, entry->long_name, &gerr);
                if (!gerr) {
                    /* strip trailing spaces */
                    *(gchar **)(entry->arg_data) = g_strchomp(arg_string);
                }
                break;
            case G_OPTION_ARG_FILENAME_ARRAY:
            case G_OPTION_ARG_STRING_ARRAY: 
                /* is this option set already */
                if (NULL == entry->arg_data || NULL != *(gchar ***)(entry->arg_data)) break;
    
                arg_string_array = g_key_file_get_string_list(keyfile, ini_group_name, entry->long_name, &len, &gerr);
                if (!gerr) {
                    for (j = 0; arg_string_array[j]; j++) {
                        arg_string_array[j] = g_strstrip(arg_string_array[j]);
                    }   
                    *(gchar ***)(entry->arg_data) = arg_string_array;
                }
                break;
            case G_OPTION_ARG_NONE: 
                arg_bool = g_key_file_get_boolean(keyfile, ini_group_name, entry->long_name, &gerr);
                if (!gerr) {
                    *(int *)(entry->arg_data) = arg_bool;
                }
                break;
            case G_OPTION_ARG_INT: 
                arg_int = g_key_file_get_integer(keyfile, ini_group_name, entry->long_name, &gerr);
                if (!gerr) {
                    *(gint *)(entry->arg_data) = arg_int;
                }
                break;
    #if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 12 
            case G_OPTION_ARG_DOUBLE: 
                arg_double = g_key_file_get_double(keyfile, ini_group_name, entry->long_name, &gerr);
                if (!gerr) {
                    *(gdouble *)(entry->arg_data) = arg_double;
                }
                break;
    #endif
            default:
                g_log_dbproxy(g_error, "(keyfile) the option %d can't be handled", entry->arg);
                break;
            }
    
            if (gerr) {
                if (gerr->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) {
                    g_log_dbproxy(g_critical, "%s", gerr->message);
                    ret = -1;
                }
    
                g_error_free(gerr);
                gerr = NULL;
            }
        }
    
        return ret;
    }

    chassis_frontend_init_base_options
    位置:srcchassis-frontend.c

    int chassis_frontend_init_base_options(GOptionContext *option_ctx,
            int *argc_p, char ***argv_p,
            int *print_version,
            char **config_file,
            GError **gerr) {
        chassis_options_t *opts;
        GOptionEntry *base_main_entries;
        int ret = 0;
    
        opts = chassis_options_new();
        chassis_options_set_cmdline_only_options(opts, print_version, config_file);
        base_main_entries = chassis_options_to_g_option_entries(opts);
    
        g_option_context_add_main_entries(option_ctx, base_main_entries, NULL);
        g_option_context_set_help_enabled(option_ctx, FALSE);
        g_option_context_set_ignore_unknown_options(option_ctx, TRUE);
    
        if (FALSE == g_option_context_parse(option_ctx, argc_p, argv_p, gerr)) {
            ret = -1;
        }
    
        /* do not use chassis_options_free_g_options... here, we need to hang on to the data until the end of the program! */
        chassis_frontend_options_free(base_main_entries);
    
        chassis_options_free(opts);
    
        return ret;
    }

    chassis_options_set_cmdline_only_options
    位置: srcchassis-frontend.c

    /**
     * setup the options that can only appear on the command-line
     */
    int chassis_options_set_cmdline_only_options(chassis_options_t *opts,
            int *print_version,
            char **config_file) {
    
        chassis_options_add(opts,
            "version", 'V', 0, G_OPTION_ARG_NONE, print_version, "Show version", NULL, NULL, NULL, 0);
    
        chassis_options_add(opts,
            "defaults-file", 0, 0, G_OPTION_ARG_STRING, config_file, "configuration file", "<file>", NULL, NULL, 0);
    
        return 0;
    }

    chassis_frontend_init_plugins
    位置:srcchassis-frontend.c

    int chassis_frontend_init_plugins(GPtrArray *plugins,
            GOptionContext *option_ctx,
            int *argc_p, char ***argv_p,
            GKeyFile *keyfile,
            const char* keyfile_section_name,
            const char *base_dir,
            GError **gerr) {
        guint i;
    
        for (i = 0; i < plugins->len; i++) {
            GOptionEntry *config_entries = NULL;
            chassis_plugin *p = plugins->pdata[i];
            chassis_options_t *plugin_opts = NULL;
    
            if (NULL != (plugin_opts = chassis_plugin_get_options(p))) {
                gchar *group_desc = g_strdup_printf("%s-module", p->option_grp_name);
                gchar *help_msg = g_strdup_printf("Show options for the %s-module", p->option_grp_name);
                const gchar *group_name = p->option_grp_name;
    
                config_entries = chassis_options_to_g_option_entries(plugin_opts);
    
                GOptionGroup *option_grp = g_option_group_new(group_name, group_desc, help_msg, NULL, NULL);
                g_option_group_add_entries(option_grp, config_entries);
                g_option_context_add_group(option_ctx, option_grp);
    
                g_free(help_msg);
                g_free(group_desc);
    
                /* parse the new options */
                if (FALSE == g_option_context_parse(option_ctx, argc_p, argv_p, gerr)) {
                    return -1;
                }
        
                if (keyfile) {
                    if (chassis_keyfile_to_options(keyfile, keyfile_section_name, config_entries)) {
                        return -1;
                    }
                }
    
                /* resolve the path names for these config entries */
                chassis_keyfile_resolve_path(base_dir, config_entries); 
            }
    
            if (config_entries != NULL) {
                chassis_frontend_options_free(config_entries);
            }
        }
    
    
    
        return 0;
    }

    chassis_plugin_get_options
    位置:srcchassis-plugin.c

    chassis_options_t* chassis_plugin_get_options(chassis_plugin *p) {
        chassis_options_t * options;
    
        if (!p->get_options) return NULL;
    
        if (NULL == (options = p->get_options(p->config))) {
            g_log_dbproxy(g_critical, "adding config options for module '%s' failed", p->name);
        }
    
        return options;
    }

    chassis_frontend_load_plugins
    位置srcchassis-frontend.c

    int chassis_frontend_load_plugins(GPtrArray *plugins, const gchar *plugin_dir, gchar **plugin_names) {
        int i;
    
        /* load the plugins */
        for (i = 0; plugin_names && plugin_names[i]; i++) {
            chassis_plugin *p;
    
            char *plugin_filename;
            /* skip trying to load a plugin when the parameter was --plugins= 
               that will never work...
            */
            if (!g_strcmp0("", plugin_names[i])) {
                continue;
            }
    
            plugin_filename = g_strdup_printf("%s%c%s%s.%s", 
                    plugin_dir, 
                    G_DIR_SEPARATOR, 
                    G_MODULE_PREFIX,
                    plugin_names[i],
                    SHARED_LIBRARY_SUFFIX);
    
            p = chassis_plugin_load(plugin_filename);
            g_free(plugin_filename);
    
            if (NULL == p) {
                g_log_dbproxy(g_critical, "setting --plugin-dir=<dir> might help");
                return -1;
            }
            p->option_grp_name = g_strdup(plugin_names[i]);
    
            g_ptr_array_add(plugins, p);
        }
        return 0;
    }

    chassis_plugin_load
    位置:srcchassis-plugin.c

    chassis_plugin* chassis_plugin_load(const gchar *name) {
        int (*plugin_init)(chassis_plugin *p);
        chassis_plugin *p = chassis_plugin_new();
    
        p->module = g_module_open(name, G_MODULE_BIND_LOCAL);
    
        if (!p->module) {
            g_log_dbproxy(g_critical, "loading module '%s' failed: %s", name, g_module_error());
    
            chassis_plugin_free(p);
    
            return NULL;
        }
    
        /* each module has to have a plugin_init function */
        if (!g_module_symbol(p->module, "plugin_init", (gpointer) &plugin_init)) {
            g_log_dbproxy(g_critical, "module '%s' doesn't have a init-function: %s", name, g_module_error());
            chassis_plugin_free(p);
            return NULL;
        }
    
        if (0 != plugin_init(p)) {
            g_log_dbproxy(g_critical, "init-function for module '%s' failed", name);
            chassis_plugin_free(p);
            return NULL;
        }
    
        if (p->magic != CHASSIS_PLUGIN_MAGIC) {
            g_log_dbproxy(g_critical, "plugin '%s' doesn't match the current plugin interface (plugin is %lx, chassis is %lx)", name, p->magic, CHASSIS_PLUGIN_MAGIC);
            chassis_plugin_free(p);
            return NULL;
        }
    
        if (p->init) {
            p->config = p->init();
        }
    
        /* if the plugins haven't set p->name provide our own name */
        if (!p->name) p->name = g_strdup(name);
        /* set dummy version number if the plugin doesn't provide a real one */
        if (!p->version) {
            g_log_dbproxy(g_critical, "plugin '%s' doesn't set a version number, refusing to load this plugin", name);
            chassis_plugin_free(p);
            return NULL;
        }
        
        if (p->new_stats) {
            p->stats = p->new_stats();
        }
    
        return p;
    }

    plugin_init
    位置:pluginsproxyproxy-plugin.c

    G_MODULE_EXPORT int plugin_init(chassis_plugin *p) {
        p->magic        = CHASSIS_PLUGIN_MAGIC;
        p->name         = g_strdup("proxy");
        p->version  = g_strdup(PACKAGE_VERSION);
    
        p->init         = network_mysqld_proxy_plugin_new;
        p->get_options  = network_mysqld_proxy_plugin_get_options;
        p->apply_config = network_mysqld_proxy_plugin_apply_config;
        p->destroy      = network_mysqld_proxy_plugin_free;
    
        return 0;
    }

    network_mysqld_proxy_plugin_new
    位置:pluginsproxyproxy-plugin.c

    //全局变量
    chassis_plugin_config *config = NULL;
    
    chassis_plugin_config * network_mysqld_proxy_plugin_new(void) {
        config = g_new0(chassis_plugin_config, 1);
    
        config->fix_bug_25371   = 0; /** double ERR packet on AUTH failures */
        config->profiling       = 1;
        config->start_proxy     = 1;
        config->pool_change_user = 1; /* issue a COM_CHANGE_USER to cleanup the connection 
                         when we get back the connection from the pool */
        config->dt_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)dt_table_free);
    
        config->select_where_limit_str = NULL;
        config->select_where_limit = SEL_OFF;
        config->charset = NULL;
    
        config->opts = NULL;
    
        config->percentile_value = 64;
    
        config->check_state_conn_timeout = 3;
        config->check_state_interval = PROXY_CHECK_STATE_WAIT_TIMEOUT;
        config->check_state_retry_times = RETRY_TIMES;
        config->check_state_sleep_delay = SLEEP_DELAY;
        g_rw_lock_init(&config->config_lock);
    
        config->sql_log_mgr = sql_log_t_new();
        config->percentile_controller = pt_percentile_new(6.0, 29.0, 2);
    
        config->plugin_threads = g_hash_table_new_full(g_str_hash,
                                             g_str_equal,
                                             g_free,
                                             (GDestroyNotify)plugin_thread_t_free);
        config->table_prefix = NULL;
        config->table_suffix = NULL;
        config->tnw = tbl_name_wrap_new();
    
        return config;
    }

    network_mysqld_proxy_plugin_get_options
    位置:pluginsproxyproxy-plugin.c

    设置插件的选项
    我们更改的id-generate 就在这里
    需要在
    
    1)config增加新的属性id-generate
    ./plugins/proxy/proxy-plugin.h
    struct chassis_plugin_config {
        ...
        gchar* id_generate;
    };
    2)初始化
    ./plugins/proxy/proxy-plugin.c
    chassis_plugin_config * network_mysqld_proxy_plugin_new(void) {
        ...
        config->id_generate = NULL;
        return config;
    }
    static chassis_options_t * network_mysqld_proxy_plugin_get_options(chassis_plugin_config *oldconfig) {
        if (config->opts == NULL) {
            chassis_options_t *opts = chassis_options_new();
    
            chassis_options_add(opts, "proxy-address",            'P', 0, G_OPTION_ARG_STRING, &(config->address), "listening address:port of the proxy-server (default: :4040)", "<host:port>",
                                NULL, show_proxy_address, SHOW_OPTS_PROPERTY);
        chassis_options_add(opts, "id-generate", 0, 0, G_OPTION_ARG_STRING, &(config->id_generate), "Run mysql-proxy as user", NULL, NULL, NULL, 0);
        
         config->opts = opts;
        }
            
        return config->opts;
    }

    chassis_mainloop
    位置:srcchassis-mainloop.c

    int chassis_mainloop(void *_chas) {
        chassis *chas = _chas;
        guint i;
        struct event ev_sigterm, ev_sigint;
    #ifdef SIGHUP
        struct event ev_sighup;
    #endif
        chassis_event_thread_t *mainloop_thread;
    
        /* redirect logging from libevent to glib */
        event_set_log_callback(event_log_use_glib);
    
    
        /* add a event-handler for the "main" events */
        mainloop_thread = chassis_event_thread_new(0);
        chassis_event_threads_init_thread(mainloop_thread, chas);
        g_ptr_array_add(chas->threads, mainloop_thread);
    
        chas->event_base = mainloop_thread->event_base; /* all global events go to the 1st thread */
    
        g_assert(chas->event_base);
    
    
        /* setup all plugins all plugins */
        for (i = 0; i < chas->modules->len; i++) {
            chassis_plugin *p = chas->modules->pdata[i];
    
            g_assert(p->apply_config);
            if (0 != p->apply_config(chas, p->config)) {
                g_log_dbproxy(g_critical, "applying config of plugin %s failed", p->name);
                return -1;
            }
        }
    
        signal_set(&ev_sigterm, SIGTERM, sigterm_handler, NULL);
        event_base_set(chas->event_base, &ev_sigterm);
        signal_add(&ev_sigterm, NULL);
    
        signal_set(&ev_sigint, SIGINT, sigint_handler, NULL);
        event_base_set(chas->event_base, &ev_sigint);
        signal_add(&ev_sigint, NULL);
    
    #ifdef SIGHUP
        signal_set(&ev_sighup, SIGHUP, sighup_handler, chas);
        event_base_set(chas->event_base, &ev_sighup);
        if (signal_add(&ev_sighup, NULL)) {
            g_log_dbproxy(g_critical, "signal_add(SIGHUP) failed");
        }
    #endif
    
        if (chas->event_thread_count < 1) chas->event_thread_count = 1;
    
        /* create the event-threads
         *
         * - dup the async-queue-ping-fds
         * - setup the events notification
         * */
        for (i = 1; i <= (guint)chas->event_thread_count; i++) { /* we already have 1 event-thread running, the main-thread */
            chassis_event_thread_t *thread = chassis_event_thread_new(i);
    
            chassis_event_threads_init_thread(thread, chas);
    
            g_ptr_array_add(chas->threads, thread);
        }
    
        /* start the event threads */
        chassis_event_threads_start(chas->threads);
    
        /**
         * handle signals and all basic events into the main-thread
         *
         * block until we are asked to shutdown
         */
        chassis_mainloop_thread_loop(mainloop_thread);
    
        signal_del(&ev_sigterm);
        signal_del(&ev_sigint);
    #ifdef SIGHUP
        signal_del(&ev_sighup);
    #endif
        return 0;
    }

    chassis_event_thread_new
    位置:srcchassis-event-thread.c

    /**
     * create the data structure for a new event-thread
     */
    chassis_event_thread_t* chassis_event_thread_new(guint index) {
        chassis_event_thread_t *thread = g_new0(chassis_event_thread_t, 1);
    
        thread->index = index;
    
        thread->event_queue = g_async_queue_new();
    
        g_rw_lock_init(&thread->connection_lock);
        thread->connection_list = NULL;
    
        thread->exit_phase = EVENT_THREAD_NORMAL;
        return thread;
    }

    chassis_event_threads_init_thread
    位置:srcchassis-event-thread.c

    /**
     * setup the notification-fd of a event-thread
     *
     * all event-threads listen on the same notification pipe
     *
     * @see chassis_event_handle()
     */ 
    int chassis_event_threads_init_thread(chassis_event_thread_t *thread, chassis *chas) {
        thread->event_base = event_base_new();
        thread->chas = chas;
    
        int fds[2];
        if (pipe(fds)) {
            int err;
            err = errno;
            g_log_dbproxy(g_error, "evutil_socketpair() failed: %s (%d)",  g_strerror(err), err);
        }
        thread->notify_receive_fd = fds[0];
        thread->notify_send_fd = fds[1];
    
        event_set(&(thread->notify_fd_event), thread->notify_receive_fd, EV_READ | EV_PERSIST, chassis_event_handle, thread);
        event_base_set(thread->event_base, &(thread->notify_fd_event));
        event_add(&(thread->notify_fd_event), NULL);
    
        return 0;
    }

    chassis_event_threads_start
    位置:srcchassis-event-thread.c

    /**
     * start all the event-threads 
     *
     * starts all the event-threads that got added by chassis_event_threads_add()
     *
     * @see chassis_event_threads_add
     */
    void chassis_event_threads_start(GPtrArray *threads) {
        guint i;
    
        g_log_dbproxy(g_message, "starting %d threads", threads->len - 1);
    
        for (i = 1; i < threads->len; i++) { /* the 1st is the main-thread and already set up */
            chassis_event_thread_t *thread = threads->pdata[i];
            GError *gerr = NULL;
    
            thread->thr = g_thread_try_new("event thread", (GThreadFunc)chassis_event_thread_loop, thread, &gerr);
            if (gerr) {
                g_log_dbproxy(g_critical, "%s", gerr->message);
                g_error_free(gerr);
                gerr = NULL;
            }
        }
    }

    chassis_mainloop_thread_loop
    位置:srcchassis-event-thread.c

    /**
     * event-handler thread
     *
     */
    void* chassis_mainloop_thread_loop(chassis_event_thread_t *thread) {
        cur_thid = thread->index;
        gboolean is_all_work_thread_exit = FALSE;
        g_assert(thread->index == 0);
    
        /**
         * check once a second if we shall shutdown the proxy
         */
        while (!chassis_is_shutdown() || !is_all_work_thread_exit) {
            struct timeval timeout;
            int r;
    
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;
    
            g_assert(event_base_loopexit(thread->event_base, &timeout) == 0);
    
            r = event_base_dispatch(thread->event_base);
    
            if (r == -1) {
                if (errno == EINTR) continue;
                g_log_dbproxy(g_critical, "leaving chassis_event_thread_loop early, errno != EINTR was: %s (%d)", g_strerror(errno), errno);
                break;
            }
    
            if (chassis_is_shutdown()) {
                    gint i = 1;
                    for (; i < thread->chas->threads->len; i++) {
                        chassis_event_thread_t *event_thread = g_ptr_array_index(thread->chas->threads, i);
                        if (g_atomic_int_get(&event_thread->exit_phase) != EVENT_THREAD_EXITED) break;
                    }
                    if (i == thread->chas->threads->len) {
                        is_all_work_thread_exit = TRUE;
                    }
                }
        }
    
        g_log_dbproxy(g_message, "main loop thread will exit");
    
        return NULL;
    }
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/taek/p/8344960.html
Copyright © 2020-2023  润新知