After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 388304 - [Win32] Create widget dynamically in a gthread
[Win32] Create widget dynamically in a gthread
Status: RESOLVED DUPLICATE of bug 60620
Product: gtk+
Classification: Platform
Component: Backend: Win32
2.8.x
Other All
: Normal critical
: ---
Assigned To: gtk-win32 maintainers
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2006-12-21 15:54 UTC by Boris Brugevin
Modified: 2006-12-21 18:55 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Boris Brugevin 2006-12-21 15:54:36 UTC
Steps to reproduce:
1. Create a notebook with textview and treeview, a gthread
2. in the thread create new page for notebook with textview and treeview in
3. The programm crash in win32 (maybe the mutex of gtk_thread)


Stack trace:
/*
 * Compile with:
 *
 * @g++ -Wall -o gtk-thread main.cpp `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
 *
 *
 */

#ifndef __linux__
	#pragma comment(lib, "gtk-win32-2.0.lib")
	#pragma comment(lib, "gdk-win32-2.0.lib")
	#pragma comment(lib, "glib-2.0.lib")
	#pragma comment(lib, "gobject-2.0.lib")
	#pragma comment(lib, "gthread-2.0.lib")
#endif

#include <iostream>
#ifndef __linux__
	#include <windows.h>
#endif
#include <gtk/gtk.h>
#include <glib/gprintf.h>

typedef struct
{
  GtkWidget *noteBook;
} WidgetNoteBook;

void addPage(GtkWidget * notebook, const char *name);

/* enter GTK thread lock */
inline void enter() {  gdk_threads_enter(); };
/* release GTK thread lock */
inline void leave() {  gdk_flush(); gdk_threads_leave(); };

void destroy(GtkWidget *widget, gpointer data)
{
  gtk_main_quit();
}

GtkWidget   *object = NULL;

void OnClicked(GtkWidget *pButton, gpointer data)
{
	GtkWidget * notebook = (GtkWidget*)data;
	addPage((GtkWidget *)notebook, "Other");
}

/*void attente(const char *name)
{
	if(strcmp(name, "Thread") == 0)
	{
		//leave();
		while (gtk_events_pending())
		{
			gtk_main_iteration();
		}
		//enter();
	}
}*/

void *argument_thread(void *args)
{
  WidgetNoteBook *data = (WidgetNoteBook *)args;

  while(1)
    {

		/*while (gtk_events_pending ())
		{
			gtk_main_iteration ();
		}*/

    /* sleep a while */
	#ifndef __linux__
      Sleep(g_random_int_range (1000, 4000));
	#else
	  sleep(g_random_int_range (1, 4));
	#endif

	 enter();
	 //gtk_signal_emit_by_name( (GtkObject*)(object), "clicked", (gpointer)data->noteBook );
	 //addPage((GtkWidget *)data->noteBook, "Thread");
	 //attente("Thread");
	 leave();
    }

  return NULL;
}

void addPage(GtkWidget * notebook, const char *name)
{
	if(notebook)
	{

		GtkWidget *pHBox;
		pHBox = gtk_hbox_new(FALSE, 5);
		gtk_widget_show(pHBox);

		// Textview
		GtkWidget *pScrolled;
		GtkWidget *pTextView;

		pScrolled = gtk_scrolled_window_new(NULL, NULL);
		gtk_widget_show(pScrolled);

		pTextView=gtk_text_view_new();
		gtk_widget_show(pTextView);

		gtk_text_view_set_editable(GTK_TEXT_VIEW(pTextView), FALSE);
		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (pScrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
		gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pScrolled), GTK_SHADOW_IN);
		gtk_container_add(GTK_CONTAINER(pScrolled), pTextView);

		// Liste
		GtkWidget *pListView;
		GtkWidget *pScrollbar;
		GtkListStore *pListStore;
		GtkTreeViewColumn *pColumn;
		GtkCellRenderer *pCellRenderer;

		pListStore = gtk_list_store_new(1, G_TYPE_STRING);
		pListView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(pListStore));
		gtk_widget_show(pListView);
		gtk_widget_set_size_request(pListView, 120, -1);

		pCellRenderer = gtk_cell_renderer_text_new();
		pColumn = gtk_tree_view_column_new_with_attributes("Utilisateurs", pCellRenderer, "text", 0, NULL);
		gtk_tree_view_append_column(GTK_TREE_VIEW(pListView), pColumn);

		pScrollbar = gtk_scrolled_window_new(NULL, NULL);
		gtk_widget_show(pScrollbar);

		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pScrollbar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
		gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pScrollbar), GTK_SHADOW_IN);
		gtk_container_add(GTK_CONTAINER(pScrollbar), pListView);

		// Onglet
		GtkWidget *pHBoxOnglet;
		GtkWidget *pButtonOnglet;
		GtkWidget *pTabLabel;

		pHBoxOnglet = gtk_hbox_new(FALSE, 0);
		gtk_widget_show(pHBoxOnglet);

		char *text=g_convert(name, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
		pTabLabel = gtk_label_new(text);
		gtk_widget_show(pTabLabel);
		g_free(text);

		pButtonOnglet = gtk_button_new_with_label(" x ");
		gtk_widget_show(pButtonOnglet);
		gtk_button_set_relief (GTK_BUTTON (pButtonOnglet), GTK_RELIEF_NONE);

		if(strcmp(name, "Main") == 0)
			object = pButtonOnglet;
		g_signal_connect(G_OBJECT(pButtonOnglet), "clicked", G_CALLBACK(OnClicked), (gpointer*)notebook);

		gtk_box_pack_start(GTK_BOX (pHBoxOnglet), pTabLabel, FALSE, FALSE, 0);
		gtk_box_pack_start(GTK_BOX (pHBoxOnglet), pButtonOnglet, FALSE, FALSE, 0);
		gtk_box_pack_start(GTK_BOX (pHBox), pScrolled, TRUE, TRUE, 0);
		gtk_box_pack_start(GTK_BOX(pHBox), pScrollbar, FALSE, FALSE, 0);

		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pHBox, pHBoxOnglet);
	}
}

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GError *error = NULL;
  WidgetNoteBook yes_args;

  /* init threads */
  g_thread_init(NULL);
  gdk_threads_init();

  /* init gtk */
  gtk_init(&argc, &argv);

  /* create a window */
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW(window), 320, 200);
  g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);
  gtk_container_set_border_width(GTK_CONTAINER (window), 0);

  /* create a label */
  GtkWidget *pNotebook;
  pNotebook = gtk_notebook_new();
  gtk_notebook_set_tab_pos(GTK_NOTEBOOK(pNotebook), GTK_POS_TOP);
  gtk_notebook_set_scrollable(GTK_NOTEBOOK(pNotebook), TRUE);
  gtk_container_add(GTK_CONTAINER(window), pNotebook);

  addPage(pNotebook, "Main");

  /* show everything */
  gtk_widget_show(pNotebook);
  gtk_widget_show(window);

  /* create the threads */
  yes_args.noteBook = pNotebook;
  if (!g_thread_create(argument_thread, &yes_args, FALSE, &error))
    {
      g_printerr ("Failed to create YES thread: %s\n", error->message);
      return 1;
    }

  //gtk_widget_show_all(window);

  /* enter the GTK main loop */
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();

  return 0;
}

Other information:
Comment 1 Tor Lillqvist 2006-12-21 18:51:50 UTC
One can't call GTK+ functions from multiple threads in Windows. Sorry.
Comment 2 Tor Lillqvist 2006-12-21 18:55:47 UTC

*** This bug has been marked as a duplicate of 60620 ***