/* * Initializes the thread subsystem, creating various worker threads. * * nthreads Number of worker event handler threads to spawn * main_base Event base for main thread */ void thread_init(int nthr, struct event_base *main_base, void (*dispatcher_callback)(int, short, void *)) { int i; nthreads = nthr + 1; pthread_mutex_init(&stats_lock, NULL); pthread_mutex_init(&init_lock, NULL); pthread_cond_init(&init_cond, NULL); pthread_mutex_init(&cqi_freelist_lock, NULL); cqi_freelist = NULL; threads = calloc(nthreads, sizeof(LIBEVENT_THREAD)); if (! threads) { settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, "Can't allocate thread descriptors: %s", strerror(errno)); exit(1); } thread_ids = calloc(nthreads, sizeof(pthread_t)); if (! thread_ids) { perror("Can't allocate thread descriptors"); exit(1); } setup_dispatcher(main_base, dispatcher_callback); for (i = 0; i < nthreads; i++) { if (!create_notification_pipe(&threads[i])) { exit(1); } threads[i].index = i; setup_thread(&threads[i], i == (nthreads - 1)); } /* Create threads after we've done all the libevent setup. */ for (i = 0; i < nthreads; i++) { create_worker(worker_libevent, &threads[i], &thread_ids[i]); threads[i].thread_id = thread_ids[i]; } tap_thread = &threads[nthreads - 1]; /* Wait for all the threads to set themselves up before returning. */ pthread_mutex_lock(&init_lock); while (init_count < nthreads) { pthread_cond_wait(&init_cond, &init_lock); } pthread_mutex_unlock(&init_lock); }
int main (int argc, char *argv[]) { #if HAVE_GEOCLUE EmpathyLocationManager *location_manager = NULL; #endif EmpathyStatusIcon *icon; EmpathyDispatcher *dispatcher; TpAccountManager *account_manager; EmpathyLogManager *log_manager; EmpathyChatroomManager *chatroom_manager; EmpathyCallFactory *call_factory; EmpathyFTFactory *ft_factory; GtkWidget *window; EmpathyIdle *idle; EmpathyConnectivity *connectivity; GError *error = NULL; TpDBusDaemon *dbus_daemon; UniqueApp *unique_app; gboolean chatroom_manager_ready; GOptionContext *optcontext; GOptionEntry options[] = { { "no-connect", 'n', 0, G_OPTION_ARG_NONE, &no_connect, N_("Don't connect on startup"), NULL }, { "start-hidden", 'h', 0, G_OPTION_ARG_NONE, &start_hidden, N_("Don't display the contact list or any other dialogs on startup"), NULL }, { "accounts", 'a', 0, G_OPTION_ARG_NONE, &account_dialog_only, N_("Show the accounts dialog"), NULL }, { "version", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb, NULL, NULL }, { NULL } }; /* Init */ g_thread_init (NULL); empathy_init (); optcontext = g_option_context_new (N_("- Empathy IM Client")); g_option_context_add_group (optcontext, gst_init_get_option_group ()); g_option_context_add_group (optcontext, gtk_get_option_group (TRUE)); g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); if (!g_option_context_parse (optcontext, &argc, &argv, &error)) { g_print ("%s\nRun '%s --help' to see a full list of available command line options.\n", error->message, argv[0]); g_warning ("Error in empathy init: %s", error->message); return EXIT_FAILURE; } g_option_context_free (optcontext); empathy_gtk_init (); g_set_application_name (_(PACKAGE_NAME)); g_setenv ("PULSE_PROP_media.role", "phone", TRUE); #if HAVE_LIBCHAMPLAIN gtk_clutter_init (&argc, &argv); #endif gtk_window_set_default_icon_name ("empathy"); textdomain (GETTEXT_PACKAGE); #ifdef ENABLE_DEBUG /* Set up debugger */ g_log_set_default_handler (default_log_handler, NULL); #endif unique_app = unique_app_new_with_commands ("org.gnome.Empathy", NULL, "accounts_dialog", COMMAND_ACCOUNTS_DIALOG, NULL); if (unique_app_is_running (unique_app)) { unique_app_send_message (unique_app, account_dialog_only ? COMMAND_ACCOUNTS_DIALOG : UNIQUE_ACTIVATE, NULL); g_object_unref (unique_app); return EXIT_SUCCESS; } /* Take well-known name */ dbus_daemon = tp_dbus_daemon_dup (&error); if (error == NULL) { if (!tp_dbus_daemon_request_name (dbus_daemon, "org.gnome.Empathy", TRUE, &error)) { DEBUG ("Failed to request well-known name: %s", error ? error->message : "no message"); g_clear_error (&error); } g_object_unref (dbus_daemon); } else { DEBUG ("Failed to dup dbus daemon: %s", error ? error->message : "no message"); g_clear_error (&error); } if (account_dialog_only) { account_manager = tp_account_manager_dup (); show_accounts_ui (NULL, TRUE); gtk_main (); g_object_unref (account_manager); return 0; } notify_init (_(PACKAGE_NAME)); /* Setting up Idle */ idle = empathy_idle_dup_singleton (); empathy_idle_set_auto_away (idle, TRUE); /* Setting up Connectivity */ connectivity = empathy_connectivity_dup_singleton (); use_conn_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_CONN, connectivity); empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_CONN, use_conn_notify_cb, connectivity); /* account management */ account_manager = tp_account_manager_dup (); tp_account_manager_prepare_async (account_manager, NULL, account_manager_ready_cb, NULL); /* Handle channels */ dispatcher = setup_dispatcher (); g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL); migrate_config_to_xdg_dir (); /* Setting up UI */ window = empathy_main_window_show (); icon = empathy_status_icon_new (GTK_WINDOW (window), start_hidden); g_signal_connect (unique_app, "message-received", G_CALLBACK (unique_app_message_cb), window); /* Logging */ log_manager = empathy_log_manager_dup_singleton (); empathy_log_manager_observe (log_manager, dispatcher); chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL); empathy_chatroom_manager_observe (chatroom_manager, dispatcher); g_object_get (chatroom_manager, "ready", &chatroom_manager_ready, NULL); if (!chatroom_manager_ready) { g_signal_connect (G_OBJECT (chatroom_manager), "notify::ready", G_CALLBACK (chatroom_manager_ready_cb), account_manager); } else { chatroom_manager_ready_cb (chatroom_manager, NULL, account_manager); } /* Create the call factory */ call_factory = empathy_call_factory_initialise (); g_signal_connect (G_OBJECT (call_factory), "new-call-handler", G_CALLBACK (new_call_handler_cb), NULL); /* Create the FT factory */ ft_factory = empathy_ft_factory_dup_singleton (); g_signal_connect (ft_factory, "new-ft-handler", G_CALLBACK (new_ft_handler_cb), NULL); g_signal_connect (ft_factory, "new-incoming-transfer", G_CALLBACK (new_incoming_transfer_cb), NULL); /* Location mananger */ #if HAVE_GEOCLUE location_manager = empathy_location_manager_dup_singleton (); #endif gtk_main (); empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE); g_object_unref (idle); g_object_unref (connectivity); g_object_unref (icon); g_object_unref (account_manager); g_object_unref (log_manager); g_object_unref (dispatcher); g_object_unref (chatroom_manager); #if HAVE_GEOCLUE g_object_unref (location_manager); #endif g_object_unref (ft_factory); g_object_unref (unique_app); notify_uninit (); return EXIT_SUCCESS; }