GTK No Refresh after long time activity.

Windows specific questions.
Post Reply
exagonx
Posts: 314
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

GTK No Refresh after long time activity.

Post by exagonx »

Hello.
I have done a little software Server Side for run some program or restart the pc but I have a little problem:

I make a litthe thred where each seconds write the text on label in GLADE Interface,
but after some minutes the interface stop the refreshing, the software is like freezed but its work if I click on close button the program end like normal work , work all but without show the animation like the Menus, the animation button (press and release)
and the label text and the entry is like freezed because if I put text inside the entry is appen nothing but the text is in memory and if I click in the save button the text will be saved .
That is differend from PC and PC that depend how memory have , biggher is the memory longer time work without problem.

I try this script with a simple glade ui

1) close button
2) label text

and that appen too then I dont understand how I can solve this problem because the program have to work for one week , the text mode work but the problem is the GTK where I show the status and the time .
I working on GTK 3 with TOBAC

Code: Select all

Dim Shared ControlTime as Integer
ControlTime = 1
Sub TimeControl(Funzione As Any Ptr)
    Dim TmStart as Integer
    Dim TmStop as Integer  
    
    Dim as zstring ptr ZTesto
	Dim as String STesto
	Dim as Integer SNumero
    
    Dim As Double t = Timer
    
    While( 1 )
		
		
		If not ControlTime = 3 Then TmStart = TmStart - 1
		If CTReset = 1 then
			CTReset = 0
			TmStart = TempoCic
		End If
		
		If TmStart < 0 Then
			TmStart = TempoCic
			 
		End If
		
		If ControlTime = 3 Then
		TmStop = TmStart
		TmStart = TempoCic
        STesto = Str(TmStop)
		ZTesto = StrPtr(STesto)
		
		gtk_label_set_label (GTK_LABEL (STimer), *ZTesto)
        End If 
        
        If ControlTime = 2 Then
        STesto = Str(TmStart)
		ZTesto = StrPtr(STesto)
		
		gtk_label_set_label (GTK_LABEL (STimer), *ZTesto)
        End If 
              
        Sleep 1000
        
        
        If ControlTime = 1 Then Exit Sub
    Wend
    
End Sub



SetCommand()
ConfigFile(0)

WriteLog(0)
Dim shared thread As Any Ptr

thread = ThreadCreate( @TimeControl, 0 )

Thank you
I hope someone ca help me with a solution.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: GTK No Refresh after long time activity.

Post by TJF »

Setting a new label text by a thread is critical, since the thread may interrupt a GUI refresh (causing race conditions). In a thread you've to enclose the GUI functions by gdk_threads_enter() ... gdk_threads_leave(), which doesn't work with FB threads. Instead, use a GLib thread. Find an example at
Note: this example is old and uses a deprecated GLib function. Replace g_thread_create() by new function g_thread_new() (or the *_try* version).

I just noticed, also this is out-dated. The new policy is
https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk-threads-enter wrote:gdk_threads_enter has been deprecated since version 3.6 and should not be used in newly-written code.

All GDK and GTK+ calls should be made from the main thread
BR
exagonx
Posts: 314
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: GTK No Refresh after long time activity.

Post by exagonx »

Hi TJF
Thank you for the answer, but I have to ask something
The FB Thread if work in background without send any to the GTK GUI make some problem too ? or I can use without problem ?
because in another project I want put the "Refresh" button for check the status.
You think its work ?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: GTK No Refresh after long time activity.

Post by caseih »

The recommended thing to do is the same regardless of programming language, and really regardless of GUI toolkit. You've got two options for GTK:

1. Anytime your thread needs to update something in the GUI, post a message to an async message queue you've set up that a timer event callback in the main thread can poll. GTK (well GLIB) has message queue data structures you can use. But as far as I can tell it does not generate events, so you have to poll for messages periodically in the main thread.

2. Call g_idle_add from the thread to schedule a callback to run at the next opportunity in the main thread which can do the update for you. g_idle_add can be called from the thread, but the callback will run in the main thread. I'm typing this from memory, GTK2. I believe the call is similarly named in GTK3. This is probably your easiest solution.

Another option is to eliminate threads altogether and go for asynchronous I/O calls.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: GTK No Refresh after long time activity.

Post by TJF »

@caseih

1. You need not poll anything. Events are handled in GLib, see https://developer.gnome.org/glib/stable ... -Loop.html for details.

2. g_idle_add() adds a callback to be called when the app is in idle state (no user action). As far as I understand, exagonx wants to perform a callback function on a regular basis, so g_timeout_add() or g_timeout_add_seconds() may be a better choice (which should be called once in the main code, as in the example above).


