FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

D_Version2 and gdk.Threads
Goto page 1, 2  Next
 
Post new topic   Reply to topic     Forum Index -> gtkD
View previous topic :: View next topic  
Author Message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Sun Dec 06, 2009 9:50 am    Post subject: D_Version2 and gdk.Threads Reply with quote

Is it true that gdk.Threads is not compatible with D_Version2(I'm using dmd2.036 and GtkD1.3).
Because I try to make test application with a thread that listen a socket client to update a TextView (like chat), but event if I use Main.initMultiThread(args) before gtk.main(), and gdkThreadsEnter and gdkThreadsLeave around textview.insertText("...") in RUN method of the thread, the application crashes with Segmentation fault (core dumped), doesn't it?

Has anybody ever achieved it with Thread application ?

Thanks !
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Sun Dec 06, 2009 10:18 am    Post subject: Reply with quote

Are you using Linux or Windows, since the gdk threads don't work on windows.

The segfault would suggest Linux, where it should work, but i haven't tested with the latest compiler yet.
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Sun Dec 06, 2009 10:30 am    Post subject: Reply with quote

I'm using Linux,

Code source client.d:

module client;

import std.stdio;
import std.socket;
import std.string;
import std.conv;

import gtk.Builder;
import gtk.Main;
import gtk.Window;
import gtk.Widget;
import gtk.TextView;
import gtk.TextBuffer;
import gdk.Keymap;

import std.encoding;
import gdk.Threads;
import core.thread;


class ClassClient
{
private Builder app;
private Window w;
private TextView txtvSend;
private TextBuffer txtBufferSend;
private Socket s_client;
public TextView txtvRcv;

this(Socket s)
{
s_client = s;
app = new Builder();
auto err = app.addFromFile("client.glade");
if(err == 0 ) {
writefln("Error opening glade file.");
}
else
{
auto obj = app.getObject("window1");
obj.setData("GObject", null);
w = new Window(cast(GtkWindow*)obj.getObjectGStruct());
if(w !is null) {
obj = app.getObject("textviewSend");
obj.setData("GObject",null);
txtvSend = new TextView(cast(GtkTextView*)obj.getObjectGStruct());
txtvSend.addOnKeyPress(&onKeyPressSend);
obj = app.getObject("bufferSend");
obj.setData("GObject",null);
txtBufferSend = new TextBuffer(cast(GtkTextBuffer*)obj.getObjectGStruct());
obj = app.getObject("textviewRcv");
obj.setData("GObject",null);
txtvRcv = new TextView(cast(GtkTextView*)obj.getObjectGStruct());

w.show();
w.addOnHide( delegate void(Widget aux){ Main.exit(0); } );

Thread th_client = new Th_client();
th_client.start();

}
else { writefln("Error launching application."); }
}
}
bool onKeyPressSend( GdkEventKey* event, Widget widget )
{
if(event.state & GdkModifierType.SHIFT_MASK)
{
if(Keymap.gdkKeyvalName(event.keyval) == "Return")
return false;
}
if(Keymap.gdkKeyvalName(event.keyval) == "Return")
{
sendToAll();
return true;
}

return false;
}

void sendToAll()
{
char[1024] buf = void;
int read = s_client.send(cast(const char[])txtBufferSend.getText());
txtBufferSend.setText("");
writefln("%d",read);
s_client.receive(buf);
writefln("%s",buf[0..read]);
/*string temp = "";
transcode(cast(Latin1String)to!string(buf[0..read]),temp);
txtvRcv.insertText(temp~"\r");*/
}

class Th_client : Thread
{
this()
{
super( &run );
}

~this()
{
//writefln("killed id = %d",id);
}

private void run()
{
char[1024] buf = void;
while(true)
{

int read = s_client.receive(buf);

if(Socket.ERROR == read)
{
writefln("connection error");
break;
}
else if (read==0)
{
try

{

//if the connection closed due to an error, remoteAddress() could fail

writefln("Connection from %s closed.\n", s_client.remoteAddress().toString());

}

catch

{

}
break;
}
else

{

writefln("Received %d bytes from %s: %s", read, s_client.remoteAddress().toString(), buf[0 .. read]);
string temp = "";
transcode(cast(Latin1String)to!string(buf[0..read]),temp);
gdkThreadsEnter();
txtvRcv.insertText("Hello"~"\r");
gdkThreadsLeave();

}
}
}
}
}



class MyInternetAddress: InternetAddress
{
this(string addr, ushort port)
{
sin.sin_family = AddressFamily.INET;
super(addr, port);
}

this(uint addr, ushort port)
{
sin.sin_family = AddressFamily.INET;
super(addr, port);
}

this(ushort port)
{
sin.sin_family = AddressFamily.INET;
super(port);
}
}


int main (string[] args)

{
Main.initMultiThread(args);
string domain;
ushort port;
if(args.length >= 3)

{
domain = to!string(args[1]);

port = to!ushort(args[2]);

}

else

{
domain = "127.0.0.1";

port = 4444;

}

Socket s_client = new TcpSocket(new MyInternetAddress(domain, port));
assert(s_client.isAlive);
new ClassClient(s_client);

Main.run();
return 0;
}


If we can't create thread application with gtk.Threads, there is another solution ? I think about ProgressBar also.

Thanks !
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Sun Dec 06, 2009 9:47 pm    Post subject: Reply with quote

Using GTK+2.18.3, DMD2.37, GtkD1.3, compile and get same problem.
Is there a problem of compatibility between them?

After long investigation, I discovered this when my application loads library:
Loaded lib = libatk-1.0.so
Loaded lib = libgtk-x11-2.0.so
Loaded lib = libgmodule-2.0.so
Loaded lib = libgdk-x11-2.0.so
Loaded lib = libgio-2.0.so
Loaded lib = libgobject-2.0.so
Loaded lib = libglib-2.0.so
Loaded lib = libgdk_pixbuf-2.0.so
Loaded lib = libcairo.so
Loaded lib = libgthread-2.0.so
Loaded lib = libpango-1.0.so
Loaded lib = libpangocairo-1.0.so
failed (libgio-2.0.so) g_io_module_load
failed (libgio-2.0.so) g_io_module_unload
failed (libglib-2.0.so) g_atomic_int_inc
failed (libglib-2.0.so) g_atomic_int_dec_and_test
failed (libglib-2.0.so) g_io_channel_win32_new_fd
failed (libglib-2.0.so) g_io_channel_win32_new_socket
failed (libglib-2.0.so) g_io_channel_win32_new_messages
failed (libglib-2.0.so) g_ascii_isalnum
failed (libglib-2.0.so) g_ascii_isalpha
failed (libglib-2.0.so) g_ascii_iscntrl
failed (libglib-2.0.so) g_ascii_isdigit
failed (libglib-2.0.so) g_ascii_isgraph
failed (libglib-2.0.so) g_ascii_islower
failed (libglib-2.0.so) g_ascii_isprint
failed (libglib-2.0.so) g_ascii_ispunct
failed (libglib-2.0.so) g_ascii_isspace
failed (libglib-2.0.so) g_ascii_isupper
failed (libglib-2.0.so) g_ascii_isxdigit
failed (libglib-2.0.so) g_win32_error_message
failed (libglib-2.0.so) g_win32_getlocale
failed (libglib-2.0.so) g_win32_get_package_installation_directory
failed (libglib-2.0.so) g_win32_get_package_installation_directory_of_module
failed (libglib-2.0.so) g_win32_get_package_installation_subdirectory
failed (libglib-2.0.so) g_win32_get_windows_version
failed (libglib-2.0.so) g_win32_locale_filename_from_utf8
failed (libgthread-2.0.so) g_mutex_new
failed (libgthread-2.0.so) g_mutex_lock
failed (libgthread-2.0.so) g_mutex_trylock
failed (libgthread-2.0.so) g_mutex_unlock
failed (libgthread-2.0.so) g_mutex_free
failed (libgthread-2.0.so) g_static_mutex_lock
failed (libgthread-2.0.so) g_static_mutex_trylock
failed (libgthread-2.0.so) g_static_mutex_unlock
failed (libgthread-2.0.so) g_static_mutex_get_mutex
failed (libgthread-2.0.so) g_cond_new
failed (libgthread-2.0.so) g_cond_signal
failed (libgthread-2.0.so) g_cond_broadcast
failed (libgthread-2.0.so) g_cond_wait
failed (libgthread-2.0.so) g_cond_timed_wait
failed (libgthread-2.0.so) g_cond_free
failed (libgthread-2.0.so) g_private_new
failed (libgthread-2.0.so) g_private_get
failed (libgthread-2.0.so) g_private_set
failed (libgthread-2.0.so) g_thread_supported
failed (libgthread-2.0.so) g_thread_create
failed (libgthread-2.0.so) g_thread_yield
failed (libpango-1.0.so) script_engine_list
failed (libpango-1.0.so) script_engine_init
failed (libpango-1.0.so) script_engine_exit
failed (libpango-1.0.so) script_engine_create

Same problem with demo "TestWindow" of GtkD, application got segmentation fault when it arrives on "gdkThreadsEnter()".
Is there a solution ?
I can't imagine me work with application without threading ! Crying or Very sad

Thanks !
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Mon Dec 07, 2009 12:46 pm    Post subject: Reply with quote

Could you post a backtrace i seen to have problems with my debugger
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Mon Dec 07, 2009 2:47 pm    Post subject: Reply with quote

hum, I'm using DMD2 as compiler, and I think there is no backtrace within. Can I do something as : debug scope( failure ) writef("Backtrace xx "__FILE__"(",__LINE__,")\n");

Is it enought?
I've never used a debugger with D, what debugger can I use ?

Another point attracted me, when I compile:
dmd -v client.o -ofClient -L-ldl -L-lgtkd
GIVE:
gcc client.o -o Client -m32 -ldl -lgtkd -Xlinker -L/etc/../lib -Xlinker -L/etc/../usr/local/lib -lphobos2 -lpthread -lm

Default library used here is -lpthread, what about -lgthread-2.0 ?
If I want remove -lpthread by -lgthread, it is possible ?

Thanks !
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Mon Dec 07, 2009 4:01 pm    Post subject: Reply with quote

Okey ! I decided to use gdb as debugger and it gives me:

[Thread debugging using libthread_db enabled]
warning: .dynamic section for "/usr/lib/libcairo.so.2" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libpixman-1.so.0" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libatk-1.0.so.0" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libgthread-2.0.so" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
Loaded lib = libatk-1.0.so
Loaded lib = libgtk-x11-2.0.so
Loaded lib = libgmodule-2.0.so
Loaded lib = libgdk-x11-2.0.so
Loaded lib = libgio-2.0.so
Loaded lib = libgobject-2.0.so
Loaded lib = libglib-2.0.so
Loaded lib = libgdk_pixbuf-2.0.so
Loaded lib = libcairo.so
Loaded lib = libgthread-2.0.so
Loaded lib = libpango-1.0.so
Loaded lib = libpangocairo-1.0.so
failed (libgio-2.0.so) g_io_module_load
failed (libgio-2.0.so) g_io_module_unload
failed (libglib-2.0.so) g_atomic_int_inc
failed (libglib-2.0.so) g_atomic_int_dec_and_test
failed (libglib-2.0.so) g_io_channel_win32_new_fd
failed (libglib-2.0.so) g_io_channel_win32_new_socket
failed (libglib-2.0.so) g_io_channel_win32_new_messages
failed (libglib-2.0.so) g_ascii_isalnum
failed (libglib-2.0.so) g_ascii_isalpha
failed (libglib-2.0.so) g_ascii_iscntrl
failed (libglib-2.0.so) g_ascii_isdigit
failed (libglib-2.0.so) g_ascii_isgraph
failed (libglib-2.0.so) g_ascii_islower
failed (libglib-2.0.so) g_ascii_isprint
failed (libglib-2.0.so) g_ascii_ispunct
failed (libglib-2.0.so) g_ascii_isspace
failed (libglib-2.0.so) g_ascii_isupper
failed (libglib-2.0.so) g_ascii_isxdigit
failed (libglib-2.0.so) g_win32_error_message
failed (libglib-2.0.so) g_win32_getlocale
failed (libglib-2.0.so) g_win32_get_package_installation_directory
failed (libglib-2.0.so) g_win32_get_package_installation_directory_of_module
failed (libglib-2.0.so) g_win32_get_package_installation_subdirectory
failed (libglib-2.0.so) g_win32_get_windows_version
failed (libglib-2.0.so) g_win32_locale_filename_from_utf8
failed (libgthread-2.0.so) g_mutex_new
failed (libgthread-2.0.so) g_mutex_lock
failed (libgthread-2.0.so) g_mutex_trylock
failed (libgthread-2.0.so) g_mutex_unlock
failed (libgthread-2.0.so) g_mutex_free
failed (libgthread-2.0.so) g_static_mutex_lock
failed (libgthread-2.0.so) g_static_mutex_trylock
failed (libgthread-2.0.so) g_static_mutex_unlock
failed (libgthread-2.0.so) g_static_mutex_get_mutex
failed (libgthread-2.0.so) g_cond_new
failed (libgthread-2.0.so) g_cond_signal
failed (libgthread-2.0.so) g_cond_broadcast
failed (libgthread-2.0.so) g_cond_wait
failed (libgthread-2.0.so) g_cond_timed_wait
failed (libgthread-2.0.so) g_cond_free
failed (libgthread-2.0.so) g_private_new
failed (libgthread-2.0.so) g_private_get
failed (libgthread-2.0.so) g_private_set
failed (libgthread-2.0.so) g_thread_supported
failed (libgthread-2.0.so) g_thread_create
failed (libgthread-2.0.so) g_thread_yield
failed (libpango-1.0.so) script_engine_list
failed (libpango-1.0.so) script_engine_init
failed (libpango-1.0.so) script_engine_exit
failed (libpango-1.0.so) script_engine_create
[New Thread 0x19fbb70 (LWP 2357)]
1 <= (length data received)
Received 1 bytes from 127.0.0.1:4444: d

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x19fbb70 (LWP 2357)]
0x00000000 in ?? ()
---------------------------------------------------------------------------
And info threads:
(gdb) info threads
* 2 Thread 0x19fbb70 (LWP 2357) 0x00000000 in ?? ()
1 Thread 0x116f90 (LWP 2353) 0x006e7416 in __kernel_vsyscall ()
---------------------------------------------------------------------------

