I tried to c开发者_开发百科all,
g_io_scheduler_push_job(job_func, ¶m, NULL, G_PRIORITY_HIGH, generator_cancellable);
In my C/gtk+
application for running job_func()
in another thread then main program. But have segfault when I call this function, and debugger said that: ** userdata attempt to difference a generic pointer**
The job_func()
code is,
gboolean job_func(GIOSchedulerJob *job, GCancellable *cancellable, gpointer user_data)
{
JobParam* job_param = (JobParam*)user_data;
build(NULL, job_param->mw);
return TRUE;
}
Where JobParam
,
typedef struct _JobParam
{
GtkWidget* widget;
MainWin* mw;
}JobParam;
Where MainWin
,
typedef struct _MainWin
{
GtkWindow parent;
GtkWidget* scroll;
GtkWidget* box;
GtkUIManager *uimanager;
} MainWin;
And build
,
void build(GtkWidget* widget, MainWin* mw)
{
gtk_list_store_clear(mw->model);
}
How can I fix it?
Thank you.
You're messing with widgets (and related stuff) off the main thread, DON'T DO THAT.
GTK functions are not thread safe unless noted otherwise in the documentation, you cannot manipulate widgets (and I'm fairly certain the GtkTreeModel implementations) in any thread except the one running the main loop. Basically just don't. I think you might be able to do this if AND ONLY IF the GtkListStore is doesn't have any GtkTreeView attached to it. (and if you're doing lots of changes it's a good idea to disconnect it first anyway, saves redraws and lots of useless events)
EDIT: the reason I mention disconnecting the TreeView from the ListStore is because I expect that you're trying to do gtk_list_store_clear()
in a separate thread because it's taking too long, it's a common problem, any time you're going to add/remove a large number of rows to/from a TreeModel you should first do gtk_tree_view_set_model(treeview, NULL);
Without seeing the full code, it's hard to determine what is going on. My guess is that param is allocated on the stack based on the way you're passing it in, so the address is invalid when your job_func is actually called is invalid and dereferences garbage.
Try allocating your param using malloc and then freeing it. You can pass in a GDestroyNotify which you can call free within.
精彩评论