@exagonx

Nobody can estimate if a thread will cause problems unless the code is known.

And even then I couldn't tell, since I don't test such constellations. I try to avoid mixing critical features of different systems: when using GTK+, then using GLib threads.
exagonx
Posts: 314
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: GTK No Refresh after long time activity.

Post by exagonx »

Thank you TJF

At moment I put the thread alone all message log are in shared var where I can whatch if work correctly.
Ill start to work for make like you sayd a gui with glib but Im beginner and I need more time than a normal professionale developer to understand how work .
exagonx
Posts: 314
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: GTK No Refresh after long time activity.

Post by exagonx »

TJF wrote:Setting a new label text by a thread is critical, since the thread may interrupt a GUI refresh (causing race conditions). In a thread you've to enclose the GUI functions by gdk_threads_enter() ... gdk_threads_leave(), which doesn't work with FB threads. Instead, use a GLib thread. Find an example at
Note: this example is old and uses a deprecated GLib function. Replace g_thread_create() by new function g_thread_new() (or the *_try* version).

I just noticed, also this is out-dated. The new policy is
https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk-threads-enter wrote:gdk_threads_enter has been deprecated since version 3.6 and should not be used in newly-written code.

All GDK and GTK+ calls should be made from the main thread
BR
Hi again TJF I have used the example of your program but I have got a little problem if I move the window on the desktop the software freeze and I have to terminate , its my problem or you allready know this ?
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: GTK No Refresh after long time activity.

Post by TJF »

I just tested the code again. Minor adaptions are necessary to compile with fbc-1.01 64bit under Xubuntu14.04. The code compiles against GTK+-2.24 or GTK+-3.8 and runs fine here, even when I move the window on the desktop.
exagonx
Posts: 314
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: GTK No Refresh after long time activity.

Post by exagonx »

meybe i have thi problem because im working on windows I move all under Linux and Ill try again , but its fine if I found a solution where work correctly in windows too
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: GTK No Refresh after long time activity.

Post by TJF »

I've only LINUX on my boxes and therefor cannot test under non-LINIX systems any more. Usualy the code should run without changes.

Which installer did you use? Where did you get it from?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: GTK No Refresh after long time activity.

Post by caseih »

TJF wrote:@caseih

1. You need not poll anything. Events are handled in GLib, see https://developer.gnome.org/glib/stable ... -Loop.html for details.
No this is not what I'm talking about. I'm talking about g_async_queue. When things are pushed on the queue it does not trigger an event for the other end which would want to pop, mainly because they could be used in either direction, and without the main loop running. Queues are very useful for communicating between threads, but you do have to poll for messages with something like g_async_queue_pop_try. Thus they could be useful in a situation like this, but g_idle_add is better.
2. g_idle_add() adds a callback to be called when the app is in idle state (no user action). As far as I understand, exagonx wants to perform a callback function on a regular basis, so g_timeout_add() or g_timeout_add_seconds() may be a better choice (which should be called once in the main code, as in the example above).
This is not quite correct. I think you're misunderstanding what the idle state is in GTK. The g_idle_add docs say: "Adds a function to be called whenever there are no higher priority events pending to the default main loop." So this says nothing about user action. It will run regardless of user activity, but after high-priority events like timers. In any event g_idle_add and g_idle_add_full *are* the recommended mechanisms for doing updates from threads. All the GTK docs I've read have stated this. g_timeout_add is another good option for many kinds of thread updates but not all (especially infrequent ones such as reporting on the progress of a download). GTK3 now includes g_main_context_invoke which enters into this somehow, but I'm not sure since I've not done any GTK3 programming.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: GTK No Refresh after long time activity.

Post by TJF »

caseih wrote:No this is not what I'm talking about. I'm talking about g_async_queue. When things are pushed on the queue it does not trigger an event for the other end which would want to pop, mainly because they could be used in either direction, and without the main loop running. Queues are very useful for communicating between threads, but you do have to poll for messages with something like g_async_queue_pop_try. Thus they could be useful in a situation like this, but g_idle_add is better.
Yes, we're talking about different methods.

The g_async_queue is made for inter-thread communications, but not for communications between a thread and the main loop. Polling anything by a g_idle_add callback isn't 'better', since it generates a lot of CPU load and therefor slows down other apps, running in parallel.

From my point of view it's better to use the event system. Either by hooking up to an existing signal or by creating a new one. The g_timeout_add thread sends the signal, and it gets catched in the main loop to update the label context.
Post Reply