I don't understand this, I hope it tells you something !

Thanks !
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Tue Dec 08, 2009 3:13 pm    Post subject: Reply with quote

Thats the same output i get, i first thought it wan't correct.
But i found that the function pointers aren't set correctly by the loader.
This obviously resuts in a segfault when calling the function while is still null.

No clue as to why though.
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Tue Dec 08, 2009 3:37 pm    Post subject: Reply with quote

Mike Wey wrote:
No clue as to why though.


TLS, the functions are only linked for one thread, the declerations for the fonction pointer probably need to be marked __gshared.

I've got threading working with this patch:
http://gtkd.mikewey.eu/shared.diff
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Tue Dec 08, 2009 7:44 pm    Post subject: Reply with quote

You got it Mike Wey !!!!!!!!!!!!!!!!!!!!!!!!!!!! It wasn't easy !!!

Thanks to confirm me that we can create threading application with D and GtkD. It's a real pleasure to work with.

Many thanks for this patch !

Only thing I have to do to make it work:
- after modifying files in gtkc/, don't forget to 'make clean' and 'make', at first time I forgot to clean and get :
-----------------------------------------
/usr/bin/ld: c_g_type_from_name: TLS reference in /usr/lib/gcc/i686-redhat-linux/4.4.2/../../../libgtkd.a(Builder.o) mismatches non-TLS definition in /usr/lib/gcc/i686-redhat-linux/4.4.2/../../../libgtkd.a(gobject.o) section .bss
/usr/lib/gcc/i686-redhat-linux/4.4.2/../../../libgtkd.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
-----------------------------------------

I know this code is not supposed to work under Windows but I'll try it just for fun.

Thanks Mike for your help.
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Wed Dec 09, 2009 4:04 pm    Post subject: Reply with quote

Now if only dmd1 also defined __gshared, than we could put it in svn as is.
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Wed Dec 09, 2009 6:06 pm    Post subject: Reply with quote

OK, good !

I compiled this code under Windows and ... it works !!!!! I'm surprised because it was not supposed...
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Thu Dec 10, 2009 12:52 pm    Post subject: Reply with quote

You can find the following in the gtk documentation:

Quote:
GLib is completely thread safe (all global data is automatically locked), but individual data structure instances are not automatically locked for performance reasons. So e.g. you must coordinate accesses to the same GHashTable from multiple threads.

GTK+ is thread aware but not thread safe it provides a global lock controlled by gdk_threads_enter()/gdk_threads_leave() which protects all use of GTK+. That is, only one thread can use GTK+ at any given time.

Unfortunately the above holds with the X11 backend only. With the Win32 backend, GDK calls should not be attempted from multiple threads at all.

You must call g_thread_init() and gdk_threads_init() before executing any other GTK+ or GDK functions in a threaded GTK+ program.

http://library.gnome.org/devel/gdk/stable/gdk-Threads.html
Back to top
View user's profile Send private message
GG



Joined: 05 Nov 2009
Posts: 18

PostPosted: Thu Dec 10, 2009 1:47 pm    Post subject: Reply with quote

So, to create GUI application threading and work with progressbar for example, we can use :
- gdkThreadsEnter() with main gtk+ lock
- g_idle_add_full() in /Glib/Idle.d,
- or timeout in gtk/timeout.d

Right ? Is there a best choice ?
If the answer is YES, then I will try the idles and timeout.

Thanks !
Back to top
View user's profile Send private message
Mike Wey



Joined: 07 May 2007
Posts: 428

PostPosted: Thu Dec 10, 2009 4:34 pm    Post subject: Reply with quote

I think glib.Idle would be a good choice.

If the function you're adding returns false, you could add the idle function every time you need to modify the progressbar.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> gtkD All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group